diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-02-23 21:41:25 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:53 -0400 |
commit | 18a7b97239b6f0bae3fa1475cb276a273e07597a (patch) | |
tree | ebd4bf1d4108683e7e8fe09b89134e3315db1d61 | |
parent | dab9ef0d271648c24b867059855439ec48775fc4 (diff) |
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: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/btree_cache.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c index 443d669e6a30..2152813554b4 100644 --- a/fs/bcachefs/btree_cache.c +++ b/fs/bcachefs/btree_cache.c @@ -844,7 +844,7 @@ retry: b = btree_cache_find(bc, k); if (unlikely(!b)) { if (nofill) - return NULL; + goto out; b = bch2_btree_node_fill(c, NULL, k, btree_id, level, SIX_LOCK_read, true); @@ -853,8 +853,12 @@ retry: if (!b) goto retry; + if (IS_ERR(b) && + !bch2_btree_cache_cannibalize_lock(c, NULL)) + goto retry; + if (IS_ERR(b)) - return b; + goto out; } else { lock_node: ret = six_lock_read(&b->c.lock, lock_node_check_fn, (void *) k); @@ -889,7 +893,8 @@ lock_node: if (unlikely(btree_node_read_error(b))) { six_unlock_read(&b->c.lock); - return ERR_PTR(-EIO); + b = ERR_PTR(-EIO); + goto out; } EBUG_ON(b->c.btree_id != btree_id); @@ -898,7 +903,8 @@ lock_node: EBUG_ON(b->key.k.type == KEY_TYPE_btree_ptr_v2 && bkey_cmp(b->data->min_key, bkey_i_to_btree_ptr_v2(&b->key)->v.min_key)); - +out: + bch2_btree_cache_cannibalize_unlock(c); return b; } |