btrfs: panic instead of warn when splitting extent state not in the tree

We are not expected ever to split an extent state record that is not in
the rbtree, as every record we pass to split_state() was found by
iterating the rbtree, so if that ever happens it means we are not holding
the extent io tree's spinlock or we have some memory corruption.

Instead of simply warning in case the extent state record passed to
split_state() is not in the rbtree, panic as this is a serious problem.
Also tag as unlikely the case where the record is not in the rbtree.

This also makes a tiny reduction the btrfs module's text size.

Before:

  $ size fs/btrfs/btrfs.ko
     text	   data	    bss	    dec	    hex	filename
  2000080	 174328	  15592	2190000	 216ab0	fs/btrfs/btrfs.ko

After:

  $ size fs/btrfs/btrfs.ko
     text	   data	    bss	    dec	    hex	filename
  2000064	 174328	  15592	2189984	 216aa0	fs/btrfs/btrfs.ko

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Filipe Manana 2026-03-11 16:15:59 +00:00 committed by David Sterba
parent 0611e2ad02
commit 057217f39a

View File

@ -591,14 +591,13 @@ static struct extent_state *clear_state_bit(struct extent_io_tree *tree,
state->state &= ~bits_to_clear;
state_wake_up(tree, state, bits);
if (state->state == 0) {
if (unlikely(!extent_state_in_tree(state)))
extent_io_tree_panic(tree, state, "extent_state_in_tree", -EUCLEAN);
next = next_search_state(state, end);
if (extent_state_in_tree(state)) {
rb_erase(&state->rb_node, &tree->state);
RB_CLEAR_NODE(&state->rb_node);
btrfs_free_extent_state(state);
} else {
WARN_ON(1);
}
rb_erase(&state->rb_node, &tree->state);
RB_CLEAR_NODE(&state->rb_node);
btrfs_free_extent_state(state);
} else {
merge_state(tree, state);
next = next_search_state(state, end);