[PATCH 6/6] xfs: fix the rtrmap and rtrefcount _maxlevels_ondisk functions
"Darrick J. Wong" <[email protected]> Wed, 29 Jul 2026 22:27:35 -0700
| Newsgroups | org.kernel.vger.linux-xfs,org.kernel.vger.stable |
|---|---|
| Message-ID | <178538913008.4070956.1052714188976376785.stgit@frogsfrogsfrogs> |
From: Darrick J. Wong <[email protected]> The _maxlevels_ondisk functions are used to compute the size of in-memory btree cursors for each btree type. Unfortunately, LOLLM noticed that the rtrmap and rtrefcount versions of these functions forget to account for the inode root, which means that we could access beyond the end of the cursor given a sufficiently large btree. Fix this. Cc: <[email protected]> # v6.14 Fixes: 9abe03a0e4f978 ("xfs: introduce realtime refcount btree ondisk definitions") Signed-off-by: "Darrick J. Wong" <[email protected]> Assisted-by: LOLLM # finding obvious bugs --- fs/xfs/libxfs/xfs_rtrefcount_btree.c | 7 +++++-- fs/xfs/libxfs/xfs_rtrmap_btree.c | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtrefcount_btree.c b/fs/xfs/libxfs/xfs_rtrefcount_btree.c index f27b80a199ba2e..971cb27400b042 100644 --- a/fs/xfs/libxfs/xfs_rtrefcount_btree.c +++ b/fs/xfs/libxfs/xfs_rtrefcount_btree.c @@ -489,8 +489,11 @@ xfs_rtrefcountbt_maxlevels_ondisk(void) minrecs[0] = xfs_rtrefcountbt_block_maxrecs(blocklen, true) / 2; minrecs[1] = xfs_rtrefcountbt_block_maxrecs(blocklen, false) / 2; - /* We need at most one record for every block in an rt group. */ - return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_RGBLOCKS); + /* + * We need at most one record for every block in an rt group, and + * one extra level for the inode root. + */ + return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_RGBLOCKS) + 1; } int __init diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.c b/fs/xfs/libxfs/xfs_rtrmap_btree.c index c264bc5651c0a6..0cb2113d5b4045 100644 --- a/fs/xfs/libxfs/xfs_rtrmap_btree.c +++ b/fs/xfs/libxfs/xfs_rtrmap_btree.c @@ -716,10 +716,12 @@ xfs_rtrmapbt_maxlevels_ondisk(void) * happens, which means that we must compute the max height based on * what the btree will look like if it consumes almost all the blocks * in the data device due to maximal sharing factor. + * + * Add one extra level for the inode root. */ max_dblocks = -1U; /* max ag count */ max_dblocks *= XFS_MAX_CRC_AG_BLOCKS; - return xfs_btree_space_to_height(minrecs, max_dblocks); + return xfs_btree_space_to_height(minrecs, max_dblocks) + 1; } int __init