add patch create-function-to-read-journal-inode
[ext4-patch-queue.git] / enable-quota-enforcement-based-on-mount-options
blob742f4ef581bf5406c0d97091be9411871c31ec02
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>
13 ---
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
20 agree with it.
22 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
23 index b84aa1ca480a..224cb832e2dc 100644
24 --- a/fs/ext4/ext4.h
25 +++ b/fs/ext4/ext4.h
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
36 +                                                * quota files */
37 +#define EXT4_MOUNT_GRPQUOTA            0x100000 /* "old" group quota, enable
38 +                                                 * enforcement for hidden quota
39 +                                                 * files */
40 +#define EXT4_MOUNT_PRJQUOTA            0x200000 /* Enable project quota
41 +                                                 * enforcement */
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
47 --- a/fs/ext4/super.c
48 +++ b/fs/ext4/super.c
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"},
60         {Opt_quota, "quota"},
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 {
67                                                         MOPT_SET | MOPT_Q},
68         {Opt_grpquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_GRPQUOTA,
69                                                         MOPT_SET | MOPT_Q},
70 +       {Opt_prjquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_PRJQUOTA,
71 +                                                       MOPT_SET | MOPT_Q},
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,
80                         return 0;
81         }
82  #ifdef CONFIG_QUOTA
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]) {
90 +       /*
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.
94 +        */
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.");
98 +               return 0;
99 +       }
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)
107         };
108 +       bool quota_mopt[EXT4_MAXQUOTAS] = {
109 +               test_opt(sb, USRQUOTA),
110 +               test_opt(sb, GRPQUOTA),
111 +               test_opt(sb, PRJQUOTA),
112 +       };
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));
121                         if (err) {
122                                 ext4_warning(sb,
123                                         "Failed to enable quota tracking "
124 -- 
125 2.6.6
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