diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-04-13 16:13:13 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-04-13 22:49:25 -0400 |
commit | 9054ef2ea944528b7935d0ce3f540d4dc0bc37ba (patch) | |
tree | 42c8f8122a74fbaca3c36b495802ae2f86883849 | |
parent | 9e203c43dc1cbaefb3888ee0ba885b2d20d47526 (diff) | |
download | lwn-9054ef2ea944528b7935d0ce3f540d4dc0bc37ba.tar.gz lwn-9054ef2ea944528b7935d0ce3f540d4dc0bc37ba.zip |
bcachefs: Run merges at BCH_WATERMARK_btree
This fixes a deadlock where the interior update path during journal
replay ends up doing a ton of merges on the backpointers btree, and
deadlocking.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 29a5bc7d8789..1a7537ee4329 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -1926,6 +1926,8 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans, BUG_ON(!trans->paths[path].should_be_locked); BUG_ON(!btree_node_locked(&trans->paths[path], level)); + flags &= ~BCH_WATERMARK_MASK; + b = trans->paths[path].l[level].b; if ((sib == btree_prev_sib && bpos_eq(b->data->min_key, POS_MIN)) || @@ -2071,6 +2073,10 @@ err: bch2_path_put(trans, new_path, true); bch2_path_put(trans, sib_path, true); bch2_trans_verify_locks(trans); + if (ret == -BCH_ERR_journal_reclaim_would_deadlock) + ret = 0; + if (!ret) + ret = bch2_trans_relock(trans); return ret; err_free_update: bch2_btree_node_free_never_used(as, trans, n); |