]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
bcachefs: Fix for bch2_btree_node_get_noiter() returning -ENOMEM
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 24 Feb 2021 02:41:25 +0000 (21:41 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:53 +0000 (17:08 -0400)
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>
fs/bcachefs/btree_cache.c

index 443d669e6a302bc81247a9bb722d169ba8f5574b..2152813554b48d4ad9aea84a7c45f7901ad80270 100644 (file)
@@ -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;
 }