summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_cache.c')
-rw-r--r--libbcachefs/btree_cache.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/libbcachefs/btree_cache.c b/libbcachefs/btree_cache.c
index 22846d8a..78e36299 100644
--- a/libbcachefs/btree_cache.c
+++ b/libbcachefs/btree_cache.c
@@ -178,9 +178,9 @@ static int __btree_node_reclaim(struct bch_fs *c, struct btree *b, bool flush)
* the post write cleanup:
*/
if (verify_btree_ondisk(c))
- bch2_btree_node_write(c, b, NULL, SIX_LOCK_intent);
+ bch2_btree_node_write(c, b, SIX_LOCK_intent);
else
- __bch2_btree_node_write(c, b, NULL, SIX_LOCK_read);
+ __bch2_btree_node_write(c, b, SIX_LOCK_read);
/* wait for any in flight btree write */
btree_node_wait_on_io(b);
@@ -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);
}