]> www.infradead.org Git - users/dwmw2/linux.git/commit
xfs: update btree keys correctly when _insrec splits an inode root block
authorDarrick J. Wong <djwong@kernel.org>
Mon, 2 Dec 2024 18:57:31 +0000 (10:57 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Fri, 13 Dec 2024 01:45:10 +0000 (17:45 -0800)
commit6d7b4bc1c3e00b1a25b7a05141a64337b4629337
tree3e1e32cb43f5048d84d19ce7232c8f1caf0c2e09
parent23bee6f390a12d0c4c51fefc083704bc5dac377e
xfs: update btree keys correctly when _insrec splits an inode root block

In commit 2c813ad66a72, I partially fixed a bug wherein xfs_btree_insrec
would erroneously try to update the parent's key for a block that had
been split if we decided to insert the new record into the new block.
The solution was to detect this situation and update the in-core key
value that we pass up to the caller so that the caller will (eventually)
add the new block to the parent level of the tree with the correct key.

However, I missed a subtlety about the way inode-rooted btrees work.  If
the full block was a maximally sized inode root block, we'll solve that
fullness by moving the root block's records to a new block, resizing the
root block, and updating the root to point to the new block.  We don't
pass a pointer to the new block to the caller because that work has
already been done.  The new record will /always/ land in the new block,
so in this case we need to use xfs_btree_update_keys to update the keys.

This bug can theoretically manifest itself in the very rare case that we
split a bmbt root block and the new record lands in the very first slot
of the new block, though I've never managed to trigger it in practice.
However, it is very easy to reproduce by running generic/522 with the
realtime rmapbt patchset if rtinherit=1.

Cc: <stable@vger.kernel.org> # v4.8
Fixes: 2c813ad66a7218 ("xfs: support btrees with overlapping intervals for keys")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_btree.c