diff options
Diffstat (limited to 'include/linux/quota.h')
| -rw-r--r-- | include/linux/quota.h | 136 | 
1 files changed, 130 insertions, 6 deletions
diff --git a/include/linux/quota.h b/include/linux/quota.h index 524ede8a160..dcd5721e626 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -181,10 +181,135 @@ enum {  #include <linux/dqblk_v2.h>  #include <linux/atomic.h> +#include <linux/uidgid.h> +#include <linux/projid.h> + +#undef USRQUOTA +#undef GRPQUOTA +enum quota_type { +	USRQUOTA = 0,		/* element used for user quotas */ +	GRPQUOTA = 1,		/* element used for group quotas */ +	PRJQUOTA = 2,		/* element used for project quotas */ +};  typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */  typedef long long qsize_t;	/* Type in which we store sizes */ +struct kqid {			/* Type in which we store the quota identifier */ +	union { +		kuid_t uid; +		kgid_t gid; +		kprojid_t projid; +	}; +	enum quota_type type;  /* USRQUOTA (uid) or GRPQUOTA (gid) or PRJQUOTA (projid) */ +}; + +extern bool qid_eq(struct kqid left, struct kqid right); +extern bool qid_lt(struct kqid left, struct kqid right); +extern qid_t from_kqid(struct user_namespace *to, struct kqid qid); +extern qid_t from_kqid_munged(struct user_namespace *to, struct kqid qid); +extern bool qid_valid(struct kqid qid); + +/** + *	make_kqid - Map a user-namespace, type, qid tuple into a kqid. + *	@from: User namespace that the qid is in + *	@type: The type of quota + *	@qid: Quota identifier + * + *	Maps a user-namespace, type qid tuple into a kernel internal + *	kqid, and returns that kqid. + * + *	When there is no mapping defined for the user-namespace, type, + *	qid tuple an invalid kqid is returned.  Callers are expected to + *	test for and handle handle invalid kqids being returned. + *	Invalid kqids may be tested for using qid_valid(). + */ +static inline struct kqid make_kqid(struct user_namespace *from, +				    enum quota_type type, qid_t qid) +{ +	struct kqid kqid; + +	kqid.type = type; +	switch (type) { +	case USRQUOTA: +		kqid.uid = make_kuid(from, qid); +		break; +	case GRPQUOTA: +		kqid.gid = make_kgid(from, qid); +		break; +	case PRJQUOTA: +		kqid.projid = make_kprojid(from, qid); +		break; +	default: +		BUG(); +	} +	return kqid; +} + +/** + *	make_kqid_invalid - Explicitly make an invalid kqid + *	@type: The type of quota identifier + * + *	Returns an invalid kqid with the specified type. + */ +static inline struct kqid make_kqid_invalid(enum quota_type type) +{ +	struct kqid kqid; + +	kqid.type = type; +	switch (type) { +	case USRQUOTA: +		kqid.uid = INVALID_UID; +		break; +	case GRPQUOTA: +		kqid.gid = INVALID_GID; +		break; +	case PRJQUOTA: +		kqid.projid = INVALID_PROJID; +		break; +	default: +		BUG(); +	} +	return kqid; +} + +/** + *	make_kqid_uid - Make a kqid from a kuid + *	@uid: The kuid to make the quota identifier from + */ +static inline struct kqid make_kqid_uid(kuid_t uid) +{ +	struct kqid kqid; +	kqid.type = USRQUOTA; +	kqid.uid = uid; +	return kqid; +} + +/** + *	make_kqid_gid - Make a kqid from a kgid + *	@gid: The kgid to make the quota identifier from + */ +static inline struct kqid make_kqid_gid(kgid_t gid) +{ +	struct kqid kqid; +	kqid.type = GRPQUOTA; +	kqid.gid = gid; +	return kqid; +} + +/** + *	make_kqid_projid - Make a kqid from a projid + *	@projid: The kprojid to make the quota identifier from + */ +static inline struct kqid make_kqid_projid(kprojid_t projid) +{ +	struct kqid kqid; +	kqid.type = PRJQUOTA; +	kqid.projid = projid; +	return kqid; +} + +  extern spinlock_t dq_data_lock;  /* Maximal numbers of writes for quota operation (insert/delete/update) @@ -294,10 +419,9 @@ struct dquot {  	atomic_t dq_count;		/* Use count */  	wait_queue_head_t dq_wait_unused;	/* Wait queue for dquot to become unused */  	struct super_block *dq_sb;	/* superblock this applies to */ -	unsigned int dq_id;		/* ID this applies to (uid, gid) */ +	struct kqid dq_id;		/* ID this applies to (uid, gid, projid) */  	loff_t dq_off;			/* Offset of dquot on disk */  	unsigned long dq_flags;		/* See DQ_* */ -	short dq_type;			/* Type of quota */  	struct mem_dqblk dq_dqb;	/* Diskquota usage */  }; @@ -336,8 +460,8 @@ struct quotactl_ops {  	int (*quota_sync)(struct super_block *, int);  	int (*get_info)(struct super_block *, int, struct if_dqinfo *);  	int (*set_info)(struct super_block *, int, struct if_dqinfo *); -	int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *); -	int (*set_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *); +	int (*get_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *); +	int (*set_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *);  	int (*get_xstate)(struct super_block *, struct fs_quota_stat *);  	int (*set_xstate)(struct super_block *, unsigned int, int);  }; @@ -386,10 +510,10 @@ static inline unsigned int dquot_generic_flag(unsigned int flags, int type)  }  #ifdef CONFIG_QUOTA_NETLINK_INTERFACE -extern void quota_send_warning(short type, unsigned int id, dev_t dev, +extern void quota_send_warning(struct kqid qid, dev_t dev,  			       const char warntype);  #else -static inline void quota_send_warning(short type, unsigned int id, dev_t dev, +static inline void quota_send_warning(struct kqid qid, dev_t dev,  				      const char warntype)  {  	return;  |