diff options
-rw-r--r-- | fs/ext4/ext4.h | 18 | ||||
-rw-r--r-- | fs/ext4/indirect.c | 105 | ||||
-rw-r--r-- | fs/ext4/inode.c | 7 | ||||
-rw-r--r-- | fs/ext4/super.c | 31 | ||||
-rw-r--r-- | fs/jbd2/recovery.c | 3 |
5 files changed, 108 insertions, 56 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 982d934fd9ac..f63c3d5805c4 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -364,7 +364,8 @@ struct flex_groups { | |||
364 | #define EXT4_DIRTY_FL 0x00000100 | 364 | #define EXT4_DIRTY_FL 0x00000100 |
365 | #define EXT4_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ | 365 | #define EXT4_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ |
366 | #define EXT4_NOCOMPR_FL 0x00000400 /* Don't compress */ | 366 | #define EXT4_NOCOMPR_FL 0x00000400 /* Don't compress */ |
367 | #define EXT4_ECOMPR_FL 0x00000800 /* Compression error */ | 367 | /* nb: was previously EXT2_ECOMPR_FL */ |
368 | #define EXT4_ENCRYPT_FL 0x00000800 /* encrypted file */ | ||
368 | /* End compression flags --- maybe not all used */ | 369 | /* End compression flags --- maybe not all used */ |
369 | #define EXT4_INDEX_FL 0x00001000 /* hash-indexed directory */ | 370 | #define EXT4_INDEX_FL 0x00001000 /* hash-indexed directory */ |
370 | #define EXT4_IMAGIC_FL 0x00002000 /* AFS directory */ | 371 | #define EXT4_IMAGIC_FL 0x00002000 /* AFS directory */ |
@@ -421,7 +422,7 @@ enum { | |||
421 | EXT4_INODE_DIRTY = 8, | 422 | EXT4_INODE_DIRTY = 8, |
422 | EXT4_INODE_COMPRBLK = 9, /* One or more compressed clusters */ | 423 | EXT4_INODE_COMPRBLK = 9, /* One or more compressed clusters */ |
423 | EXT4_INODE_NOCOMPR = 10, /* Don't compress */ | 424 | EXT4_INODE_NOCOMPR = 10, /* Don't compress */ |
424 | EXT4_INODE_ECOMPR = 11, /* Compression error */ | 425 | EXT4_INODE_ENCRYPT = 11, /* Compression error */ |
425 | /* End compression flags --- maybe not all used */ | 426 | /* End compression flags --- maybe not all used */ |
426 | EXT4_INODE_INDEX = 12, /* hash-indexed directory */ | 427 | EXT4_INODE_INDEX = 12, /* hash-indexed directory */ |
427 | EXT4_INODE_IMAGIC = 13, /* AFS directory */ | 428 | EXT4_INODE_IMAGIC = 13, /* AFS directory */ |
@@ -466,7 +467,7 @@ static inline void ext4_check_flag_values(void) | |||
466 | CHECK_FLAG_VALUE(DIRTY); | 467 | CHECK_FLAG_VALUE(DIRTY); |
467 | CHECK_FLAG_VALUE(COMPRBLK); | 468 | CHECK_FLAG_VALUE(COMPRBLK); |
468 | CHECK_FLAG_VALUE(NOCOMPR); | 469 | CHECK_FLAG_VALUE(NOCOMPR); |
469 | CHECK_FLAG_VALUE(ECOMPR); | 470 | CHECK_FLAG_VALUE(ENCRYPT); |
470 | CHECK_FLAG_VALUE(INDEX); | 471 | CHECK_FLAG_VALUE(INDEX); |
471 | CHECK_FLAG_VALUE(IMAGIC); | 472 | CHECK_FLAG_VALUE(IMAGIC); |
472 | CHECK_FLAG_VALUE(JOURNAL_DATA); | 473 | CHECK_FLAG_VALUE(JOURNAL_DATA); |
@@ -1048,6 +1049,12 @@ extern void ext4_set_bits(void *bm, int cur, int len); | |||
1048 | /* Metadata checksum algorithm codes */ | 1049 | /* Metadata checksum algorithm codes */ |
1049 | #define EXT4_CRC32C_CHKSUM 1 | 1050 | #define EXT4_CRC32C_CHKSUM 1 |
1050 | 1051 | ||
1052 | /* Encryption algorithms */ | ||
1053 | #define EXT4_ENCRYPTION_MODE_INVALID 0 | ||
1054 | #define EXT4_ENCRYPTION_MODE_AES_256_XTS 1 | ||
1055 | #define EXT4_ENCRYPTION_MODE_AES_256_GCM 2 | ||
1056 | #define EXT4_ENCRYPTION_MODE_AES_256_CBC 3 | ||
1057 | |||
1051 | /* | 1058 | /* |
1052 | * Structure of the super block | 1059 | * Structure of the super block |
1053 | */ | 1060 | */ |
@@ -1161,7 +1168,8 @@ struct ext4_super_block { | |||
1161 | __le32 s_grp_quota_inum; /* inode for tracking group quota */ | 1168 | __le32 s_grp_quota_inum; /* inode for tracking group quota */ |
1162 | __le32 s_overhead_clusters; /* overhead blocks/clusters in fs */ | 1169 | __le32 s_overhead_clusters; /* overhead blocks/clusters in fs */ |
1163 | __le32 s_backup_bgs[2]; /* groups with sparse_super2 SBs */ | 1170 | __le32 s_backup_bgs[2]; /* groups with sparse_super2 SBs */ |
1164 | __le32 s_reserved[106]; /* Padding to the end of the block */ | 1171 | __u8 s_encrypt_algos[4]; /* Encryption algorithms in use */ |
1172 | __le32 s_reserved[105]; /* Padding to the end of the block */ | ||
1165 | __le32 s_checksum; /* crc32c(superblock) */ | 1173 | __le32 s_checksum; /* crc32c(superblock) */ |
1166 | }; | 1174 | }; |
1167 | 1175 | ||
@@ -1527,6 +1535,7 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei) | |||
1527 | * GDT_CSUM bits are mutually exclusive. | 1535 | * GDT_CSUM bits are mutually exclusive. |
1528 | */ | 1536 | */ |
1529 | #define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400 | 1537 | #define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400 |
1538 | #define EXT4_FEATURE_RO_COMPAT_READONLY 0x1000 | ||
1530 | 1539 | ||
1531 | #define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001 | 1540 | #define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001 |
1532 | #define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002 | 1541 | #define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002 |
@@ -1542,6 +1551,7 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei) | |||
1542 | #define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */ | 1551 | #define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */ |
1543 | #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ | 1552 | #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ |
1544 | #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ | 1553 | #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ |
1554 | #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 | ||
1545 | 1555 | ||
1546 | #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR | 1556 | #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR |
1547 | #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ | 1557 | #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ |
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index 6b9878a24182..45fe924f82bc 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c | |||
@@ -1401,10 +1401,7 @@ end_range: | |||
1401 | * to free. Everything was covered by the start | 1401 | * to free. Everything was covered by the start |
1402 | * of the range. | 1402 | * of the range. |
1403 | */ | 1403 | */ |
1404 | return 0; | 1404 | goto do_indirects; |
1405 | } else { | ||
1406 | /* Shared branch grows from an indirect block */ | ||
1407 | partial2--; | ||
1408 | } | 1405 | } |
1409 | } else { | 1406 | } else { |
1410 | /* | 1407 | /* |
@@ -1435,56 +1432,96 @@ end_range: | |||
1435 | /* Punch happened within the same level (n == n2) */ | 1432 | /* Punch happened within the same level (n == n2) */ |
1436 | partial = ext4_find_shared(inode, n, offsets, chain, &nr); | 1433 | partial = ext4_find_shared(inode, n, offsets, chain, &nr); |
1437 | partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2); | 1434 | partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2); |
1438 | /* | 1435 | |
1439 | * ext4_find_shared returns Indirect structure which | 1436 | /* Free top, but only if partial2 isn't its subtree. */ |
1440 | * points to the last element which should not be | 1437 | if (nr) { |
1441 | * removed by truncate. But this is end of the range | 1438 | int level = min(partial - chain, partial2 - chain2); |
1442 | * in punch_hole so we need to point to the next element | 1439 | int i; |
1443 | */ | 1440 | int subtree = 1; |
1444 | partial2->p++; | 1441 | |
1445 | while ((partial > chain) || (partial2 > chain2)) { | 1442 | for (i = 0; i <= level; i++) { |
1446 | /* We're at the same block, so we're almost finished */ | 1443 | if (offsets[i] != offsets2[i]) { |
1447 | if ((partial->bh && partial2->bh) && | 1444 | subtree = 0; |
1448 | (partial->bh->b_blocknr == partial2->bh->b_blocknr)) { | 1445 | break; |
1449 | if ((partial > chain) && (partial2 > chain2)) { | 1446 | } |
1447 | } | ||
1448 | |||
1449 | if (!subtree) { | ||
1450 | if (partial == chain) { | ||
1451 | /* Shared branch grows from the inode */ | ||
1452 | ext4_free_branches(handle, inode, NULL, | ||
1453 | &nr, &nr+1, | ||
1454 | (chain+n-1) - partial); | ||
1455 | *partial->p = 0; | ||
1456 | } else { | ||
1457 | /* Shared branch grows from an indirect block */ | ||
1458 | BUFFER_TRACE(partial->bh, "get_write_access"); | ||
1450 | ext4_free_branches(handle, inode, partial->bh, | 1459 | ext4_free_branches(handle, inode, partial->bh, |
1451 | partial->p + 1, | 1460 | partial->p, |
1452 | partial2->p, | 1461 | partial->p+1, |
1453 | (chain+n-1) - partial); | 1462 | (chain+n-1) - partial); |
1454 | BUFFER_TRACE(partial->bh, "call brelse"); | ||
1455 | brelse(partial->bh); | ||
1456 | BUFFER_TRACE(partial2->bh, "call brelse"); | ||
1457 | brelse(partial2->bh); | ||
1458 | } | 1463 | } |
1459 | return 0; | ||
1460 | } | 1464 | } |
1465 | } | ||
1466 | |||
1467 | if (!nr2) { | ||
1461 | /* | 1468 | /* |
1462 | * Clear the ends of indirect blocks on the shared branch | 1469 | * ext4_find_shared returns Indirect structure which |
1463 | * at the start of the range | 1470 | * points to the last element which should not be |
1471 | * removed by truncate. But this is end of the range | ||
1472 | * in punch_hole so we need to point to the next element | ||
1464 | */ | 1473 | */ |
1465 | if (partial > chain) { | 1474 | partial2->p++; |
1475 | } | ||
1476 | |||
1477 | while (partial > chain || partial2 > chain2) { | ||
1478 | int depth = (chain+n-1) - partial; | ||
1479 | int depth2 = (chain2+n2-1) - partial2; | ||
1480 | |||
1481 | if (partial > chain && partial2 > chain2 && | ||
1482 | partial->bh->b_blocknr == partial2->bh->b_blocknr) { | ||
1483 | /* | ||
1484 | * We've converged on the same block. Clear the range, | ||
1485 | * then we're done. | ||
1486 | */ | ||
1466 | ext4_free_branches(handle, inode, partial->bh, | 1487 | ext4_free_branches(handle, inode, partial->bh, |
1467 | partial->p + 1, | 1488 | partial->p + 1, |
1468 | (__le32 *)partial->bh->b_data+addr_per_block, | 1489 | partial2->p, |
1469 | (chain+n-1) - partial); | 1490 | (chain+n-1) - partial); |
1470 | BUFFER_TRACE(partial->bh, "call brelse"); | 1491 | BUFFER_TRACE(partial->bh, "call brelse"); |
1471 | brelse(partial->bh); | 1492 | brelse(partial->bh); |
1472 | partial--; | 1493 | BUFFER_TRACE(partial2->bh, "call brelse"); |
1494 | brelse(partial2->bh); | ||
1495 | return 0; | ||
1473 | } | 1496 | } |
1497 | |||
1474 | /* | 1498 | /* |
1475 | * Clear the ends of indirect blocks on the shared branch | 1499 | * The start and end partial branches may not be at the same |
1476 | * at the end of the range | 1500 | * level even though the punch happened within one level. So, we |
1501 | * give them a chance to arrive at the same level, then walk | ||
1502 | * them in step with each other until we converge on the same | ||
1503 | * block. | ||
1477 | */ | 1504 | */ |
1478 | if (partial2 > chain2) { | 1505 | if (partial > chain && depth <= depth2) { |
1506 | ext4_free_branches(handle, inode, partial->bh, | ||
1507 | partial->p + 1, | ||
1508 | (__le32 *)partial->bh->b_data+addr_per_block, | ||
1509 | (chain+n-1) - partial); | ||
1510 | BUFFER_TRACE(partial->bh, "call brelse"); | ||
1511 | brelse(partial->bh); | ||
1512 | partial--; | ||
1513 | } | ||
1514 | if (partial2 > chain2 && depth2 <= depth) { | ||
1479 | ext4_free_branches(handle, inode, partial2->bh, | 1515 | ext4_free_branches(handle, inode, partial2->bh, |
1480 | (__le32 *)partial2->bh->b_data, | 1516 | (__le32 *)partial2->bh->b_data, |
1481 | partial2->p, | 1517 | partial2->p, |
1482 | (chain2+n-1) - partial2); | 1518 | (chain2+n2-1) - partial2); |
1483 | BUFFER_TRACE(partial2->bh, "call brelse"); | 1519 | BUFFER_TRACE(partial2->bh, "call brelse"); |
1484 | brelse(partial2->bh); | 1520 | brelse(partial2->bh); |
1485 | partial2--; | 1521 | partial2--; |
1486 | } | 1522 | } |
1487 | } | 1523 | } |
1524 | return 0; | ||
1488 | 1525 | ||
1489 | do_indirects: | 1526 | do_indirects: |
1490 | /* Kill the remaining (whole) subtrees */ | 1527 | /* Kill the remaining (whole) subtrees */ |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 85404f15e53a..5cb9a212b86f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1024,6 +1024,7 @@ static int ext4_write_end(struct file *file, | |||
1024 | { | 1024 | { |
1025 | handle_t *handle = ext4_journal_current_handle(); | 1025 | handle_t *handle = ext4_journal_current_handle(); |
1026 | struct inode *inode = mapping->host; | 1026 | struct inode *inode = mapping->host; |
1027 | loff_t old_size = inode->i_size; | ||
1027 | int ret = 0, ret2; | 1028 | int ret = 0, ret2; |
1028 | int i_size_changed = 0; | 1029 | int i_size_changed = 0; |
1029 | 1030 | ||
@@ -1054,6 +1055,8 @@ static int ext4_write_end(struct file *file, | |||
1054 | unlock_page(page); | 1055 | unlock_page(page); |
1055 | page_cache_release(page); | 1056 | page_cache_release(page); |
1056 | 1057 | ||
1058 | if (old_size < pos) | ||
1059 | pagecache_isize_extended(inode, old_size, pos); | ||
1057 | /* | 1060 | /* |
1058 | * Don't mark the inode dirty under page lock. First, it unnecessarily | 1061 | * Don't mark the inode dirty under page lock. First, it unnecessarily |
1059 | * makes the holding time of page lock longer. Second, it forces lock | 1062 | * makes the holding time of page lock longer. Second, it forces lock |
@@ -1095,6 +1098,7 @@ static int ext4_journalled_write_end(struct file *file, | |||
1095 | { | 1098 | { |
1096 | handle_t *handle = ext4_journal_current_handle(); | 1099 | handle_t *handle = ext4_journal_current_handle(); |
1097 | struct inode *inode = mapping->host; | 1100 | struct inode *inode = mapping->host; |
1101 | loff_t old_size = inode->i_size; | ||
1098 | int ret = 0, ret2; | 1102 | int ret = 0, ret2; |
1099 | int partial = 0; | 1103 | int partial = 0; |
1100 | unsigned from, to; | 1104 | unsigned from, to; |
@@ -1127,6 +1131,9 @@ static int ext4_journalled_write_end(struct file *file, | |||
1127 | unlock_page(page); | 1131 | unlock_page(page); |
1128 | page_cache_release(page); | 1132 | page_cache_release(page); |
1129 | 1133 | ||
1134 | if (old_size < pos) | ||
1135 | pagecache_isize_extended(inode, old_size, pos); | ||
1136 | |||
1130 | if (size_changed) { | 1137 | if (size_changed) { |
1131 | ret2 = ext4_mark_inode_dirty(handle, inode); | 1138 | ret2 = ext4_mark_inode_dirty(handle, inode); |
1132 | if (!ret) | 1139 | if (!ret) |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1adac6868e6f..e061e66c8280 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -2779,6 +2779,12 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly) | |||
2779 | if (readonly) | 2779 | if (readonly) |
2780 | return 1; | 2780 | return 1; |
2781 | 2781 | ||
2782 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_READONLY)) { | ||
2783 | ext4_msg(sb, KERN_INFO, "filesystem is read-only"); | ||
2784 | sb->s_flags |= MS_RDONLY; | ||
2785 | return 1; | ||
2786 | } | ||
2787 | |||
2782 | /* Check that feature set is OK for a read-write mount */ | 2788 | /* Check that feature set is OK for a read-write mount */ |
2783 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP)) { | 2789 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP)) { |
2784 | ext4_msg(sb, KERN_ERR, "couldn't mount RDWR because of " | 2790 | ext4_msg(sb, KERN_ERR, "couldn't mount RDWR because of " |
@@ -3936,9 +3942,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3936 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 3942 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
3937 | spin_lock_init(&sbi->s_next_gen_lock); | 3943 | spin_lock_init(&sbi->s_next_gen_lock); |
3938 | 3944 | ||
3939 | init_timer(&sbi->s_err_report); | 3945 | setup_timer(&sbi->s_err_report, print_daily_error_info, |
3940 | sbi->s_err_report.function = print_daily_error_info; | 3946 | (unsigned long) sb); |
3941 | sbi->s_err_report.data = (unsigned long) sb; | ||
3942 | 3947 | ||
3943 | /* Register extent status tree shrinker */ | 3948 | /* Register extent status tree shrinker */ |
3944 | if (ext4_es_register_shrinker(sbi)) | 3949 | if (ext4_es_register_shrinker(sbi)) |
@@ -4866,9 +4871,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
4866 | if (sbi->s_journal && sbi->s_journal->j_task->io_context) | 4871 | if (sbi->s_journal && sbi->s_journal->j_task->io_context) |
4867 | journal_ioprio = sbi->s_journal->j_task->io_context->ioprio; | 4872 | journal_ioprio = sbi->s_journal->j_task->io_context->ioprio; |
4868 | 4873 | ||
4869 | /* | ||
4870 | * Allow the "check" option to be passed as a remount option. | ||
4871 | */ | ||
4872 | if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) { | 4874 | if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) { |
4873 | err = -EINVAL; | 4875 | err = -EINVAL; |
4874 | goto restore_opts; | 4876 | goto restore_opts; |
@@ -4877,17 +4879,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
4877 | if ((old_opts.s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) ^ | 4879 | if ((old_opts.s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) ^ |
4878 | test_opt(sb, JOURNAL_CHECKSUM)) { | 4880 | test_opt(sb, JOURNAL_CHECKSUM)) { |
4879 | ext4_msg(sb, KERN_ERR, "changing journal_checksum " | 4881 | ext4_msg(sb, KERN_ERR, "changing journal_checksum " |
4880 | "during remount not supported"); | 4882 | "during remount not supported; ignoring"); |
4881 | err = -EINVAL; | 4883 | sbi->s_mount_opt ^= EXT4_MOUNT_JOURNAL_CHECKSUM; |
4882 | goto restore_opts; | ||
4883 | } | ||
4884 | |||
4885 | if ((old_opts.s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) ^ | ||
4886 | test_opt(sb, JOURNAL_CHECKSUM)) { | ||
4887 | ext4_msg(sb, KERN_ERR, "changing journal_checksum " | ||
4888 | "during remount not supported"); | ||
4889 | err = -EINVAL; | ||
4890 | goto restore_opts; | ||
4891 | } | 4884 | } |
4892 | 4885 | ||
4893 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | 4886 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { |
@@ -4963,7 +4956,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
4963 | ext4_mark_recovery_complete(sb, es); | 4956 | ext4_mark_recovery_complete(sb, es); |
4964 | } else { | 4957 | } else { |
4965 | /* Make sure we can mount this feature set readwrite */ | 4958 | /* Make sure we can mount this feature set readwrite */ |
4966 | if (!ext4_feature_set_ok(sb, 0)) { | 4959 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, |
4960 | EXT4_FEATURE_RO_COMPAT_READONLY) || | ||
4961 | !ext4_feature_set_ok(sb, 0)) { | ||
4967 | err = -EROFS; | 4962 | err = -EROFS; |
4968 | goto restore_opts; | 4963 | goto restore_opts; |
4969 | } | 4964 | } |
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index bcbef08a4d8f..b5128c6e63ad 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c | |||
@@ -524,6 +524,9 @@ static int do_one_pass(journal_t *journal, | |||
524 | if (descr_csum_size > 0 && | 524 | if (descr_csum_size > 0 && |
525 | !jbd2_descr_block_csum_verify(journal, | 525 | !jbd2_descr_block_csum_verify(journal, |
526 | bh->b_data)) { | 526 | bh->b_data)) { |
527 | printk(KERN_ERR "JBD2: Invalid checksum " | ||
528 | "recovering block %lu in log\n", | ||
529 | next_log_block); | ||
527 | err = -EIO; | 530 | err = -EIO; |
528 | brelse(bh); | 531 | brelse(bh); |
529 | goto failed; | 532 | goto failed; |