aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/quota/quota.c29
-rw-r--r--include/linux/quota.h1
-rw-r--r--include/uapi/linux/dqblk_xfs.h47
3 files changed, 77 insertions, 0 deletions
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index c7314f1771f5..dea86e8967ee 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -27,6 +27,7 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
27 case Q_SYNC: 27 case Q_SYNC:
28 case Q_GETINFO: 28 case Q_GETINFO:
29 case Q_XGETQSTAT: 29 case Q_XGETQSTAT:
30 case Q_XGETQSTATV:
30 case Q_XQUOTASYNC: 31 case Q_XQUOTASYNC:
31 break; 32 break;
32 /* allow to query information for dquots we "own" */ 33 /* allow to query information for dquots we "own" */
@@ -217,6 +218,31 @@ static int quota_getxstate(struct super_block *sb, void __user *addr)
217 return ret; 218 return ret;
218} 219}
219 220
221static int quota_getxstatev(struct super_block *sb, void __user *addr)
222{
223 struct fs_quota_statv fqs;
224 int ret;
225
226 if (!sb->s_qcop->get_xstatev)
227 return -ENOSYS;
228
229 memset(&fqs, 0, sizeof(fqs));
230 if (copy_from_user(&fqs, addr, 1)) /* Just read qs_version */
231 return -EFAULT;
232
233 /* If this kernel doesn't support user specified version, fail */
234 switch (fqs.qs_version) {
235 case FS_QSTATV_VERSION1:
236 break;
237 default:
238 return -EINVAL;
239 }
240 ret = sb->s_qcop->get_xstatev(sb, &fqs);
241 if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
242 return -EFAULT;
243 return ret;
244}
245
220static int quota_setxquota(struct super_block *sb, int type, qid_t id, 246static int quota_setxquota(struct super_block *sb, int type, qid_t id,
221 void __user *addr) 247 void __user *addr)
222{ 248{
@@ -293,6 +319,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
293 return quota_setxstate(sb, cmd, addr); 319 return quota_setxstate(sb, cmd, addr);
294 case Q_XGETQSTAT: 320 case Q_XGETQSTAT:
295 return quota_getxstate(sb, addr); 321 return quota_getxstate(sb, addr);
322 case Q_XGETQSTATV:
323 return quota_getxstatev(sb, addr);
296 case Q_XSETQLIM: 324 case Q_XSETQLIM:
297 return quota_setxquota(sb, type, id, addr); 325 return quota_setxquota(sb, type, id, addr);
298 case Q_XGETQUOTA: 326 case Q_XGETQUOTA:
@@ -317,6 +345,7 @@ static int quotactl_cmd_write(int cmd)
317 case Q_GETINFO: 345 case Q_GETINFO:
318 case Q_SYNC: 346 case Q_SYNC:
319 case Q_XGETQSTAT: 347 case Q_XGETQSTAT:
348 case Q_XGETQSTATV:
320 case Q_XGETQUOTA: 349 case Q_XGETQUOTA:
321 case Q_XQUOTASYNC: 350 case Q_XQUOTASYNC:
322 return 0; 351 return 0;
diff --git a/include/linux/quota.h b/include/linux/quota.h
index d13371134c59..cc7494a35429 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -328,6 +328,7 @@ struct quotactl_ops {
328 int (*set_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *); 328 int (*set_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *);
329 int (*get_xstate)(struct super_block *, struct fs_quota_stat *); 329 int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
330 int (*set_xstate)(struct super_block *, unsigned int, int); 330 int (*set_xstate)(struct super_block *, unsigned int, int);
331 int (*get_xstatev)(struct super_block *, struct fs_quota_statv *);
331}; 332};
332 333
333struct quota_format_type { 334struct quota_format_type {
diff --git a/include/uapi/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h
index 86552807aed9..dcd75cc26196 100644
--- a/include/uapi/linux/dqblk_xfs.h
+++ b/include/uapi/linux/dqblk_xfs.h
@@ -38,6 +38,7 @@
38#define Q_XGETQSTAT XQM_CMD(5) /* get quota subsystem status */ 38#define Q_XGETQSTAT XQM_CMD(5) /* get quota subsystem status */
39#define Q_XQUOTARM XQM_CMD(6) /* free disk space used by dquots */ 39#define Q_XQUOTARM XQM_CMD(6) /* free disk space used by dquots */
40#define Q_XQUOTASYNC XQM_CMD(7) /* delalloc flush, updates dquots */ 40#define Q_XQUOTASYNC XQM_CMD(7) /* delalloc flush, updates dquots */
41#define Q_XGETQSTATV XQM_CMD(8) /* newer version of get quota */
41 42
42/* 43/*
43 * fs_disk_quota structure: 44 * fs_disk_quota structure:
@@ -163,4 +164,50 @@ typedef struct fs_quota_stat {
163 __u16 qs_iwarnlimit; /* limit for num warnings */ 164 __u16 qs_iwarnlimit; /* limit for num warnings */
164} fs_quota_stat_t; 165} fs_quota_stat_t;
165 166
167/*
168 * fs_quota_statv is used by Q_XGETQSTATV for a given file system. It provides
169 * a centralized way to get meta information about the quota subsystem. eg.
170 * space taken up for user, group, and project quotas, number of dquots
171 * currently incore.
172 *
173 * This version has proper versioning support with appropriate padding for
174 * future expansions, and ability to expand for future without creating any
175 * backward compatibility issues.
176 *
177 * Q_XGETQSTATV uses the passed in value of the requested version via
178 * fs_quota_statv.qs_version to determine the return data layout of
179 * fs_quota_statv. The kernel will fill the data fields relevant to that
180 * version.
181 *
182 * If kernel does not support user space caller specified version, EINVAL will
183 * be returned. User space caller can then reduce the version number and retry
184 * the same command.
185 */
186#define FS_QSTATV_VERSION1 1 /* fs_quota_statv.qs_version */
187/*
188 * Some basic information about 'quota files' for Q_XGETQSTATV command
189 */
190struct fs_qfilestatv {
191 __u64 qfs_ino; /* inode number */
192 __u64 qfs_nblks; /* number of BBs 512-byte-blks */
193 __u32 qfs_nextents; /* number of extents */
194 __u32 qfs_pad; /* pad for 8-byte alignment */
195};
196
197struct fs_quota_statv {
198 __s8 qs_version; /* version for future changes */
199 __u8 qs_pad1; /* pad for 16bit alignment */
200 __u16 qs_flags; /* FS_QUOTA_.* flags */
201 __u32 qs_incoredqs; /* number of dquots incore */
202 struct fs_qfilestatv qs_uquota; /* user quota information */
203 struct fs_qfilestatv qs_gquota; /* group quota information */
204 struct fs_qfilestatv qs_pquota; /* project quota information */
205 __s32 qs_btimelimit; /* limit for blks timer */
206 __s32 qs_itimelimit; /* limit for inodes timer */
207 __s32 qs_rtbtimelimit;/* limit for rt blks timer */
208 __u16 qs_bwarnlimit; /* limit for num warnings */
209 __u16 qs_iwarnlimit; /* limit for num warnings */
210 __u64 qs_pad2[8]; /* for future proofing */
211};
212
166#endif /* _LINUX_DQBLK_XFS_H */ 213#endif /* _LINUX_DQBLK_XFS_H */