bcachefs: Fix oops in btree_node_seq_matches()
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 2 Jun 2025 13:26:20 +0000 (09:26 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 4 Jun 2025 20:45:41 +0000 (16:45 -0400)
commit9f2dc5f39431a17d304e5845a3f7e78905473442
treee57aa37735d29af89a9465d5513063cab1d940be
parent2bf380c005adcc653464215a5170afa3367c0b22
bcachefs: Fix oops in btree_node_seq_matches()

btree_update_nodes_written() needs to wait on in-flight writes to old
nodes before marking them as freed. But it has no reason to pin those
old nodes in memory, so some trickyness ensues.

The update we're completing deleted references to those nodes from the
btree, so we know if they've been evicted they can't be pulled back in.
We just have to check if the nodes we have pointers to are still those
old nodes, and haven't been reused.

To do that we check the node's "sequence number" (actually a random 64
bit cookie), but that lives in the node's data buffer. 'struct btree'
can't be freed until filesystem shutdown (as they're quite small), but
the data buffers can be freed or swapped around.

Commit 1f88c3567495, which was fixing a kmsan warning, assumed that we
could safely do this locklessly with just a READ_ONCE() - if we've got a
non-null ptr it would be safe to read from.

But that's not true if the data buffer is a vmalloc allocation, so we
need to restore the locking that commit deleted (or alternatively RCU
free those data buffers, but there's no other reason for that).

Fixes: 1f88c3567495 ("bcachefs: Fix a KMSAN splat in btree_update_nodes_written()")
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_update_interior.c