aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_alloc_btree.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-07 09:38:51 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-07 09:38:51 -0800
commit9e1fd794cb6bf813a40849a1fc236703bdcbc1a7 (patch)
treeee707b91c8b80e2404b46172f2952b1e161ccaf1 /fs/xfs/libxfs/xfs_alloc_btree.c
parentMerge tag 'for-5.1-part1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux (diff)
parentxfs: fix reporting supported extra file attributes for statx() (diff)
downloadlinux-dev-9e1fd794cb6bf813a40849a1fc236703bdcbc1a7.tar.xz
linux-dev-9e1fd794cb6bf813a40849a1fc236703bdcbc1a7.zip
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.c74
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,