diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-01-12 05:16:36 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-05-22 00:44:18 -0400 |
commit | 479e7b1b28403b813aed98924fcf4a39d5f11960 (patch) | |
tree | 74735e422abdb0643b217e6a5f6b4e0780b5b439 | |
parent | 7fd271b2f203ced72b0c400086f7a78800108a19 (diff) |
bcachefs: fix a locking bug
-rw-r--r-- | fs/bcachefs/btree_cache.c | 10 |
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); } |