Commit 18a7b972 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix for bch2_btree_node_get_noiter() returning -ENOMEM

bch2_btree_node_get_noiter() isn't used from the btree iterator code,
which retries with the btree node cache cannibalize lock held on
-ENOMEM, so we should do it ourself if necessary.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent dab9ef0d
...@@ -844,7 +844,7 @@ struct btree *bch2_btree_node_get_noiter(struct bch_fs *c, ...@@ -844,7 +844,7 @@ struct btree *bch2_btree_node_get_noiter(struct bch_fs *c,
b = btree_cache_find(bc, k); b = btree_cache_find(bc, k);
if (unlikely(!b)) { if (unlikely(!b)) {
if (nofill) if (nofill)
return NULL; goto out;
b = bch2_btree_node_fill(c, NULL, k, btree_id, b = bch2_btree_node_fill(c, NULL, k, btree_id,
level, SIX_LOCK_read, true); level, SIX_LOCK_read, true);
...@@ -853,8 +853,12 @@ struct btree *bch2_btree_node_get_noiter(struct bch_fs *c, ...@@ -853,8 +853,12 @@ struct btree *bch2_btree_node_get_noiter(struct bch_fs *c,
if (!b) if (!b)
goto retry; goto retry;
if (IS_ERR(b) &&
!bch2_btree_cache_cannibalize_lock(c, NULL))
goto retry;
if (IS_ERR(b)) if (IS_ERR(b))
return b; goto out;
} else { } else {
lock_node: lock_node:
ret = six_lock_read(&b->c.lock, lock_node_check_fn, (void *) k); ret = six_lock_read(&b->c.lock, lock_node_check_fn, (void *) k);
...@@ -889,7 +893,8 @@ struct btree *bch2_btree_node_get_noiter(struct bch_fs *c, ...@@ -889,7 +893,8 @@ struct btree *bch2_btree_node_get_noiter(struct bch_fs *c,
if (unlikely(btree_node_read_error(b))) { if (unlikely(btree_node_read_error(b))) {
six_unlock_read(&b->c.lock); six_unlock_read(&b->c.lock);
return ERR_PTR(-EIO); b = ERR_PTR(-EIO);
goto out;
} }
EBUG_ON(b->c.btree_id != btree_id); EBUG_ON(b->c.btree_id != btree_id);
...@@ -898,7 +903,8 @@ struct btree *bch2_btree_node_get_noiter(struct bch_fs *c, ...@@ -898,7 +903,8 @@ struct btree *bch2_btree_node_get_noiter(struct bch_fs *c,
EBUG_ON(b->key.k.type == KEY_TYPE_btree_ptr_v2 && EBUG_ON(b->key.k.type == KEY_TYPE_btree_ptr_v2 &&
bkey_cmp(b->data->min_key, bkey_cmp(b->data->min_key,
bkey_i_to_btree_ptr_v2(&b->key)->v.min_key)); bkey_i_to_btree_ptr_v2(&b->key)->v.min_key));
out:
bch2_btree_cache_cannibalize_unlock(c);
return b; return b;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment