]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: Don't allocate new memory when mempool is exhausted
authorAlan Huang <mmpgouride@gmail.com>
Fri, 13 Jun 2025 13:19:50 +0000 (21:19 +0800)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 16 Jun 2025 02:11:55 +0000 (22:11 -0400)
Allocating new memory when mempool is exhausted is too complicated, just
return ENOMEM is fine. memcpy is not needed, since there might be
pointers point to the old memory, that's the bug.

Signed-off-by: Alan Huang <mmpgouride@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_iter.c

index b586ecf2fdfa15e77616a2b86b713456ae2facfd..55de2e474705cea386e68e505c2208d7611d004d 100644 (file)
@@ -3217,28 +3217,8 @@ void *__bch2_trans_kmalloc(struct btree_trans *trans, size_t size, unsigned long
        }
 
        if (trans->used_mempool) {
-               if (trans->mem_bytes >= new_bytes)
-                       goto out_change_top;
-
-               /* No more space from mempool item, need malloc new one */
-               new_mem = kmalloc(new_bytes, GFP_NOWAIT|__GFP_NOWARN);
-               if (unlikely(!new_mem)) {
-                       bch2_trans_unlock(trans);
-
-                       new_mem = kmalloc(new_bytes, GFP_KERNEL);
-                       if (!new_mem)
-                               return ERR_PTR(-BCH_ERR_ENOMEM_trans_kmalloc);
-
-                       ret = bch2_trans_relock(trans);
-                       if (ret) {
-                               kfree(new_mem);
-                               return ERR_PTR(ret);
-                       }
-               }
-               memcpy(new_mem, trans->mem, trans->mem_top);
-               trans->used_mempool = false;
-               mempool_free(trans->mem, &c->btree_trans_mem_pool);
-               goto out_new_mem;
+               EBUG_ON(trans->mem_bytes >= new_bytes);
+               return ERR_PTR(-BCH_ERR_ENOMEM_trans_kmalloc);
        }
 
        new_mem = krealloc(trans->mem, new_bytes, GFP_NOWAIT|__GFP_NOWARN);
@@ -3249,7 +3229,6 @@ void *__bch2_trans_kmalloc(struct btree_trans *trans, size_t size, unsigned long
                if (!new_mem && new_bytes <= BTREE_TRANS_MEM_MAX) {
                        new_mem = mempool_alloc(&c->btree_trans_mem_pool, GFP_KERNEL);
                        new_bytes = BTREE_TRANS_MEM_MAX;
-                       memcpy(new_mem, trans->mem, trans->mem_top);
                        trans->used_mempool = true;
                        kfree(trans->mem);
                }
@@ -3264,7 +3243,7 @@ void *__bch2_trans_kmalloc(struct btree_trans *trans, size_t size, unsigned long
                if (ret)
                        return ERR_PTR(ret);
        }
-out_new_mem:
+
        trans->mem = new_mem;
        trans->mem_bytes = new_bytes;
 
@@ -3273,7 +3252,7 @@ out_new_mem:
                return ERR_PTR(btree_trans_restart_ip(trans,
                                        BCH_ERR_transaction_restart_mem_realloced, _RET_IP_));
        }
-out_change_top:
+
        bch2_trans_kmalloc_trace(trans, size, ip);
 
        p = trans->mem + trans->mem_top;