diff options
| -rw-r--r-- | fs/ext4/super.c | 123 |
1 files changed, 69 insertions, 54 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7e8b1b4236d3..79937e921988 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -1206,6 +1206,64 @@ static ext4_fsblk_t get_sb_block(void **data) | |||
| 1206 | 1206 | ||
| 1207 | #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) | 1207 | #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) |
| 1208 | 1208 | ||
| 1209 | #ifdef CONFIG_QUOTA | ||
| 1210 | static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) | ||
| 1211 | { | ||
| 1212 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 1213 | char *qname; | ||
| 1214 | |||
| 1215 | if (sb_any_quota_loaded(sb) && | ||
| 1216 | !sbi->s_qf_names[qtype]) { | ||
| 1217 | ext4_msg(sb, KERN_ERR, | ||
| 1218 | "Cannot change journaled " | ||
| 1219 | "quota options when quota turned on"); | ||
| 1220 | return 0; | ||
| 1221 | } | ||
| 1222 | qname = match_strdup(args); | ||
| 1223 | if (!qname) { | ||
| 1224 | ext4_msg(sb, KERN_ERR, | ||
| 1225 | "Not enough memory for storing quotafile name"); | ||
| 1226 | return 0; | ||
| 1227 | } | ||
| 1228 | if (sbi->s_qf_names[qtype] && | ||
| 1229 | strcmp(sbi->s_qf_names[qtype], qname)) { | ||
| 1230 | ext4_msg(sb, KERN_ERR, | ||
| 1231 | "%s quota file already specified", QTYPE2NAME(qtype)); | ||
| 1232 | kfree(qname); | ||
| 1233 | return 0; | ||
| 1234 | } | ||
| 1235 | sbi->s_qf_names[qtype] = qname; | ||
| 1236 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
| 1237 | ext4_msg(sb, KERN_ERR, | ||
| 1238 | "quotafile must be on filesystem root"); | ||
| 1239 | kfree(sbi->s_qf_names[qtype]); | ||
| 1240 | sbi->s_qf_names[qtype] = NULL; | ||
| 1241 | return 0; | ||
| 1242 | } | ||
| 1243 | set_opt(sbi->s_mount_opt, QUOTA); | ||
| 1244 | return 1; | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | static int clear_qf_name(struct super_block *sb, int qtype) | ||
| 1248 | { | ||
| 1249 | |||
| 1250 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 1251 | |||
| 1252 | if (sb_any_quota_loaded(sb) && | ||
| 1253 | sbi->s_qf_names[qtype]) { | ||
| 1254 | ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" | ||
| 1255 | " when quota turned on"); | ||
| 1256 | return 0; | ||
| 1257 | } | ||
| 1258 | /* | ||
| 1259 | * The space will be released later when all options are confirmed | ||
| 1260 | * to be correct | ||
| 1261 | */ | ||
| 1262 | sbi->s_qf_names[qtype] = NULL; | ||
| 1263 | return 1; | ||
| 1264 | } | ||
| 1265 | #endif | ||
| 1266 | |||
| 1209 | static int parse_options(char *options, struct super_block *sb, | 1267 | static int parse_options(char *options, struct super_block *sb, |
| 1210 | unsigned long *journal_devnum, | 1268 | unsigned long *journal_devnum, |
| 1211 | unsigned int *journal_ioprio, | 1269 | unsigned int *journal_ioprio, |
| @@ -1217,8 +1275,7 @@ static int parse_options(char *options, struct super_block *sb, | |||
| 1217 | int data_opt = 0; | 1275 | int data_opt = 0; |
| 1218 | int option; | 1276 | int option; |
| 1219 | #ifdef CONFIG_QUOTA | 1277 | #ifdef CONFIG_QUOTA |
| 1220 | int qtype, qfmt; | 1278 | int qfmt; |
| 1221 | char *qname; | ||
| 1222 | #endif | 1279 | #endif |
| 1223 | 1280 | ||
| 1224 | if (!options) | 1281 | if (!options) |
| @@ -1401,63 +1458,22 @@ static int parse_options(char *options, struct super_block *sb, | |||
| 1401 | break; | 1458 | break; |
| 1402 | #ifdef CONFIG_QUOTA | 1459 | #ifdef CONFIG_QUOTA |
| 1403 | case Opt_usrjquota: | 1460 | case Opt_usrjquota: |
| 1404 | qtype = USRQUOTA; | 1461 | if (!set_qf_name(sb, USRQUOTA, &args[0])) |
| 1405 | goto set_qf_name; | ||
| 1406 | case Opt_grpjquota: | ||
| 1407 | qtype = GRPQUOTA; | ||
| 1408 | set_qf_name: | ||
| 1409 | if (sb_any_quota_loaded(sb) && | ||
| 1410 | !sbi->s_qf_names[qtype]) { | ||
| 1411 | ext4_msg(sb, KERN_ERR, | ||
| 1412 | "Cannot change journaled " | ||
| 1413 | "quota options when quota turned on"); | ||
| 1414 | return 0; | 1462 | return 0; |
| 1415 | } | 1463 | break; |
| 1416 | qname = match_strdup(&args[0]); | 1464 | case Opt_grpjquota: |
| 1417 | if (!qname) { | 1465 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) |
| 1418 | ext4_msg(sb, KERN_ERR, | ||
| 1419 | "Not enough memory for " | ||
| 1420 | "storing quotafile name"); | ||
| 1421 | return 0; | ||
| 1422 | } | ||
| 1423 | if (sbi->s_qf_names[qtype] && | ||
| 1424 | strcmp(sbi->s_qf_names[qtype], qname)) { | ||
| 1425 | ext4_msg(sb, KERN_ERR, | ||
| 1426 | "%s quota file already " | ||
| 1427 | "specified", QTYPE2NAME(qtype)); | ||
| 1428 | kfree(qname); | ||
| 1429 | return 0; | ||
| 1430 | } | ||
| 1431 | sbi->s_qf_names[qtype] = qname; | ||
| 1432 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
| 1433 | ext4_msg(sb, KERN_ERR, | ||
| 1434 | "quotafile must be on " | ||
| 1435 | "filesystem root"); | ||
| 1436 | kfree(sbi->s_qf_names[qtype]); | ||
| 1437 | sbi->s_qf_names[qtype] = NULL; | ||
| 1438 | return 0; | 1466 | return 0; |
| 1439 | } | ||
| 1440 | set_opt(sbi->s_mount_opt, QUOTA); | ||
| 1441 | break; | 1467 | break; |
| 1442 | case Opt_offusrjquota: | 1468 | case Opt_offusrjquota: |
| 1443 | qtype = USRQUOTA; | 1469 | if (!clear_qf_name(sb, USRQUOTA)) |
| 1444 | goto clear_qf_name; | 1470 | return 0; |
| 1471 | break; | ||
| 1445 | case Opt_offgrpjquota: | 1472 | case Opt_offgrpjquota: |
| 1446 | qtype = GRPQUOTA; | 1473 | if (!clear_qf_name(sb, GRPQUOTA)) |
| 1447 | clear_qf_name: | ||
| 1448 | if (sb_any_quota_loaded(sb) && | ||
| 1449 | sbi->s_qf_names[qtype]) { | ||
| 1450 | ext4_msg(sb, KERN_ERR, "Cannot change " | ||
| 1451 | "journaled quota options when " | ||
| 1452 | "quota turned on"); | ||
| 1453 | return 0; | 1474 | return 0; |
| 1454 | } | ||
| 1455 | /* | ||
| 1456 | * The space will be released later when all options | ||
| 1457 | * are confirmed to be correct | ||
| 1458 | */ | ||
| 1459 | sbi->s_qf_names[qtype] = NULL; | ||
| 1460 | break; | 1475 | break; |
| 1476 | |||
| 1461 | case Opt_jqfmt_vfsold: | 1477 | case Opt_jqfmt_vfsold: |
| 1462 | qfmt = QFMT_VFS_OLD; | 1478 | qfmt = QFMT_VFS_OLD; |
| 1463 | goto set_qf_format; | 1479 | goto set_qf_format; |
| @@ -1630,8 +1646,7 @@ set_qf_format: | |||
| 1630 | if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) | 1646 | if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) |
| 1631 | clear_opt(sbi->s_mount_opt, GRPQUOTA); | 1647 | clear_opt(sbi->s_mount_opt, GRPQUOTA); |
| 1632 | 1648 | ||
| 1633 | if ((sbi->s_qf_names[USRQUOTA] && test_opt(sb, GRPQUOTA)) || | 1649 | if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) { |
| 1634 | (sbi->s_qf_names[GRPQUOTA] && test_opt(sb, USRQUOTA))) { | ||
| 1635 | ext4_msg(sb, KERN_ERR, "old and new quota " | 1650 | ext4_msg(sb, KERN_ERR, "old and new quota " |
| 1636 | "format mixing"); | 1651 | "format mixing"); |
| 1637 | return 0; | 1652 | return 0; |
