summaryrefslogtreecommitdiff
path: root/fs/bcachefs/btree_locking.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-06-13 05:29:48 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:08:41 +0300
commitbd2bb273a09b93e2a7d79d30458ab5f6f0b3757a (patch)
tree8ed7c91566eaef19f442b0a763cf43e08fb72faa /fs/bcachefs/btree_locking.h
parent515282ac7d847d567dd3ba802edf34316368bb14 (diff)
downloadlinux-bd2bb273a09b93e2a7d79d30458ab5f6f0b3757a.tar.xz
bcachefs: Don't deadlock when btree node reuse changes lock ordering
Btree node lock ordering is based on the logical key. However, 'struct btree' may be reused for a different btree node under memory pressure. This patch uses the new six lock callback to check if a btree node is no longer the node we wanted to lock before blocking. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_locking.h')
-rw-r--r--fs/bcachefs/btree_locking.h19
1 files changed, 12 insertions, 7 deletions
diff --git a/fs/bcachefs/btree_locking.h b/fs/bcachefs/btree_locking.h
index 4c80ab368e69..ffee6f2d7d4b 100644
--- a/fs/bcachefs/btree_locking.h
+++ b/fs/bcachefs/btree_locking.h
@@ -174,17 +174,21 @@ static inline bool btree_node_lock_increment(struct btree_trans *trans,
}
bool __bch2_btree_node_lock(struct btree *, struct bpos, unsigned,
- struct btree_iter *, enum six_lock_type);
-
-static inline bool btree_node_lock(struct btree *b, struct bpos pos,
- unsigned level,
- struct btree_iter *iter,
- enum six_lock_type type)
+ struct btree_iter *, enum six_lock_type,
+ six_lock_should_sleep_fn, void *);
+
+static inline bool btree_node_lock(struct btree *b,
+ struct bpos pos, unsigned level,
+ struct btree_iter *iter,
+ enum six_lock_type type,
+ six_lock_should_sleep_fn should_sleep_fn, void *p)
{
struct btree_trans *trans = iter->trans;
bool ret;
EBUG_ON(level >= BTREE_MAX_DEPTH);
+ EBUG_ON(!(trans->iters_linked & (1ULL << iter->idx)));
+
#ifdef CONFIG_BCACHEFS_DEBUG
trans->locking = b;
trans->locking_iter_idx = iter->idx;
@@ -194,7 +198,8 @@ static inline bool btree_node_lock(struct btree *b, struct bpos pos,
#endif
ret = likely(six_trylock_type(&b->c.lock, type)) ||
btree_node_lock_increment(trans, b, level, type) ||
- __bch2_btree_node_lock(b, pos, level, iter, type);
+ __bch2_btree_node_lock(b, pos, level, iter, type,
+ should_sleep_fn, p);
#ifdef CONFIG_BCACHEFS_DEBUG
trans->locking = NULL;