diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_attr_leaf.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_btree.c | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_format.h | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 19 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 18 |
5 files changed, 42 insertions, 11 deletions
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index f9d7846097e2..444a7704596c 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h | |||
@@ -128,6 +128,7 @@ struct xfs_attr3_leaf_hdr { | |||
128 | __u8 holes; | 128 | __u8 holes; |
129 | __u8 pad1; | 129 | __u8 pad1; |
130 | struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE]; | 130 | struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE]; |
131 | __be32 pad2; /* 64 bit alignment */ | ||
131 | }; | 132 | }; |
132 | 133 | ||
133 | #define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc)) | 134 | #define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc)) |
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 8804b8a3c310..0903960410a2 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c | |||
@@ -2544,7 +2544,17 @@ xfs_btree_new_iroot( | |||
2544 | if (error) | 2544 | if (error) |
2545 | goto error0; | 2545 | goto error0; |
2546 | 2546 | ||
2547 | /* | ||
2548 | * we can't just memcpy() the root in for CRC enabled btree blocks. | ||
2549 | * In that case have to also ensure the blkno remains correct | ||
2550 | */ | ||
2547 | memcpy(cblock, block, xfs_btree_block_len(cur)); | 2551 | memcpy(cblock, block, xfs_btree_block_len(cur)); |
2552 | if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) { | ||
2553 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) | ||
2554 | cblock->bb_u.l.bb_blkno = cpu_to_be64(cbp->b_bn); | ||
2555 | else | ||
2556 | cblock->bb_u.s.bb_blkno = cpu_to_be64(cbp->b_bn); | ||
2557 | } | ||
2548 | 2558 | ||
2549 | be16_add_cpu(&block->bb_level, 1); | 2559 | be16_add_cpu(&block->bb_level, 1); |
2550 | xfs_btree_set_numrecs(block, 1); | 2560 | xfs_btree_set_numrecs(block, 1); |
diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h index 995f1f505a52..7826782b8d78 100644 --- a/fs/xfs/xfs_dir2_format.h +++ b/fs/xfs/xfs_dir2_format.h | |||
@@ -266,6 +266,7 @@ struct xfs_dir3_blk_hdr { | |||
266 | struct xfs_dir3_data_hdr { | 266 | struct xfs_dir3_data_hdr { |
267 | struct xfs_dir3_blk_hdr hdr; | 267 | struct xfs_dir3_blk_hdr hdr; |
268 | xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT]; | 268 | xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT]; |
269 | __be32 pad; /* 64 bit alignment */ | ||
269 | }; | 270 | }; |
270 | 271 | ||
271 | #define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc) | 272 | #define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc) |
@@ -477,7 +478,7 @@ struct xfs_dir3_leaf_hdr { | |||
477 | struct xfs_da3_blkinfo info; /* header for da routines */ | 478 | struct xfs_da3_blkinfo info; /* header for da routines */ |
478 | __be16 count; /* count of entries */ | 479 | __be16 count; /* count of entries */ |
479 | __be16 stale; /* count of stale entries */ | 480 | __be16 stale; /* count of stale entries */ |
480 | __be32 pad; | 481 | __be32 pad; /* 64 bit alignment */ |
481 | }; | 482 | }; |
482 | 483 | ||
483 | struct xfs_dir3_icleaf_hdr { | 484 | struct xfs_dir3_icleaf_hdr { |
@@ -715,7 +716,7 @@ struct xfs_dir3_free_hdr { | |||
715 | __be32 firstdb; /* db of first entry */ | 716 | __be32 firstdb; /* db of first entry */ |
716 | __be32 nvalid; /* count of valid entries */ | 717 | __be32 nvalid; /* count of valid entries */ |
717 | __be32 nused; /* count of used entries */ | 718 | __be32 nused; /* count of used entries */ |
718 | __be32 pad; /* 64 bit alignment. */ | 719 | __be32 pad; /* 64 bit alignment */ |
719 | }; | 720 | }; |
720 | 721 | ||
721 | struct xfs_dir3_free { | 722 | struct xfs_dir3_free { |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 45a85ff84da1..7cf5e4eafe28 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -1845,7 +1845,13 @@ xlog_recover_do_inode_buffer( | |||
1845 | xfs_agino_t *buffer_nextp; | 1845 | xfs_agino_t *buffer_nextp; |
1846 | 1846 | ||
1847 | trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f); | 1847 | trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f); |
1848 | bp->b_ops = &xfs_inode_buf_ops; | 1848 | |
1849 | /* | ||
1850 | * Post recovery validation only works properly on CRC enabled | ||
1851 | * filesystems. | ||
1852 | */ | ||
1853 | if (xfs_sb_version_hascrc(&mp->m_sb)) | ||
1854 | bp->b_ops = &xfs_inode_buf_ops; | ||
1849 | 1855 | ||
1850 | inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog; | 1856 | inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog; |
1851 | for (i = 0; i < inodes_per_buf; i++) { | 1857 | for (i = 0; i < inodes_per_buf; i++) { |
@@ -2205,7 +2211,16 @@ xlog_recover_do_reg_buffer( | |||
2205 | /* Shouldn't be any more regions */ | 2211 | /* Shouldn't be any more regions */ |
2206 | ASSERT(i == item->ri_total); | 2212 | ASSERT(i == item->ri_total); |
2207 | 2213 | ||
2208 | xlog_recovery_validate_buf_type(mp, bp, buf_f); | 2214 | /* |
2215 | * We can only do post recovery validation on items on CRC enabled | ||
2216 | * fielsystems as we need to know when the buffer was written to be able | ||
2217 | * to determine if we should have replayed the item. If we replay old | ||
2218 | * metadata over a newer buffer, then it will enter a temporarily | ||
2219 | * inconsistent state resulting in verification failures. Hence for now | ||
2220 | * just avoid the verification stage for non-crc filesystems | ||
2221 | */ | ||
2222 | if (xfs_sb_version_hascrc(&mp->m_sb)) | ||
2223 | xlog_recovery_validate_buf_type(mp, bp, buf_f); | ||
2209 | } | 2224 | } |
2210 | 2225 | ||
2211 | /* | 2226 | /* |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index f6bfbd734669..e8e310c05097 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -314,7 +314,8 @@ STATIC int | |||
314 | xfs_mount_validate_sb( | 314 | xfs_mount_validate_sb( |
315 | xfs_mount_t *mp, | 315 | xfs_mount_t *mp, |
316 | xfs_sb_t *sbp, | 316 | xfs_sb_t *sbp, |
317 | bool check_inprogress) | 317 | bool check_inprogress, |
318 | bool check_version) | ||
318 | { | 319 | { |
319 | 320 | ||
320 | /* | 321 | /* |
@@ -337,9 +338,10 @@ xfs_mount_validate_sb( | |||
337 | 338 | ||
338 | /* | 339 | /* |
339 | * Version 5 superblock feature mask validation. Reject combinations the | 340 | * Version 5 superblock feature mask validation. Reject combinations the |
340 | * kernel cannot support up front before checking anything else. | 341 | * kernel cannot support up front before checking anything else. For |
342 | * write validation, we don't need to check feature masks. | ||
341 | */ | 343 | */ |
342 | if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { | 344 | if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { |
343 | xfs_alert(mp, | 345 | xfs_alert(mp, |
344 | "Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" | 346 | "Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" |
345 | "Use of these features in this kernel is at your own risk!"); | 347 | "Use of these features in this kernel is at your own risk!"); |
@@ -675,7 +677,8 @@ xfs_sb_to_disk( | |||
675 | 677 | ||
676 | static int | 678 | static int |
677 | xfs_sb_verify( | 679 | xfs_sb_verify( |
678 | struct xfs_buf *bp) | 680 | struct xfs_buf *bp, |
681 | bool check_version) | ||
679 | { | 682 | { |
680 | struct xfs_mount *mp = bp->b_target->bt_mount; | 683 | struct xfs_mount *mp = bp->b_target->bt_mount; |
681 | struct xfs_sb sb; | 684 | struct xfs_sb sb; |
@@ -686,7 +689,8 @@ xfs_sb_verify( | |||
686 | * Only check the in progress field for the primary superblock as | 689 | * Only check the in progress field for the primary superblock as |
687 | * mkfs.xfs doesn't clear it from secondary superblocks. | 690 | * mkfs.xfs doesn't clear it from secondary superblocks. |
688 | */ | 691 | */ |
689 | return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR); | 692 | return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR, |
693 | check_version); | ||
690 | } | 694 | } |
691 | 695 | ||
692 | /* | 696 | /* |
@@ -719,7 +723,7 @@ xfs_sb_read_verify( | |||
719 | goto out_error; | 723 | goto out_error; |
720 | } | 724 | } |
721 | } | 725 | } |
722 | error = xfs_sb_verify(bp); | 726 | error = xfs_sb_verify(bp, true); |
723 | 727 | ||
724 | out_error: | 728 | out_error: |
725 | if (error) { | 729 | if (error) { |
@@ -758,7 +762,7 @@ xfs_sb_write_verify( | |||
758 | struct xfs_buf_log_item *bip = bp->b_fspriv; | 762 | struct xfs_buf_log_item *bip = bp->b_fspriv; |
759 | int error; | 763 | int error; |
760 | 764 | ||
761 | error = xfs_sb_verify(bp); | 765 | error = xfs_sb_verify(bp, false); |
762 | if (error) { | 766 | if (error) { |
763 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); | 767 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); |
764 | xfs_buf_ioerror(bp, error); | 768 | xfs_buf_ioerror(bp, error); |