1 From 611406e29293c37b4a8771073030ccdaf0bd4fa5 Mon Sep 17 00:00:00 2001
2 From: Li Xi <pkuelelixi@gmail.com>
3 Subject: [PATCH] vfs: Add general support to enforce project quota limits
5 This patch adds support for a new quota type PRJQUOTA for project quota
6 enforcement. Also a new method get_projid() is added into dquot_operations
9 Signed-off-by: Li Xi <lixi@ddn.com>
10 Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
11 Reviewed-by: Jan Kara <jack@suse.cz>
12 Signed-off-by: Jan Kara <jack@suse.cz>
15 diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
16 index d7d5a0a..6b80f11 100644
17 --- a/fs/quota/dquot.c
18 +++ b/fs/quota/dquot.c
19 @@ -1152,8 +1152,8 @@ static int need_print_warning(struct dquot_warn *warn)
20 return uid_eq(current_fsuid(), warn->w_dq_id.uid);
22 return in_group_p(warn->w_dq_id.gid);
23 - case PRJQUOTA: /* Never taken... Just make gcc happy */
30 @@ -1392,6 +1392,9 @@ static void __dquot_initialize(struct inode *inode, int type)
31 /* First get references to structures we might need. */
32 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
38 if (type != -1 && cnt != type)
40 @@ -1402,6 +1405,10 @@ static void __dquot_initialize(struct inode *inode, int type)
42 if (inode->i_dquot[cnt])
45 + if (!sb_has_quota_active(sb, cnt))
51 @@ -1411,6 +1418,12 @@ static void __dquot_initialize(struct inode *inode, int type)
53 qid = make_kqid_gid(inode->i_gid);
56 + rc = inode->i_sb->dq_op->get_projid(inode, &projid);
59 + qid = make_kqid_projid(projid);
62 got[cnt] = dqget(sb, qid);
64 @@ -2154,7 +2167,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
68 - if (!sb->s_op->quota_write || !sb->s_op->quota_read) {
69 + if (!sb->s_op->quota_write || !sb->s_op->quota_read ||
70 + (type == PRJQUOTA && sb->dq_op->get_projid == NULL)) {
74 diff --git a/fs/quota/quotaio_v2.h b/fs/quota/quotaio_v2.h
75 index f1966b4..4e95430 100644
76 --- a/fs/quota/quotaio_v2.h
77 +++ b/fs/quota/quotaio_v2.h
80 #define V2_INITQMAGICS {\
81 0xd9c01f11, /* USRQUOTA */\
82 - 0xd9c01927 /* GRPQUOTA */\
83 + 0xd9c01927, /* GRPQUOTA */\
84 + 0xd9c03f14, /* PRJQUOTA */\
87 #define V2_INITQVERSIONS {\
94 /* First generic header */
95 diff --git a/include/linux/quota.h b/include/linux/quota.h
96 index 99932a5..0d20c39 100644
97 --- a/include/linux/quota.h
98 +++ b/include/linux/quota.h
105 USRQUOTA = 0, /* element used for user quotas */
106 GRPQUOTA = 1, /* element used for group quotas */
107 @@ -314,6 +315,7 @@ struct dquot_operations {
108 /* get reserved quota for delayed alloc, value returned is managed by
110 qsize_t *(*get_reserved_space) (struct inode *);
111 + int (*get_projid) (struct inode *, kprojid_t *);/* Get project ID */
115 diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
116 index 83d19df..418e9dd 100644
117 --- a/include/uapi/linux/fs.h
118 +++ b/include/uapi/linux/fs.h
119 @@ -58,6 +58,36 @@ struct inodes_stat_t {
120 int dummy[5]; /* padding for sysctl ABI compatibility */
124 + * Structure for FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR.
127 + __u32 fsx_xflags; /* xflags field value (get/set) */
128 + __u32 fsx_extsize; /* extsize field value (get/set)*/
129 + __u32 fsx_nextents; /* nextents field value (get) */
130 + __u32 fsx_projid; /* project identifier (get/set) */
131 + unsigned char fsx_pad[12];
133 +#define HAVE_FSXATTR 1
136 + * Flags for the fsx_xflags field
138 +#define FS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */
139 +#define FS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */
140 +#define FS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */
141 +#define FS_XFLAG_APPEND 0x00000010 /* all writes append */
142 +#define FS_XFLAG_SYNC 0x00000020 /* all writes synchronous */
143 +#define FS_XFLAG_NOATIME 0x00000040 /* do not update access time */
144 +#define FS_XFLAG_NODUMP 0x00000080 /* do not include in backups */
145 +#define FS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */
146 +#define FS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */
147 +#define FS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
148 +#define FS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
149 +#define FS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
150 +#define FS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
151 +#define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */
152 +#define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
154 #define NR_FILE 8192 /* this can well be larger on a larger system */
156 @@ -163,6 +193,8 @@ struct inodes_stat_t {
157 #define FS_IOC_GETVERSION _IOR('v', 1, long)
158 #define FS_IOC_SETVERSION _IOW('v', 2, long)
159 #define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
160 +#define FS_IOC_FSGETXATTR _IOR('X', 31, struct fsxattr)
161 +#define FS_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr)
162 #define FS_IOC32_GETFLAGS _IOR('f', 1, int)
163 #define FS_IOC32_SETFLAGS _IOW('f', 2, int)
164 #define FS_IOC32_GETVERSION _IOR('v', 1, int)
165 @@ -195,6 +227,7 @@ struct inodes_stat_t {
166 #define FS_EXTENT_FL 0x00080000 /* Extents */
167 #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
168 #define FS_NOCOW_FL 0x00800000 /* Do not cow file */
169 +#define FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
170 #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
172 #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
173 diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h
174 index 3b6cfbe..b2d9486 100644
175 --- a/include/uapi/linux/quota.h
176 +++ b/include/uapi/linux/quota.h
178 #include <linux/errno.h>
179 #include <linux/types.h>
181 -#define __DQUOT_VERSION__ "dquot_6.5.2"
182 +#define __DQUOT_VERSION__ "dquot_6.6.0"
186 #define USRQUOTA 0 /* element used for user quotas */
187 #define GRPQUOTA 1 /* element used for group quotas */
188 +#define PRJQUOTA 2 /* element used for project quotas */
191 * Definitions for the default names of the quotas files.
193 #define INITQFNAMES { \
194 "user", /* USRQUOTA */ \
195 "group", /* GRPQUOTA */ \
196 + "project", /* PRJQUOTA */ \