浏览代码

ext3: correct mount option parsing to detect when quota options can be changed

We should not allow user to change quota mount options when quota is just
suspended.  I would make mount options and internal quota state inconsistent.
Also we should not allow user to change quota format when quota is turned on.
On the other hand we can just silently ignore when some option is set to the
value it already has (mount does this on remount).

Cc: <linux-ext4@vger.kernel.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Jan Kara 17 年之前
父节点
当前提交
d06bf1d252
共有 1 个文件被更改,包括 22 次插入7 次删除
  1. 22 7
      fs/ext3/super.c

+ 22 - 7
fs/ext3/super.c

@@ -842,7 +842,7 @@ static int parse_options (char *options, struct super_block *sb,
 	int data_opt = 0;
 	int data_opt = 0;
 	int option;
 	int option;
 #ifdef CONFIG_QUOTA
 #ifdef CONFIG_QUOTA
-	int qtype;
+	int qtype, qfmt;
 	char *qname;
 	char *qname;
 #endif
 #endif
 
 
@@ -1018,7 +1018,9 @@ static int parse_options (char *options, struct super_block *sb,
 		case Opt_grpjquota:
 		case Opt_grpjquota:
 			qtype = GRPQUOTA;
 			qtype = GRPQUOTA;
 set_qf_name:
 set_qf_name:
-			if (sb_any_quota_enabled(sb)) {
+			if ((sb_any_quota_enabled(sb) ||
+			     sb_any_quota_suspended(sb)) &&
+			    !sbi->s_qf_names[qtype]) {
 				printk(KERN_ERR
 				printk(KERN_ERR
 					"EXT3-fs: Cannot change journaled "
 					"EXT3-fs: Cannot change journaled "
 					"quota options when quota turned on.\n");
 					"quota options when quota turned on.\n");
@@ -1056,7 +1058,9 @@ set_qf_name:
 		case Opt_offgrpjquota:
 		case Opt_offgrpjquota:
 			qtype = GRPQUOTA;
 			qtype = GRPQUOTA;
 clear_qf_name:
 clear_qf_name:
-			if (sb_any_quota_enabled(sb)) {
+			if ((sb_any_quota_enabled(sb) ||
+			     sb_any_quota_suspended(sb)) &&
+			    sbi->s_qf_names[qtype]) {
 				printk(KERN_ERR "EXT3-fs: Cannot change "
 				printk(KERN_ERR "EXT3-fs: Cannot change "
 					"journaled quota options when "
 					"journaled quota options when "
 					"quota turned on.\n");
 					"quota turned on.\n");
@@ -1069,10 +1073,20 @@ clear_qf_name:
 			sbi->s_qf_names[qtype] = NULL;
 			sbi->s_qf_names[qtype] = NULL;
 			break;
 			break;
 		case Opt_jqfmt_vfsold:
 		case Opt_jqfmt_vfsold:
-			sbi->s_jquota_fmt = QFMT_VFS_OLD;
-			break;
+			qfmt = QFMT_VFS_OLD;
+			goto set_qf_format;
 		case Opt_jqfmt_vfsv0:
 		case Opt_jqfmt_vfsv0:
-			sbi->s_jquota_fmt = QFMT_VFS_V0;
+			qfmt = QFMT_VFS_V0;
+set_qf_format:
+			if ((sb_any_quota_enabled(sb) ||
+			     sb_any_quota_suspended(sb)) &&
+			    sbi->s_jquota_fmt != qfmt) {
+				printk(KERN_ERR "EXT3-fs: Cannot change "
+					"journaled quota options when "
+					"quota turned on.\n");
+				return 0;
+			}
+			sbi->s_jquota_fmt = qfmt;
 			break;
 			break;
 		case Opt_quota:
 		case Opt_quota:
 		case Opt_usrquota:
 		case Opt_usrquota:
@@ -1084,7 +1098,8 @@ clear_qf_name:
 			set_opt(sbi->s_mount_opt, GRPQUOTA);
 			set_opt(sbi->s_mount_opt, GRPQUOTA);
 			break;
 			break;
 		case Opt_noquota:
 		case Opt_noquota:
-			if (sb_any_quota_enabled(sb)) {
+			if (sb_any_quota_enabled(sb) ||
+			    sb_any_quota_suspended(sb)) {
 				printk(KERN_ERR "EXT3-fs: Cannot change quota "
 				printk(KERN_ERR "EXT3-fs: Cannot change quota "
 					"options when quota turned on.\n");
 					"options when quota turned on.\n");
 				return 0;
 				return 0;