From fdf42aae040930374d976d0bc50f6ee0b80d048a Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 28 Jul 2026 18:41:24 +0930 Subject: [PATCH] btrfs: add validation for extent states Extent maps have the extra validation since commit 3f255ece2f1e ("btrfs: introduce extra sanity checks for extent maps"), but extent states do not have a similar check. Introduce a basic alignment check for the following call sites, so that we can cover all extent states inserted into the tree: - insert_state_fast() - insert_state() - split_state() Reviewed-by: Filipe Manana Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- fs/btrfs/extent-io-tree.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/fs/btrfs/extent-io-tree.c b/fs/btrfs/extent-io-tree.c index c18ea5ef2974..d6df11f6088c 100644 --- a/fs/btrfs/extent-io-tree.c +++ b/fs/btrfs/extent-io-tree.c @@ -334,6 +334,21 @@ static inline struct extent_state *tree_search(struct extent_io_tree *tree, u64 return tree_search_for_insert(tree, offset, NULL, NULL); } +static void validate_extent_state(const struct extent_io_tree *tree, + const struct extent_state *state) +{ + u32 blocksize; + + if (tree->owner != IO_TREE_INODE_IO) + return; + + blocksize = btrfs_extent_io_tree_to_fs_info(tree)->sectorsize; + ASSERT(IS_ALIGNED(state->start, blocksize) && + IS_ALIGNED(state->end + 1, blocksize), + "unaligned extent state, blocksize=%u start=%llu end=%llu state=0x%x", + blocksize, state->start, state->end, state->state); +} + #define extent_io_tree_panic(tree, state, opname, err) \ btrfs_panic(btrfs_extent_io_tree_to_fs_info((tree)), (err), \ "extent io tree error on %s state start %llu end %llu", \ @@ -429,6 +444,8 @@ static struct extent_state *insert_state(struct extent_io_tree *tree, const u64 end = state->end + 1; const bool try_merge = !(bits & (EXTENT_LOCK_BITS | EXTENT_BOUNDARY)); + validate_extent_state(tree, state); + set_state_bits(tree, state, bits, changeset); node = &tree->state.rb_node; @@ -481,6 +498,8 @@ static void insert_state_fast(struct extent_io_tree *tree, struct rb_node *parent, unsigned bits, struct extent_changeset *changeset) { + validate_extent_state(tree, state); + set_state_bits(tree, state, bits, changeset); rb_link_node(&state->rb_node, parent, node); rb_insert_color(&state->rb_node, &tree->state); @@ -533,6 +552,8 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, } } + validate_extent_state(tree, orig); + validate_extent_state(tree, prealloc); rb_link_node(&prealloc->rb_node, parent, node); rb_insert_color(&prealloc->rb_node, &tree->state);