]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
btrfs: revalidate cached tree blocks on the uptodate path
authorZhengYuan Huang <gality369@gmail.com>
Fri, 13 Mar 2026 09:19:23 +0000 (17:19 +0800)
committerDavid Sterba <dsterba@suse.com>
Tue, 7 Apr 2026 16:56:02 +0000 (18:56 +0200)
commitf04c6475c2db778e7a9657a7f7b4a5033c933ff1
treeec5da2eb2f9327cec09150271f84a05ca8a6e34f
parente5267796482fad93ee7948c7cbc37f32046244f7
btrfs: revalidate cached tree blocks on the uptodate path

read_extent_buffer_pages_nowait() returns immediately when an extent
buffer is already marked uptodate. On that cache-hit path,
the caller supplied btrfs_tree_parent_check is not re-run.

This can let read_tree_root_path() accept a cached tree block whose
actual header level/owner does not match the expected value derived from
the parent.

E.g. a corrupted root item that points to a tree block which doesn't
even belong to that root, and has mismatching level/owner.

But that tree block is already read and cached, later the corrupted tree
root got read from disk and hit the cached tree block.

Fix this by re-validating cached extent buffers against the supplied
btrfs_tree_parent_check on the uptodate path, and make
read_tree_root_path() pass its check to btrfs_buffer_uptodate().

This makes cache hits and fresh reads follow the same tree-parent
verification rules, and turns the corruption into a read failure instead
of constructing an inconsistent root object.

Signed-off-by: ZhengYuan Huang <gality369@gmail.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
[ Resolve the conflict with extent_buffer_uptodate() helper, handle
  transid mismatch case ]
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.c
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/tree-log.c