ext4: don't allow quota mount options when quota feature enabled
[cascardo/linux.git] / fs / ext4 / super.c
index 990ceab..b7deba7 100644 (file)
@@ -1248,6 +1248,11 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
                        "quota options when quota turned on");
                return -1;
        }
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) {
+               ext4_msg(sb, KERN_ERR, "Cannot set journaled quota options "
+                        "when QUOTA feature is enabled");
+               return -1;
+       }
        qname = match_strdup(args);
        if (!qname) {
                ext4_msg(sb, KERN_ERR,
@@ -1545,6 +1550,13 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
                                 "quota options when quota turned on");
                        return -1;
                }
+               if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
+                                              EXT4_FEATURE_RO_COMPAT_QUOTA)) {
+                       ext4_msg(sb, KERN_ERR,
+                                "Cannot set journaled quota options "
+                                "when QUOTA feature is enabled");
+                       return -1;
+               }
                sbi->s_jquota_fmt = m->mount_opt;
 #endif
        } else {
@@ -1593,6 +1605,12 @@ static int parse_options(char *options, struct super_block *sb,
                        return 0;
        }
 #ifdef CONFIG_QUOTA
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
+           (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) {
+               ext4_msg(sb, KERN_ERR, "Cannot set quota options when QUOTA "
+                        "feature is enabled");
+               return 0;
+       }
        if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
                if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
                        clear_opt(sb, USRQUOTA);
@@ -3715,13 +3733,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_export_op = &ext4_export_ops;
        sb->s_xattr = ext4_xattr_handlers;
 #ifdef CONFIG_QUOTA
-       sb->s_qcop = &ext4_qctl_operations;
        sb->dq_op = &ext4_quota_operations;
-
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) {
-               /* Use qctl operations for hidden quota files. */
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
                sb->s_qcop = &ext4_qctl_sysfile_operations;
-       }
+       else
+               sb->s_qcop = &ext4_qctl_operations;
 #endif
        memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
 
@@ -4822,9 +4838,12 @@ static int ext4_release_dquot(struct dquot *dquot)
 
 static int ext4_mark_dquot_dirty(struct dquot *dquot)
 {
+       struct super_block *sb = dquot->dq_sb;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
        /* Are we journaling quotas? */
-       if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
-           EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) ||
+           sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
                dquot_mark_dquot_dirty(dquot);
                return ext4_write_dquot(dquot);
        } else {