diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-04-25 16:24:03 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:02 -0400 |
commit | ceda1b9a179ffd8ece3f7d15d5b1379eb2552215 (patch) | |
tree | 4592179ca6ebdb0c98516965d0183c0bfa02600b /fs/bcachefs/btree_cache.c | |
parent | fc51b041b72a7cbffc60811ff14d25207a4f7624 (diff) | |
download | lwn-ceda1b9a179ffd8ece3f7d15d5b1379eb2552215.tar.gz lwn-ceda1b9a179ffd8ece3f7d15d5b1379eb2552215.zip |
bcachefs: Evict btree nodes we're deleting
There was a bug that led to duplicate btree node pointers being inserted
at the wrong level. The new topology repair code can fix that, except
that the btree cache code gets confused when we read in a btree node
from the pointer that was at the wrong level. This patch evicts nodes
that we're deleting to, which nicely solves the problem.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_cache.c')
-rw-r--r-- | fs/bcachefs/btree_cache.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c index a42e0922f5e9..85c19e4e5216 100644 --- a/fs/bcachefs/btree_cache.c +++ b/fs/bcachefs/btree_cache.c @@ -948,6 +948,36 @@ void bch2_btree_node_prefetch(struct bch_fs *c, struct btree_iter *iter, bch2_btree_node_fill(c, iter, k, btree_id, level, SIX_LOCK_read, false); } +void bch2_btree_node_evict(struct bch_fs *c, const struct bkey_i *k) +{ + struct btree_cache *bc = &c->btree_cache; + struct btree *b; + + b = btree_cache_find(bc, k); + if (!b) + return; + + six_lock_intent(&b->c.lock, NULL, NULL); + six_lock_write(&b->c.lock, NULL, NULL); + + wait_on_bit_io(&b->flags, BTREE_NODE_read_in_flight, + TASK_UNINTERRUPTIBLE); + __bch2_btree_node_write(c, b); + + /* wait for any in flight btree write */ + btree_node_wait_on_io(b); + + BUG_ON(btree_node_dirty(b)); + + mutex_lock(&bc->lock); + btree_node_data_free(c, b); + bch2_btree_node_hash_remove(bc, b); + mutex_unlock(&bc->lock); + + six_unlock_write(&b->c.lock); + six_unlock_intent(&b->c.lock); +} + void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c, struct btree *b) { |