diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2022-09-03 05:59:39 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-23 00:09:40 +0300 |
commit | 38474c264252475196a5e3c555b2625a5bc36a00 (patch) | |
tree | 68d8bbf34a8bf3a3548b0e2c09bbd6d38bbeedee /fs/bcachefs/btree_key_cache.c | |
parent | 3d21d48e898a2eadc9055c44e0fd51e6087c9e9f (diff) | |
download | linux-38474c264252475196a5e3c555b2625a5bc36a00.tar.xz |
bcachefs: Avoid using btree_node_lock_nopath()
With the upcoming cycle detector, we have to be careful about using
btree_node_lock_nopath - in particular, using it to take write locks can
cause deadlocks.
All held locks need to be tracked in a btree_path, so that the cycle
detector knows about them - unless we know that we cannot cause
deadlocks for other reasons: e.g. we are only taking read locks, or
we're in very early fsck (topology repair).
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_key_cache.c')
-rw-r--r-- | fs/bcachefs/btree_key_cache.c | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c index 89e540c5a244..0f54db0c1b8a 100644 --- a/fs/bcachefs/btree_key_cache.c +++ b/fs/bcachefs/btree_key_cache.c @@ -568,26 +568,21 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans, atomic_long_dec(&c->btree_key_cache.nr_dirty); } } else { + struct btree_path *path2; evict: - BUG_ON(!btree_node_intent_locked(c_iter.path, 0)); + trans_for_each_path(trans, path2) + if (path2 != c_iter.path) + __bch2_btree_path_unlock(trans, path2); - /* - * XXX: holding a lock that is not marked in btree_trans, not - * ideal: - */ - six_lock_increment(&ck->c.lock, SIX_LOCK_intent); - bch2_trans_unlock(trans); - - /* Will not fail because we are holding no other locks: */ - btree_node_lock_nopath_nofail(trans, &ck->c, SIX_LOCK_write); + bch2_btree_node_lock_write_nofail(trans, c_iter.path, &ck->c); if (test_bit(BKEY_CACHED_DIRTY, &ck->flags)) { clear_bit(BKEY_CACHED_DIRTY, &ck->flags); atomic_long_dec(&c->btree_key_cache.nr_dirty); } + mark_btree_node_locked_noreset(c_iter.path, 0, BTREE_NODE_UNLOCKED); bkey_cached_evict(&c->btree_key_cache, ck); - bkey_cached_free_fast(&c->btree_key_cache, ck); } out: |