mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
bcachefs: Don't allocate new memory when mempool is exhausted
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>
This commit is contained in:
committed by
Kent Overstreet
parent
3bd6f8aeae
commit
9b9a327009
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user