summaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2024-02-22 21:40:57 +0100
committerDarrick J. Wong <djwong@kernel.org>2024-02-22 21:40:57 +0100
commitd477f1749f00899c71605ea01aba0ce67e030471 (patch)
treee4b392d739c1e23fd9a45d99309f8b26b6a51038 /fs/xfs
parentxfs: remove the crc variable in __xfs_btree_check_lblock (diff)
downloadlinux-d477f1749f00899c71605ea01aba0ce67e030471.tar.xz
linux-d477f1749f00899c71605ea01aba0ce67e030471.zip
xfs: tighten up validation of root block in inode forks
Check that root blocks that sit in the inode fork and thus have a NULL bp don't have siblings. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_btree.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 4a6bc66c14d0..f5d7c4236963 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -107,7 +107,7 @@ __xfs_btree_check_lblock(
{
struct xfs_mount *mp = cur->bc_mp;
xfs_failaddr_t fa;
- xfs_fsblock_t fsb = NULLFSBLOCK;
+ xfs_fsblock_t fsb;
if (xfs_has_crc(mp)) {
if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
@@ -127,9 +127,19 @@ __xfs_btree_check_lblock(
cur->bc_ops->get_maxrecs(cur, level))
return __this_address;
- if (bp)
- fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
+ /*
+ * For inode-rooted btrees, the root block sits in the inode fork. In
+ * that case bp is NULL, and the block must not have any siblings.
+ */
+ if (!bp) {
+ if (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK))
+ return __this_address;
+ if (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK))
+ return __this_address;
+ return NULL;
+ }
+ fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
fa = xfs_btree_check_lblock_siblings(mp, fsb, block->bb_u.l.bb_leftsib);
if (!fa)
fa = xfs_btree_check_lblock_siblings(mp, fsb,