1 ext4: enable quota enforcement based on mount options
3 From: Jan Kara <jack@suse.cz>
5 When quota information is stored in quota files, we enable only quota
6 accounting on mount and enforcement is enabled only in response to
7 Q_QUOTAON quotactl. To make ext4 behavior consistent with XFS, we add a
8 possibility to enable quota enforcement on mount by specifying
9 corresponding quota mount option (usrquota, grpquota, prjquota).
11 Signed-off-by: Jan Kara <jack@suse.cz>
12 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
14 fs/ext4/ext4.h | 12 +++++++++---
15 fs/ext4/super.c | 34 ++++++++++++++++++++++++----------
16 2 files changed, 33 insertions(+), 13 deletions(-)
18 The patch passed xfstests both with old style and new style quotas and some
19 targetted manual tests so here we go... Ted please merge the patch if you
22 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
23 index b84aa1ca480a..224cb832e2dc 100644
26 @@ -1129,9 +1129,15 @@ struct ext4_inode_info {
27 #define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
28 #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */
29 #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */
30 -#define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
31 -#define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
32 -#define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
33 +#define EXT4_MOUNT_QUOTA 0x40000 /* Some quota option set */
34 +#define EXT4_MOUNT_USRQUOTA 0x80000 /* "old" user quota,
35 + * enable enforcement for hidden
37 +#define EXT4_MOUNT_GRPQUOTA 0x100000 /* "old" group quota, enable
38 + * enforcement for hidden quota
40 +#define EXT4_MOUNT_PRJQUOTA 0x200000 /* Enable project quota
42 #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */
43 #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
44 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
45 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
46 index 3822a5aedc61..a03232634cd5 100644
49 @@ -1187,7 +1187,7 @@ enum {
50 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
51 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
52 Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
53 - Opt_usrquota, Opt_grpquota, Opt_i_version, Opt_dax,
54 + Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version, Opt_dax,
55 Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
56 Opt_lazytime, Opt_nolazytime,
57 Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
58 @@ -1247,6 +1247,7 @@ static const match_table_t tokens = {
59 {Opt_noquota, "noquota"},
61 {Opt_usrquota, "usrquota"},
62 + {Opt_prjquota, "prjquota"},
63 {Opt_barrier, "barrier=%u"},
64 {Opt_barrier, "barrier"},
65 {Opt_nobarrier, "nobarrier"},
66 @@ -1466,8 +1467,11 @@ static const struct mount_opts {
68 {Opt_grpquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_GRPQUOTA,
70 + {Opt_prjquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_PRJQUOTA,
72 {Opt_noquota, (EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA |
73 - EXT4_MOUNT_GRPQUOTA), MOPT_CLEAR | MOPT_Q},
74 + EXT4_MOUNT_GRPQUOTA | EXT4_MOUNT_PRJQUOTA),
75 + MOPT_CLEAR | MOPT_Q},
76 {Opt_usrjquota, 0, MOPT_Q},
77 {Opt_grpjquota, 0, MOPT_Q},
78 {Opt_offusrjquota, 0, MOPT_Q},
79 @@ -1756,13 +1760,17 @@ static int parse_options(char *options, struct super_block *sb,
83 - if (ext4_has_feature_quota(sb) &&
84 - (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) {
85 - ext4_msg(sb, KERN_INFO, "Quota feature enabled, usrquota and grpquota "
86 - "mount options ignored.");
87 - clear_opt(sb, USRQUOTA);
88 - clear_opt(sb, GRPQUOTA);
89 - } else if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
91 + * We do the test below only for project quotas. 'usrquota' and
92 + * 'grpquota' mount options are allowed even without quota feature
93 + * to support legacy quotas in quota files.
95 + if (test_opt(sb, PRJQUOTA) && !ext4_has_feature_project(sb)) {
96 + ext4_msg(sb, KERN_ERR, "Project quota feature not enabled. "
97 + "Cannot enable project quota enforcement.");
100 + if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
101 if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
102 clear_opt(sb, USRQUOTA);
104 @@ -5129,12 +5137,18 @@ static int ext4_enable_quotas(struct super_block *sb)
105 le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum),
106 le32_to_cpu(EXT4_SB(sb)->s_es->s_prj_quota_inum)
108 + bool quota_mopt[EXT4_MAXQUOTAS] = {
109 + test_opt(sb, USRQUOTA),
110 + test_opt(sb, GRPQUOTA),
111 + test_opt(sb, PRJQUOTA),
114 sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
115 for (type = 0; type < EXT4_MAXQUOTAS; type++) {
116 if (qf_inums[type]) {
117 err = ext4_quota_enable(sb, type, QFMT_VFS_V1,
118 - DQUOT_USAGE_ENABLED);
119 + DQUOT_USAGE_ENABLED |
120 + (quota_mopt[type] ? DQUOT_LIMITS_ENABLED : 0));
123 "Failed to enable quota tracking "
128 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
129 the body of a message to majordomo@vger.kernel.org
130 More majordomo info at http://vger.kernel.org/majordomo-info.html