diff options
| author | Theodore Ts'o <tytso@mit.edu> | 2012-04-16 18:55:26 -0400 |
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2012-04-16 18:55:26 -0400 |
| commit | 57f73c2c89a5d3b2ed87201c8100d1fa989a1a65 (patch) | |
| tree | 7615419aa669cb652099dd3a37439f475a2fbaa5 | |
| parent | 9cd70b347e9761ea2d2ac3d758c529a48a8193e6 (diff) | |
ext4: fix handling of journalled quota options
Commit 26092bf5 broke handling of journalled quota mount options by
trying to parse argument of every mount option as a number. Fix this
by dealing with the quota options before we call match_int().
Thanks to Jan Kara for discovering this regression.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
| -rw-r--r-- | fs/ext4/super.c | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ef7db5044262..6da193564e43 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -1305,20 +1305,20 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) | |||
| 1305 | ext4_msg(sb, KERN_ERR, | 1305 | ext4_msg(sb, KERN_ERR, |
| 1306 | "Cannot change journaled " | 1306 | "Cannot change journaled " |
| 1307 | "quota options when quota turned on"); | 1307 | "quota options when quota turned on"); |
| 1308 | return 0; | 1308 | return -1; |
| 1309 | } | 1309 | } |
| 1310 | qname = match_strdup(args); | 1310 | qname = match_strdup(args); |
| 1311 | if (!qname) { | 1311 | if (!qname) { |
| 1312 | ext4_msg(sb, KERN_ERR, | 1312 | ext4_msg(sb, KERN_ERR, |
| 1313 | "Not enough memory for storing quotafile name"); | 1313 | "Not enough memory for storing quotafile name"); |
| 1314 | return 0; | 1314 | return -1; |
| 1315 | } | 1315 | } |
| 1316 | if (sbi->s_qf_names[qtype] && | 1316 | if (sbi->s_qf_names[qtype] && |
| 1317 | strcmp(sbi->s_qf_names[qtype], qname)) { | 1317 | strcmp(sbi->s_qf_names[qtype], qname)) { |
| 1318 | ext4_msg(sb, KERN_ERR, | 1318 | ext4_msg(sb, KERN_ERR, |
| 1319 | "%s quota file already specified", QTYPE2NAME(qtype)); | 1319 | "%s quota file already specified", QTYPE2NAME(qtype)); |
| 1320 | kfree(qname); | 1320 | kfree(qname); |
| 1321 | return 0; | 1321 | return -1; |
| 1322 | } | 1322 | } |
| 1323 | sbi->s_qf_names[qtype] = qname; | 1323 | sbi->s_qf_names[qtype] = qname; |
| 1324 | if (strchr(sbi->s_qf_names[qtype], '/')) { | 1324 | if (strchr(sbi->s_qf_names[qtype], '/')) { |
| @@ -1326,7 +1326,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) | |||
| 1326 | "quotafile must be on filesystem root"); | 1326 | "quotafile must be on filesystem root"); |
| 1327 | kfree(sbi->s_qf_names[qtype]); | 1327 | kfree(sbi->s_qf_names[qtype]); |
| 1328 | sbi->s_qf_names[qtype] = NULL; | 1328 | sbi->s_qf_names[qtype] = NULL; |
| 1329 | return 0; | 1329 | return -1; |
| 1330 | } | 1330 | } |
| 1331 | set_opt(sb, QUOTA); | 1331 | set_opt(sb, QUOTA); |
| 1332 | return 1; | 1332 | return 1; |
| @@ -1341,7 +1341,7 @@ static int clear_qf_name(struct super_block *sb, int qtype) | |||
| 1341 | sbi->s_qf_names[qtype]) { | 1341 | sbi->s_qf_names[qtype]) { |
| 1342 | ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" | 1342 | ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" |
| 1343 | " when quota turned on"); | 1343 | " when quota turned on"); |
| 1344 | return 0; | 1344 | return -1; |
| 1345 | } | 1345 | } |
| 1346 | /* | 1346 | /* |
| 1347 | * The space will be released later when all options are confirmed | 1347 | * The space will be released later when all options are confirmed |
| @@ -1450,6 +1450,16 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, | |||
| 1450 | const struct mount_opts *m; | 1450 | const struct mount_opts *m; |
| 1451 | int arg = 0; | 1451 | int arg = 0; |
| 1452 | 1452 | ||
| 1453 | #ifdef CONFIG_QUOTA | ||
| 1454 | if (token == Opt_usrjquota) | ||
| 1455 | return set_qf_name(sb, USRQUOTA, &args[0]); | ||
| 1456 | else if (token == Opt_grpjquota) | ||
| 1457 | return set_qf_name(sb, GRPQUOTA, &args[0]); | ||
| 1458 | else if (token == Opt_offusrjquota) | ||
| 1459 | return clear_qf_name(sb, USRQUOTA); | ||
| 1460 | else if (token == Opt_offgrpjquota) | ||
| 1461 | return clear_qf_name(sb, GRPQUOTA); | ||
| 1462 | #endif | ||
| 1453 | if (args->from && match_int(args, &arg)) | 1463 | if (args->from && match_int(args, &arg)) |
| 1454 | return -1; | 1464 | return -1; |
| 1455 | switch (token) { | 1465 | switch (token) { |
| @@ -1549,18 +1559,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, | |||
| 1549 | sbi->s_mount_opt |= m->mount_opt; | 1559 | sbi->s_mount_opt |= m->mount_opt; |
| 1550 | } | 1560 | } |
| 1551 | #ifdef CONFIG_QUOTA | 1561 | #ifdef CONFIG_QUOTA |
| 1552 | } else if (token == Opt_usrjquota) { | ||
| 1553 | if (!set_qf_name(sb, USRQUOTA, &args[0])) | ||
| 1554 | return -1; | ||
| 1555 | } else if (token == Opt_grpjquota) { | ||
| 1556 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) | ||
| 1557 | return -1; | ||
| 1558 | } else if (token == Opt_offusrjquota) { | ||
| 1559 | if (!clear_qf_name(sb, USRQUOTA)) | ||
| 1560 | return -1; | ||
| 1561 | } else if (token == Opt_offgrpjquota) { | ||
| 1562 | if (!clear_qf_name(sb, GRPQUOTA)) | ||
| 1563 | return -1; | ||
| 1564 | } else if (m->flags & MOPT_QFMT) { | 1562 | } else if (m->flags & MOPT_QFMT) { |
| 1565 | if (sb_any_quota_loaded(sb) && | 1563 | if (sb_any_quota_loaded(sb) && |
| 1566 | sbi->s_jquota_fmt != m->mount_opt) { | 1564 | sbi->s_jquota_fmt != m->mount_opt) { |
