summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-01-12 05:16:36 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2018-05-22 00:44:18 -0400
commit479e7b1b28403b813aed98924fcf4a39d5f11960 (patch)
tree74735e422abdb0643b217e6a5f6b4e0780b5b439
parent7fd271b2f203ced72b0c400086f7a78800108a19 (diff)
bcachefs: fix a locking bug
-rw-r--r--fs/bcachefs/btree_cache.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c
index 22846d8acbfb..8faffc9aae9e 100644
--- a/fs/bcachefs/btree_cache.c
+++ b/fs/bcachefs/btree_cache.c
@@ -626,7 +626,9 @@ struct btree *bch2_btree_node_get(struct bch_fs *c, struct btree_iter *iter,
struct btree *b;
struct bset_tree *t;
- BUG_ON(level >= BTREE_MAX_DEPTH);
+ /* btree_node_fill() requires parent to be locked: */
+ EBUG_ON(!btree_node_locked(iter, level + 1));
+ EBUG_ON(level >= BTREE_MAX_DEPTH);
retry:
rcu_read_lock();
b = btree_cache_find(bc, k);
@@ -763,6 +765,12 @@ struct btree *bch2_btree_node_get_sibling(struct bch_fs *c,
if (IS_ERR(ret) && PTR_ERR(ret) == -EINTR) {
btree_node_unlock(iter, level);
+
+ if (!bch2_btree_node_relock(iter, level + 1)) {
+ bch2_btree_iter_set_locks_want(iter, level + 2);
+ return ERR_PTR(-EINTR);
+ }
+
ret = bch2_btree_node_get(c, iter, &tmp.k, level, SIX_LOCK_intent);
}