diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 342 |
1 files changed, 217 insertions, 125 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 735c20d5fd56..ad1ee5f21bab 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -333,7 +333,7 @@ static void ext4_handle_error(struct super_block *sb) | |||
333 | sb->s_id); | 333 | sb->s_id); |
334 | } | 334 | } |
335 | 335 | ||
336 | void ext4_error(struct super_block *sb, const char *function, | 336 | void __ext4_error(struct super_block *sb, const char *function, |
337 | const char *fmt, ...) | 337 | const char *fmt, ...) |
338 | { | 338 | { |
339 | va_list args; | 339 | va_list args; |
@@ -347,6 +347,42 @@ void ext4_error(struct super_block *sb, const char *function, | |||
347 | ext4_handle_error(sb); | 347 | ext4_handle_error(sb); |
348 | } | 348 | } |
349 | 349 | ||
350 | void ext4_error_inode(const char *function, struct inode *inode, | ||
351 | const char *fmt, ...) | ||
352 | { | ||
353 | va_list args; | ||
354 | |||
355 | va_start(args, fmt); | ||
356 | printk(KERN_CRIT "EXT4-fs error (device %s): %s: inode #%lu: (comm %s) ", | ||
357 | inode->i_sb->s_id, function, inode->i_ino, current->comm); | ||
358 | vprintk(fmt, args); | ||
359 | printk("\n"); | ||
360 | va_end(args); | ||
361 | |||
362 | ext4_handle_error(inode->i_sb); | ||
363 | } | ||
364 | |||
365 | void ext4_error_file(const char *function, struct file *file, | ||
366 | const char *fmt, ...) | ||
367 | { | ||
368 | va_list args; | ||
369 | struct inode *inode = file->f_dentry->d_inode; | ||
370 | char pathname[80], *path; | ||
371 | |||
372 | va_start(args, fmt); | ||
373 | path = d_path(&(file->f_path), pathname, sizeof(pathname)); | ||
374 | if (!path) | ||
375 | path = "(unknown)"; | ||
376 | printk(KERN_CRIT | ||
377 | "EXT4-fs error (device %s): %s: inode #%lu (comm %s path %s): ", | ||
378 | inode->i_sb->s_id, function, inode->i_ino, current->comm, path); | ||
379 | vprintk(fmt, args); | ||
380 | printk("\n"); | ||
381 | va_end(args); | ||
382 | |||
383 | ext4_handle_error(inode->i_sb); | ||
384 | } | ||
385 | |||
350 | static const char *ext4_decode_error(struct super_block *sb, int errno, | 386 | static const char *ext4_decode_error(struct super_block *sb, int errno, |
351 | char nbuf[16]) | 387 | char nbuf[16]) |
352 | { | 388 | { |
@@ -450,7 +486,7 @@ void ext4_msg (struct super_block * sb, const char *prefix, | |||
450 | va_end(args); | 486 | va_end(args); |
451 | } | 487 | } |
452 | 488 | ||
453 | void ext4_warning(struct super_block *sb, const char *function, | 489 | void __ext4_warning(struct super_block *sb, const char *function, |
454 | const char *fmt, ...) | 490 | const char *fmt, ...) |
455 | { | 491 | { |
456 | va_list args; | 492 | va_list args; |
@@ -507,7 +543,7 @@ void ext4_update_dynamic_rev(struct super_block *sb) | |||
507 | if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV) | 543 | if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV) |
508 | return; | 544 | return; |
509 | 545 | ||
510 | ext4_warning(sb, __func__, | 546 | ext4_warning(sb, |
511 | "updating to rev %d because of new feature flag, " | 547 | "updating to rev %d because of new feature flag, " |
512 | "running e2fsck is recommended", | 548 | "running e2fsck is recommended", |
513 | EXT4_DYNAMIC_REV); | 549 | EXT4_DYNAMIC_REV); |
@@ -708,7 +744,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
708 | #ifdef CONFIG_QUOTA | 744 | #ifdef CONFIG_QUOTA |
709 | ei->i_reserved_quota = 0; | 745 | ei->i_reserved_quota = 0; |
710 | #endif | 746 | #endif |
711 | INIT_LIST_HEAD(&ei->i_aio_dio_complete_list); | 747 | INIT_LIST_HEAD(&ei->i_completed_io_list); |
748 | spin_lock_init(&ei->i_completed_io_lock); | ||
712 | ei->cur_aio_dio = NULL; | 749 | ei->cur_aio_dio = NULL; |
713 | ei->i_sync_tid = 0; | 750 | ei->i_sync_tid = 0; |
714 | ei->i_datasync_tid = 0; | 751 | ei->i_datasync_tid = 0; |
@@ -796,10 +833,10 @@ static inline void ext4_show_quota_options(struct seq_file *seq, | |||
796 | if (sbi->s_qf_names[GRPQUOTA]) | 833 | if (sbi->s_qf_names[GRPQUOTA]) |
797 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); | 834 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); |
798 | 835 | ||
799 | if (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) | 836 | if (test_opt(sb, USRQUOTA)) |
800 | seq_puts(seq, ",usrquota"); | 837 | seq_puts(seq, ",usrquota"); |
801 | 838 | ||
802 | if (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) | 839 | if (test_opt(sb, GRPQUOTA)) |
803 | seq_puts(seq, ",grpquota"); | 840 | seq_puts(seq, ",grpquota"); |
804 | #endif | 841 | #endif |
805 | } | 842 | } |
@@ -926,6 +963,9 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
926 | if (test_opt(sb, NOLOAD)) | 963 | if (test_opt(sb, NOLOAD)) |
927 | seq_puts(seq, ",norecovery"); | 964 | seq_puts(seq, ",norecovery"); |
928 | 965 | ||
966 | if (test_opt(sb, DIOREAD_NOLOCK)) | ||
967 | seq_puts(seq, ",dioread_nolock"); | ||
968 | |||
929 | ext4_show_quota_options(seq, sb); | 969 | ext4_show_quota_options(seq, sb); |
930 | 970 | ||
931 | return 0; | 971 | return 0; |
@@ -1109,6 +1149,7 @@ enum { | |||
1109 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1149 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
1110 | Opt_block_validity, Opt_noblock_validity, | 1150 | Opt_block_validity, Opt_noblock_validity, |
1111 | Opt_inode_readahead_blks, Opt_journal_ioprio, | 1151 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
1152 | Opt_dioread_nolock, Opt_dioread_lock, | ||
1112 | Opt_discard, Opt_nodiscard, | 1153 | Opt_discard, Opt_nodiscard, |
1113 | }; | 1154 | }; |
1114 | 1155 | ||
@@ -1176,6 +1217,8 @@ static const match_table_t tokens = { | |||
1176 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, | 1217 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, |
1177 | {Opt_auto_da_alloc, "auto_da_alloc"}, | 1218 | {Opt_auto_da_alloc, "auto_da_alloc"}, |
1178 | {Opt_noauto_da_alloc, "noauto_da_alloc"}, | 1219 | {Opt_noauto_da_alloc, "noauto_da_alloc"}, |
1220 | {Opt_dioread_nolock, "dioread_nolock"}, | ||
1221 | {Opt_dioread_lock, "dioread_lock"}, | ||
1179 | {Opt_discard, "discard"}, | 1222 | {Opt_discard, "discard"}, |
1180 | {Opt_nodiscard, "nodiscard"}, | 1223 | {Opt_nodiscard, "nodiscard"}, |
1181 | {Opt_err, NULL}, | 1224 | {Opt_err, NULL}, |
@@ -1205,6 +1248,66 @@ static ext4_fsblk_t get_sb_block(void **data) | |||
1205 | } | 1248 | } |
1206 | 1249 | ||
1207 | #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) | 1250 | #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) |
1251 | static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n" | ||
1252 | "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; | ||
1253 | |||
1254 | #ifdef CONFIG_QUOTA | ||
1255 | static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) | ||
1256 | { | ||
1257 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1258 | char *qname; | ||
1259 | |||
1260 | if (sb_any_quota_loaded(sb) && | ||
1261 | !sbi->s_qf_names[qtype]) { | ||
1262 | ext4_msg(sb, KERN_ERR, | ||
1263 | "Cannot change journaled " | ||
1264 | "quota options when quota turned on"); | ||
1265 | return 0; | ||
1266 | } | ||
1267 | qname = match_strdup(args); | ||
1268 | if (!qname) { | ||
1269 | ext4_msg(sb, KERN_ERR, | ||
1270 | "Not enough memory for storing quotafile name"); | ||
1271 | return 0; | ||
1272 | } | ||
1273 | if (sbi->s_qf_names[qtype] && | ||
1274 | strcmp(sbi->s_qf_names[qtype], qname)) { | ||
1275 | ext4_msg(sb, KERN_ERR, | ||
1276 | "%s quota file already specified", QTYPE2NAME(qtype)); | ||
1277 | kfree(qname); | ||
1278 | return 0; | ||
1279 | } | ||
1280 | sbi->s_qf_names[qtype] = qname; | ||
1281 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
1282 | ext4_msg(sb, KERN_ERR, | ||
1283 | "quotafile must be on filesystem root"); | ||
1284 | kfree(sbi->s_qf_names[qtype]); | ||
1285 | sbi->s_qf_names[qtype] = NULL; | ||
1286 | return 0; | ||
1287 | } | ||
1288 | set_opt(sbi->s_mount_opt, QUOTA); | ||
1289 | return 1; | ||
1290 | } | ||
1291 | |||
1292 | static int clear_qf_name(struct super_block *sb, int qtype) | ||
1293 | { | ||
1294 | |||
1295 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1296 | |||
1297 | if (sb_any_quota_loaded(sb) && | ||
1298 | sbi->s_qf_names[qtype]) { | ||
1299 | ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" | ||
1300 | " when quota turned on"); | ||
1301 | return 0; | ||
1302 | } | ||
1303 | /* | ||
1304 | * The space will be released later when all options are confirmed | ||
1305 | * to be correct | ||
1306 | */ | ||
1307 | sbi->s_qf_names[qtype] = NULL; | ||
1308 | return 1; | ||
1309 | } | ||
1310 | #endif | ||
1208 | 1311 | ||
1209 | static int parse_options(char *options, struct super_block *sb, | 1312 | static int parse_options(char *options, struct super_block *sb, |
1210 | unsigned long *journal_devnum, | 1313 | unsigned long *journal_devnum, |
@@ -1217,8 +1320,7 @@ static int parse_options(char *options, struct super_block *sb, | |||
1217 | int data_opt = 0; | 1320 | int data_opt = 0; |
1218 | int option; | 1321 | int option; |
1219 | #ifdef CONFIG_QUOTA | 1322 | #ifdef CONFIG_QUOTA |
1220 | int qtype, qfmt; | 1323 | int qfmt; |
1221 | char *qname; | ||
1222 | #endif | 1324 | #endif |
1223 | 1325 | ||
1224 | if (!options) | 1326 | if (!options) |
@@ -1229,19 +1331,31 @@ static int parse_options(char *options, struct super_block *sb, | |||
1229 | if (!*p) | 1331 | if (!*p) |
1230 | continue; | 1332 | continue; |
1231 | 1333 | ||
1334 | /* | ||
1335 | * Initialize args struct so we know whether arg was | ||
1336 | * found; some options take optional arguments. | ||
1337 | */ | ||
1338 | args[0].to = args[0].from = 0; | ||
1232 | token = match_token(p, tokens, args); | 1339 | token = match_token(p, tokens, args); |
1233 | switch (token) { | 1340 | switch (token) { |
1234 | case Opt_bsd_df: | 1341 | case Opt_bsd_df: |
1342 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1235 | clear_opt(sbi->s_mount_opt, MINIX_DF); | 1343 | clear_opt(sbi->s_mount_opt, MINIX_DF); |
1236 | break; | 1344 | break; |
1237 | case Opt_minix_df: | 1345 | case Opt_minix_df: |
1346 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1238 | set_opt(sbi->s_mount_opt, MINIX_DF); | 1347 | set_opt(sbi->s_mount_opt, MINIX_DF); |
1348 | |||
1239 | break; | 1349 | break; |
1240 | case Opt_grpid: | 1350 | case Opt_grpid: |
1351 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1241 | set_opt(sbi->s_mount_opt, GRPID); | 1352 | set_opt(sbi->s_mount_opt, GRPID); |
1353 | |||
1242 | break; | 1354 | break; |
1243 | case Opt_nogrpid: | 1355 | case Opt_nogrpid: |
1356 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1244 | clear_opt(sbi->s_mount_opt, GRPID); | 1357 | clear_opt(sbi->s_mount_opt, GRPID); |
1358 | |||
1245 | break; | 1359 | break; |
1246 | case Opt_resuid: | 1360 | case Opt_resuid: |
1247 | if (match_int(&args[0], &option)) | 1361 | if (match_int(&args[0], &option)) |
@@ -1378,14 +1492,13 @@ static int parse_options(char *options, struct super_block *sb, | |||
1378 | data_opt = EXT4_MOUNT_WRITEBACK_DATA; | 1492 | data_opt = EXT4_MOUNT_WRITEBACK_DATA; |
1379 | datacheck: | 1493 | datacheck: |
1380 | if (is_remount) { | 1494 | if (is_remount) { |
1381 | if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS) | 1495 | if (test_opt(sb, DATA_FLAGS) != data_opt) { |
1382 | != data_opt) { | ||
1383 | ext4_msg(sb, KERN_ERR, | 1496 | ext4_msg(sb, KERN_ERR, |
1384 | "Cannot change data mode on remount"); | 1497 | "Cannot change data mode on remount"); |
1385 | return 0; | 1498 | return 0; |
1386 | } | 1499 | } |
1387 | } else { | 1500 | } else { |
1388 | sbi->s_mount_opt &= ~EXT4_MOUNT_DATA_FLAGS; | 1501 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); |
1389 | sbi->s_mount_opt |= data_opt; | 1502 | sbi->s_mount_opt |= data_opt; |
1390 | } | 1503 | } |
1391 | break; | 1504 | break; |
@@ -1397,63 +1510,22 @@ static int parse_options(char *options, struct super_block *sb, | |||
1397 | break; | 1510 | break; |
1398 | #ifdef CONFIG_QUOTA | 1511 | #ifdef CONFIG_QUOTA |
1399 | case Opt_usrjquota: | 1512 | case Opt_usrjquota: |
1400 | qtype = USRQUOTA; | 1513 | if (!set_qf_name(sb, USRQUOTA, &args[0])) |
1401 | goto set_qf_name; | ||
1402 | case Opt_grpjquota: | ||
1403 | qtype = GRPQUOTA; | ||
1404 | set_qf_name: | ||
1405 | if (sb_any_quota_loaded(sb) && | ||
1406 | !sbi->s_qf_names[qtype]) { | ||
1407 | ext4_msg(sb, KERN_ERR, | ||
1408 | "Cannot change journaled " | ||
1409 | "quota options when quota turned on"); | ||
1410 | return 0; | 1514 | return 0; |
1411 | } | 1515 | break; |
1412 | qname = match_strdup(&args[0]); | 1516 | case Opt_grpjquota: |
1413 | if (!qname) { | 1517 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) |
1414 | ext4_msg(sb, KERN_ERR, | ||
1415 | "Not enough memory for " | ||
1416 | "storing quotafile name"); | ||
1417 | return 0; | ||
1418 | } | ||
1419 | if (sbi->s_qf_names[qtype] && | ||
1420 | strcmp(sbi->s_qf_names[qtype], qname)) { | ||
1421 | ext4_msg(sb, KERN_ERR, | ||
1422 | "%s quota file already " | ||
1423 | "specified", QTYPE2NAME(qtype)); | ||
1424 | kfree(qname); | ||
1425 | return 0; | ||
1426 | } | ||
1427 | sbi->s_qf_names[qtype] = qname; | ||
1428 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
1429 | ext4_msg(sb, KERN_ERR, | ||
1430 | "quotafile must be on " | ||
1431 | "filesystem root"); | ||
1432 | kfree(sbi->s_qf_names[qtype]); | ||
1433 | sbi->s_qf_names[qtype] = NULL; | ||
1434 | return 0; | 1518 | return 0; |
1435 | } | ||
1436 | set_opt(sbi->s_mount_opt, QUOTA); | ||
1437 | break; | 1519 | break; |
1438 | case Opt_offusrjquota: | 1520 | case Opt_offusrjquota: |
1439 | qtype = USRQUOTA; | 1521 | if (!clear_qf_name(sb, USRQUOTA)) |
1440 | goto clear_qf_name; | 1522 | return 0; |
1523 | break; | ||
1441 | case Opt_offgrpjquota: | 1524 | case Opt_offgrpjquota: |
1442 | qtype = GRPQUOTA; | 1525 | if (!clear_qf_name(sb, GRPQUOTA)) |
1443 | clear_qf_name: | ||
1444 | if (sb_any_quota_loaded(sb) && | ||
1445 | sbi->s_qf_names[qtype]) { | ||
1446 | ext4_msg(sb, KERN_ERR, "Cannot change " | ||
1447 | "journaled quota options when " | ||
1448 | "quota turned on"); | ||
1449 | return 0; | 1526 | return 0; |
1450 | } | ||
1451 | /* | ||
1452 | * The space will be released later when all options | ||
1453 | * are confirmed to be correct | ||
1454 | */ | ||
1455 | sbi->s_qf_names[qtype] = NULL; | ||
1456 | break; | 1527 | break; |
1528 | |||
1457 | case Opt_jqfmt_vfsold: | 1529 | case Opt_jqfmt_vfsold: |
1458 | qfmt = QFMT_VFS_OLD; | 1530 | qfmt = QFMT_VFS_OLD; |
1459 | goto set_qf_format; | 1531 | goto set_qf_format; |
@@ -1518,10 +1590,11 @@ set_qf_format: | |||
1518 | clear_opt(sbi->s_mount_opt, BARRIER); | 1590 | clear_opt(sbi->s_mount_opt, BARRIER); |
1519 | break; | 1591 | break; |
1520 | case Opt_barrier: | 1592 | case Opt_barrier: |
1521 | if (match_int(&args[0], &option)) { | 1593 | if (args[0].from) { |
1522 | set_opt(sbi->s_mount_opt, BARRIER); | 1594 | if (match_int(&args[0], &option)) |
1523 | break; | 1595 | return 0; |
1524 | } | 1596 | } else |
1597 | option = 1; /* No argument, default to 1 */ | ||
1525 | if (option) | 1598 | if (option) |
1526 | set_opt(sbi->s_mount_opt, BARRIER); | 1599 | set_opt(sbi->s_mount_opt, BARRIER); |
1527 | else | 1600 | else |
@@ -1594,10 +1667,11 @@ set_qf_format: | |||
1594 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); | 1667 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); |
1595 | break; | 1668 | break; |
1596 | case Opt_auto_da_alloc: | 1669 | case Opt_auto_da_alloc: |
1597 | if (match_int(&args[0], &option)) { | 1670 | if (args[0].from) { |
1598 | clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); | 1671 | if (match_int(&args[0], &option)) |
1599 | break; | 1672 | return 0; |
1600 | } | 1673 | } else |
1674 | option = 1; /* No argument, default to 1 */ | ||
1601 | if (option) | 1675 | if (option) |
1602 | clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); | 1676 | clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); |
1603 | else | 1677 | else |
@@ -1609,6 +1683,12 @@ set_qf_format: | |||
1609 | case Opt_nodiscard: | 1683 | case Opt_nodiscard: |
1610 | clear_opt(sbi->s_mount_opt, DISCARD); | 1684 | clear_opt(sbi->s_mount_opt, DISCARD); |
1611 | break; | 1685 | break; |
1686 | case Opt_dioread_nolock: | ||
1687 | set_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
1688 | break; | ||
1689 | case Opt_dioread_lock: | ||
1690 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
1691 | break; | ||
1612 | default: | 1692 | default: |
1613 | ext4_msg(sb, KERN_ERR, | 1693 | ext4_msg(sb, KERN_ERR, |
1614 | "Unrecognized mount option \"%s\" " | 1694 | "Unrecognized mount option \"%s\" " |
@@ -1618,18 +1698,13 @@ set_qf_format: | |||
1618 | } | 1698 | } |
1619 | #ifdef CONFIG_QUOTA | 1699 | #ifdef CONFIG_QUOTA |
1620 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { | 1700 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { |
1621 | if ((sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) && | 1701 | if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) |
1622 | sbi->s_qf_names[USRQUOTA]) | ||
1623 | clear_opt(sbi->s_mount_opt, USRQUOTA); | 1702 | clear_opt(sbi->s_mount_opt, USRQUOTA); |
1624 | 1703 | ||
1625 | if ((sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) && | 1704 | if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) |
1626 | sbi->s_qf_names[GRPQUOTA]) | ||
1627 | clear_opt(sbi->s_mount_opt, GRPQUOTA); | 1705 | clear_opt(sbi->s_mount_opt, GRPQUOTA); |
1628 | 1706 | ||
1629 | if ((sbi->s_qf_names[USRQUOTA] && | 1707 | if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) { |
1630 | (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) || | ||
1631 | (sbi->s_qf_names[GRPQUOTA] && | ||
1632 | (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) { | ||
1633 | ext4_msg(sb, KERN_ERR, "old and new quota " | 1708 | ext4_msg(sb, KERN_ERR, "old and new quota " |
1634 | "format mixing"); | 1709 | "format mixing"); |
1635 | return 0; | 1710 | return 0; |
@@ -2432,8 +2507,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2432 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); | 2507 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); |
2433 | if (def_mount_opts & EXT4_DEFM_DEBUG) | 2508 | if (def_mount_opts & EXT4_DEFM_DEBUG) |
2434 | set_opt(sbi->s_mount_opt, DEBUG); | 2509 | set_opt(sbi->s_mount_opt, DEBUG); |
2435 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) | 2510 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) { |
2511 | ext4_msg(sb, KERN_WARNING, deprecated_msg, "bsdgroups", | ||
2512 | "2.6.38"); | ||
2436 | set_opt(sbi->s_mount_opt, GRPID); | 2513 | set_opt(sbi->s_mount_opt, GRPID); |
2514 | } | ||
2437 | if (def_mount_opts & EXT4_DEFM_UID16) | 2515 | if (def_mount_opts & EXT4_DEFM_UID16) |
2438 | set_opt(sbi->s_mount_opt, NO_UID32); | 2516 | set_opt(sbi->s_mount_opt, NO_UID32); |
2439 | #ifdef CONFIG_EXT4_FS_XATTR | 2517 | #ifdef CONFIG_EXT4_FS_XATTR |
@@ -2445,11 +2523,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2445 | set_opt(sbi->s_mount_opt, POSIX_ACL); | 2523 | set_opt(sbi->s_mount_opt, POSIX_ACL); |
2446 | #endif | 2524 | #endif |
2447 | if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA) | 2525 | if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA) |
2448 | sbi->s_mount_opt |= EXT4_MOUNT_JOURNAL_DATA; | 2526 | set_opt(sbi->s_mount_opt, JOURNAL_DATA); |
2449 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED) | 2527 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED) |
2450 | sbi->s_mount_opt |= EXT4_MOUNT_ORDERED_DATA; | 2528 | set_opt(sbi->s_mount_opt, ORDERED_DATA); |
2451 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK) | 2529 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK) |
2452 | sbi->s_mount_opt |= EXT4_MOUNT_WRITEBACK_DATA; | 2530 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); |
2453 | 2531 | ||
2454 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) | 2532 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) |
2455 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); | 2533 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); |
@@ -2477,7 +2555,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2477 | goto failed_mount; | 2555 | goto failed_mount; |
2478 | 2556 | ||
2479 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 2557 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
2480 | ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 2558 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
2481 | 2559 | ||
2482 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && | 2560 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && |
2483 | (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || | 2561 | (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || |
@@ -2766,7 +2844,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2766 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { | 2844 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { |
2767 | ext4_msg(sb, KERN_ERR, "required journal recovery " | 2845 | ext4_msg(sb, KERN_ERR, "required journal recovery " |
2768 | "suppressed and not mounted read-only"); | 2846 | "suppressed and not mounted read-only"); |
2769 | goto failed_mount4; | 2847 | goto failed_mount_wq; |
2770 | } else { | 2848 | } else { |
2771 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); | 2849 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); |
2772 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); | 2850 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); |
@@ -2779,7 +2857,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2779 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, | 2857 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, |
2780 | JBD2_FEATURE_INCOMPAT_64BIT)) { | 2858 | JBD2_FEATURE_INCOMPAT_64BIT)) { |
2781 | ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature"); | 2859 | ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature"); |
2782 | goto failed_mount4; | 2860 | goto failed_mount_wq; |
2783 | } | 2861 | } |
2784 | 2862 | ||
2785 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { | 2863 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { |
@@ -2818,7 +2896,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2818 | (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) { | 2896 | (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) { |
2819 | ext4_msg(sb, KERN_ERR, "Journal does not support " | 2897 | ext4_msg(sb, KERN_ERR, "Journal does not support " |
2820 | "requested data journaling mode"); | 2898 | "requested data journaling mode"); |
2821 | goto failed_mount4; | 2899 | goto failed_mount_wq; |
2822 | } | 2900 | } |
2823 | default: | 2901 | default: |
2824 | break; | 2902 | break; |
@@ -2826,13 +2904,17 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2826 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | 2904 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); |
2827 | 2905 | ||
2828 | no_journal: | 2906 | no_journal: |
2829 | |||
2830 | if (test_opt(sb, NOBH)) { | 2907 | if (test_opt(sb, NOBH)) { |
2831 | if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { | 2908 | if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { |
2832 | ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " | 2909 | ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " |
2833 | "its supported only with writeback mode"); | 2910 | "its supported only with writeback mode"); |
2834 | clear_opt(sbi->s_mount_opt, NOBH); | 2911 | clear_opt(sbi->s_mount_opt, NOBH); |
2835 | } | 2912 | } |
2913 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
2914 | ext4_msg(sb, KERN_WARNING, "dioread_nolock option is " | ||
2915 | "not supported with nobh mode"); | ||
2916 | goto failed_mount_wq; | ||
2917 | } | ||
2836 | } | 2918 | } |
2837 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); | 2919 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); |
2838 | if (!EXT4_SB(sb)->dio_unwritten_wq) { | 2920 | if (!EXT4_SB(sb)->dio_unwritten_wq) { |
@@ -2897,6 +2979,18 @@ no_journal: | |||
2897 | "requested data journaling mode"); | 2979 | "requested data journaling mode"); |
2898 | clear_opt(sbi->s_mount_opt, DELALLOC); | 2980 | clear_opt(sbi->s_mount_opt, DELALLOC); |
2899 | } | 2981 | } |
2982 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
2983 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | ||
2984 | ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock " | ||
2985 | "option - requested data journaling mode"); | ||
2986 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
2987 | } | ||
2988 | if (sb->s_blocksize < PAGE_SIZE) { | ||
2989 | ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock " | ||
2990 | "option - block size is too small"); | ||
2991 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
2992 | } | ||
2993 | } | ||
2900 | 2994 | ||
2901 | err = ext4_setup_system_zone(sb); | 2995 | err = ext4_setup_system_zone(sb); |
2902 | if (err) { | 2996 | if (err) { |
@@ -3360,10 +3454,9 @@ static void ext4_clear_journal_err(struct super_block *sb, | |||
3360 | char nbuf[16]; | 3454 | char nbuf[16]; |
3361 | 3455 | ||
3362 | errstr = ext4_decode_error(sb, j_errno, nbuf); | 3456 | errstr = ext4_decode_error(sb, j_errno, nbuf); |
3363 | ext4_warning(sb, __func__, "Filesystem error recorded " | 3457 | ext4_warning(sb, "Filesystem error recorded " |
3364 | "from previous mount: %s", errstr); | 3458 | "from previous mount: %s", errstr); |
3365 | ext4_warning(sb, __func__, "Marking fs in need of " | 3459 | ext4_warning(sb, "Marking fs in need of filesystem check."); |
3366 | "filesystem check."); | ||
3367 | 3460 | ||
3368 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | 3461 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; |
3369 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | 3462 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); |
@@ -3514,7 +3607,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3514 | ext4_abort(sb, __func__, "Abort forced by user"); | 3607 | ext4_abort(sb, __func__, "Abort forced by user"); |
3515 | 3608 | ||
3516 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 3609 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
3517 | ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 3610 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
3518 | 3611 | ||
3519 | es = sbi->s_es; | 3612 | es = sbi->s_es; |
3520 | 3613 | ||
@@ -3917,9 +4010,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3917 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); | 4010 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); |
3918 | int err = 0; | 4011 | int err = 0; |
3919 | int offset = off & (sb->s_blocksize - 1); | 4012 | int offset = off & (sb->s_blocksize - 1); |
3920 | int tocopy; | ||
3921 | int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL; | 4013 | int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL; |
3922 | size_t towrite = len; | ||
3923 | struct buffer_head *bh; | 4014 | struct buffer_head *bh; |
3924 | handle_t *handle = journal_current_handle(); | 4015 | handle_t *handle = journal_current_handle(); |
3925 | 4016 | ||
@@ -3929,52 +4020,53 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3929 | (unsigned long long)off, (unsigned long long)len); | 4020 | (unsigned long long)off, (unsigned long long)len); |
3930 | return -EIO; | 4021 | return -EIO; |
3931 | } | 4022 | } |
4023 | /* | ||
4024 | * Since we account only one data block in transaction credits, | ||
4025 | * then it is impossible to cross a block boundary. | ||
4026 | */ | ||
4027 | if (sb->s_blocksize - offset < len) { | ||
4028 | ext4_msg(sb, KERN_WARNING, "Quota write (off=%llu, len=%llu)" | ||
4029 | " cancelled because not block aligned", | ||
4030 | (unsigned long long)off, (unsigned long long)len); | ||
4031 | return -EIO; | ||
4032 | } | ||
4033 | |||
3932 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); | 4034 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); |
3933 | while (towrite > 0) { | 4035 | bh = ext4_bread(handle, inode, blk, 1, &err); |
3934 | tocopy = sb->s_blocksize - offset < towrite ? | 4036 | if (!bh) |
3935 | sb->s_blocksize - offset : towrite; | 4037 | goto out; |
3936 | bh = ext4_bread(handle, inode, blk, 1, &err); | 4038 | if (journal_quota) { |
3937 | if (!bh) | 4039 | err = ext4_journal_get_write_access(handle, bh); |
4040 | if (err) { | ||
4041 | brelse(bh); | ||
3938 | goto out; | 4042 | goto out; |
3939 | if (journal_quota) { | ||
3940 | err = ext4_journal_get_write_access(handle, bh); | ||
3941 | if (err) { | ||
3942 | brelse(bh); | ||
3943 | goto out; | ||
3944 | } | ||
3945 | } | 4043 | } |
3946 | lock_buffer(bh); | ||
3947 | memcpy(bh->b_data+offset, data, tocopy); | ||
3948 | flush_dcache_page(bh->b_page); | ||
3949 | unlock_buffer(bh); | ||
3950 | if (journal_quota) | ||
3951 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | ||
3952 | else { | ||
3953 | /* Always do at least ordered writes for quotas */ | ||
3954 | err = ext4_jbd2_file_inode(handle, inode); | ||
3955 | mark_buffer_dirty(bh); | ||
3956 | } | ||
3957 | brelse(bh); | ||
3958 | if (err) | ||
3959 | goto out; | ||
3960 | offset = 0; | ||
3961 | towrite -= tocopy; | ||
3962 | data += tocopy; | ||
3963 | blk++; | ||
3964 | } | 4044 | } |
4045 | lock_buffer(bh); | ||
4046 | memcpy(bh->b_data+offset, data, len); | ||
4047 | flush_dcache_page(bh->b_page); | ||
4048 | unlock_buffer(bh); | ||
4049 | if (journal_quota) | ||
4050 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | ||
4051 | else { | ||
4052 | /* Always do at least ordered writes for quotas */ | ||
4053 | err = ext4_jbd2_file_inode(handle, inode); | ||
4054 | mark_buffer_dirty(bh); | ||
4055 | } | ||
4056 | brelse(bh); | ||
3965 | out: | 4057 | out: |
3966 | if (len == towrite) { | 4058 | if (err) { |
3967 | mutex_unlock(&inode->i_mutex); | 4059 | mutex_unlock(&inode->i_mutex); |
3968 | return err; | 4060 | return err; |
3969 | } | 4061 | } |
3970 | if (inode->i_size < off+len-towrite) { | 4062 | if (inode->i_size < off + len) { |
3971 | i_size_write(inode, off+len-towrite); | 4063 | i_size_write(inode, off + len); |
3972 | EXT4_I(inode)->i_disksize = inode->i_size; | 4064 | EXT4_I(inode)->i_disksize = inode->i_size; |
3973 | } | 4065 | } |
3974 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 4066 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
3975 | ext4_mark_inode_dirty(handle, inode); | 4067 | ext4_mark_inode_dirty(handle, inode); |
3976 | mutex_unlock(&inode->i_mutex); | 4068 | mutex_unlock(&inode->i_mutex); |
3977 | return len - towrite; | 4069 | return len; |
3978 | } | 4070 | } |
3979 | 4071 | ||
3980 | #endif | 4072 | #endif |