diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 09:38:51 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-07 09:38:51 -0800 |
commit | 9e1fd794cb6bf813a40849a1fc236703bdcbc1a7 (patch) | |
tree | ee707b91c8b80e2404b46172f2952b1e161ccaf1 /fs/xfs/libxfs/xfs_alloc_btree.c | |
parent | b1e243957e9b3ba8e820fb8583bdf18e7c737aa2 (diff) | |
parent | 1b9598c8fb9965fff901c4caa21fed9644c34df3 (diff) |
Merge tag 'xfs-5.1-merge-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs updates from Darrick Wong:
"Here are a number of new features and bug fixes for 5.1
They've undergone a week's worth of fstesting and merge cleanly with
master as of this morning
Most of the changes center on improving metadata validation and fixing
problems with online fsck, though there's also a new cache to speed up
unlinked inode handling and cleanup of the copy on write code in
preparation for future features
Changes for Linux 5.1:
- Fix online fsck to handle inode btrees correctly on 64k block
filesystems
- Teach online fsck to check directory and attribute names for
invalid characters
- Miscellanous fixes for online fsck
- Introduce a new panic mask so that we can halt immediately on
metadata corruption (for debugging purposes)
- Fix a block mapping race during writeback
- Cache unlinked inode list backrefs in memory to speed up list
processing
- Separate the bnobt/cntbt and inobt/finobt buffer verifiers so that
we can detect crosslinked btrees
- Refactor magic number verification so that we can standardize it
- Strengthen ondisk metadata structure offset build time verification
- Fix a memory corruption problem in the listxattr code
- Fix a shutdown problem during log recovery due to unreserved finobt
expansion
- Fix a referential integrity problem where O_TMPFILE inodes were put
on the unlinked list with nlink > 0 which would cause asserts
during log recovery if the system went down immediately
- Refactor the delayed allocation allocator to be more clever about
the possibility that its mapping might be stale
- Various fixes to the copy on write mechanism
- Make CoW preallocation suitable for use even with writes that
wouldn't otherwise require it
- Refactor an internal API
- Fix some statx implementation bugs
- Fix miscellaneous compiler and static checker complaints"
* tag 'xfs-5.1-merge-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (70 commits)
xfs: fix reporting supported extra file attributes for statx()
xfs: fix backwards endian conversion in scrub
xfs: fix uninitialized error variables
xfs: rework breaking of shared extents in xfs_file_iomap_begin
xfs: don't pass iomap flags to xfs_reflink_allocate_cow
xfs: fix uninitialized error variable
xfs: introduce an always_cow mode
xfs: report IOMAP_F_SHARED from xfs_file_iomap_begin_delay
xfs: make COW fork unwritten extent conversions more robust
xfs: merge COW handling into xfs_file_iomap_begin_delay
xfs: also truncate holes covered by COW blocks
xfs: don't use delalloc extents for COW on files with extsize hints
xfs: fix SEEK_DATA for speculative COW fork preallocation
xfs: make xfs_bmbt_to_iomap more useful
xfs: fix xfs_buf magic number endian checks
xfs: retry COW fork delalloc conversion when no extent was found
xfs: remove the truncate short cut in xfs_map_blocks
xfs: move xfs_iomap_write_allocate to xfs_aops.c
xfs: move stat accounting to xfs_bmapi_convert_delalloc
xfs: move transaction handling to xfs_bmapi_convert_delalloc
..
Diffstat (limited to 'fs/xfs/libxfs/xfs_alloc_btree.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc_btree.c | 74 |
1 files changed, 35 insertions, 39 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 4e59cc8a2802..9fe949f6055e 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -297,48 +297,34 @@ xfs_allocbt_verify( struct xfs_perag *pag = bp->b_pag; xfs_failaddr_t fa; unsigned int level; + xfs_btnum_t btnum = XFS_BTNUM_BNOi; + + if (!xfs_verify_magic(bp, block->bb_magic)) + return __this_address; + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + fa = xfs_btree_sblock_v5hdr_verify(bp); + if (fa) + return fa; + } /* - * magic number and level verification - * - * During growfs operations, we can't verify the exact level or owner as - * the perag is not fully initialised and hence not attached to the - * buffer. In this case, check against the maximum tree depth. + * The perag may not be attached during grow operations or fully + * initialized from the AGF during log recovery. Therefore we can only + * check against maximum tree depth from those contexts. * - * Similarly, during log recovery we will have a perag structure - * attached, but the agf information will not yet have been initialised - * from the on disk AGF. Again, we can only check against maximum limits - * in this case. + * Otherwise check against the per-tree limit. Peek at one of the + * verifier magic values to determine the type of tree we're verifying + * against. */ level = be16_to_cpu(block->bb_level); - switch (block->bb_magic) { - case cpu_to_be32(XFS_ABTB_CRC_MAGIC): - fa = xfs_btree_sblock_v5hdr_verify(bp); - if (fa) - return fa; - /* fall through */ - case cpu_to_be32(XFS_ABTB_MAGIC): - if (pag && pag->pagf_init) { - if (level >= pag->pagf_levels[XFS_BTNUM_BNOi]) - return __this_address; - } else if (level >= mp->m_ag_maxlevels) + if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC)) + btnum = XFS_BTNUM_CNTi; + if (pag && pag->pagf_init) { + if (level >= pag->pagf_levels[btnum]) return __this_address; - break; - case cpu_to_be32(XFS_ABTC_CRC_MAGIC): - fa = xfs_btree_sblock_v5hdr_verify(bp); - if (fa) - return fa; - /* fall through */ - case cpu_to_be32(XFS_ABTC_MAGIC): - if (pag && pag->pagf_init) { - if (level >= pag->pagf_levels[XFS_BTNUM_CNTi]) - return __this_address; - } else if (level >= mp->m_ag_maxlevels) - return __this_address; - break; - default: + } else if (level >= mp->m_ag_maxlevels) return __this_address; - } return xfs_btree_sblock_verify(bp, mp->m_alloc_mxr[level != 0]); } @@ -377,13 +363,23 @@ xfs_allocbt_write_verify( } -const struct xfs_buf_ops xfs_allocbt_buf_ops = { - .name = "xfs_allocbt", +const struct xfs_buf_ops xfs_bnobt_buf_ops = { + .name = "xfs_bnobt", + .magic = { cpu_to_be32(XFS_ABTB_MAGIC), + cpu_to_be32(XFS_ABTB_CRC_MAGIC) }, .verify_read = xfs_allocbt_read_verify, .verify_write = xfs_allocbt_write_verify, .verify_struct = xfs_allocbt_verify, }; +const struct xfs_buf_ops xfs_cntbt_buf_ops = { + .name = "xfs_cntbt", + .magic = { cpu_to_be32(XFS_ABTC_MAGIC), + cpu_to_be32(XFS_ABTC_CRC_MAGIC) }, + .verify_read = xfs_allocbt_read_verify, + .verify_write = xfs_allocbt_write_verify, + .verify_struct = xfs_allocbt_verify, +}; STATIC int xfs_bnobt_keys_inorder( @@ -448,7 +444,7 @@ static const struct xfs_btree_ops xfs_bnobt_ops = { .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, .key_diff = xfs_bnobt_key_diff, - .buf_ops = &xfs_allocbt_buf_ops, + .buf_ops = &xfs_bnobt_buf_ops, .diff_two_keys = xfs_bnobt_diff_two_keys, .keys_inorder = xfs_bnobt_keys_inorder, .recs_inorder = xfs_bnobt_recs_inorder, @@ -470,7 +466,7 @@ static const struct xfs_btree_ops xfs_cntbt_ops = { .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, .key_diff = xfs_cntbt_key_diff, - .buf_ops = &xfs_allocbt_buf_ops, + .buf_ops = &xfs_cntbt_buf_ops, .diff_two_keys = xfs_cntbt_diff_two_keys, .keys_inorder = xfs_cntbt_keys_inorder, .recs_inorder = xfs_cntbt_recs_inorder, |