Merge branch 'ps/reftable-alloc-failures-zalloc-fix'

Recent reftable updates mistook a NULL return from a request for
0-byte allocation as OOM and died unnecessarily, which has been
corrected.

* ps/reftable-alloc-failures-zalloc-fix:
  reftable/basics: return NULL on zero-sized allocations
  reftable/stack: fix zero-sized allocation when there are no readers
  reftable/merged: fix zero-sized allocation when there are no readers
  reftable/stack: don't perform auto-compaction with less than two tables
This commit is contained in:
Junio C Hamano 2024-12-23 09:32:06 -08:00
commit 3151e6a121
3 changed files with 31 additions and 15 deletions

View File

@ -17,6 +17,8 @@ static void (*reftable_free_ptr)(void *);
void *reftable_malloc(size_t sz) void *reftable_malloc(size_t sz)
{ {
if (!sz)
return NULL;
if (reftable_malloc_ptr) if (reftable_malloc_ptr)
return (*reftable_malloc_ptr)(sz); return (*reftable_malloc_ptr)(sz);
return malloc(sz); return malloc(sz);
@ -24,6 +26,11 @@ void *reftable_malloc(size_t sz)
void *reftable_realloc(void *p, size_t sz) void *reftable_realloc(void *p, size_t sz)
{ {
if (!sz) {
reftable_free(p);
return NULL;
}
if (reftable_realloc_ptr) if (reftable_realloc_ptr)
return (*reftable_realloc_ptr)(p, sz); return (*reftable_realloc_ptr)(p, sz);
return realloc(p, sz); return realloc(p, sz);

View File

@ -240,14 +240,16 @@ int merged_table_init_iter(struct reftable_merged_table *mt,
struct reftable_iterator *it, struct reftable_iterator *it,
uint8_t typ) uint8_t typ)
{ {
struct merged_subiter *subiters; struct merged_subiter *subiters = NULL;
struct merged_iter *mi = NULL; struct merged_iter *mi = NULL;
int ret; int ret;
REFTABLE_CALLOC_ARRAY(subiters, mt->readers_len); if (mt->readers_len) {
if (!subiters) { REFTABLE_CALLOC_ARRAY(subiters, mt->readers_len);
ret = REFTABLE_OUT_OF_MEMORY_ERROR; if (!subiters) {
goto out; ret = REFTABLE_OUT_OF_MEMORY_ERROR;
goto out;
}
} }
for (size_t i = 0; i < mt->readers_len; i++) { for (size_t i = 0; i < mt->readers_len; i++) {

View File

@ -270,9 +270,9 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
int reuse_open) int reuse_open)
{ {
size_t cur_len = !st->merged ? 0 : st->merged->readers_len; size_t cur_len = !st->merged ? 0 : st->merged->readers_len;
struct reftable_reader **cur; struct reftable_reader **cur = NULL;
struct reftable_reader **reused = NULL; struct reftable_reader **reused = NULL;
struct reftable_reader **new_readers; struct reftable_reader **new_readers = NULL;
size_t reused_len = 0, reused_alloc = 0, names_len; size_t reused_len = 0, reused_alloc = 0, names_len;
size_t new_readers_len = 0; size_t new_readers_len = 0;
struct reftable_merged_table *new_merged = NULL; struct reftable_merged_table *new_merged = NULL;
@ -280,18 +280,22 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
int err = 0; int err = 0;
size_t i; size_t i;
cur = stack_copy_readers(st, cur_len); if (cur_len) {
if (!cur) { cur = stack_copy_readers(st, cur_len);
err = REFTABLE_OUT_OF_MEMORY_ERROR; if (!cur) {
goto done; err = REFTABLE_OUT_OF_MEMORY_ERROR;
goto done;
}
} }
names_len = names_length(names); names_len = names_length(names);
new_readers = reftable_calloc(names_len, sizeof(*new_readers)); if (names_len) {
if (!new_readers) { new_readers = reftable_calloc(names_len, sizeof(*new_readers));
err = REFTABLE_OUT_OF_MEMORY_ERROR; if (!new_readers) {
goto done; err = REFTABLE_OUT_OF_MEMORY_ERROR;
goto done;
}
} }
while (*names) { while (*names) {
@ -1627,6 +1631,9 @@ int reftable_stack_auto_compact(struct reftable_stack *st)
struct segment seg; struct segment seg;
uint64_t *sizes; uint64_t *sizes;
if (st->merged->readers_len < 2)
return 0;
sizes = stack_table_sizes_for_compaction(st); sizes = stack_table_sizes_for_compaction(st);
if (!sizes) if (!sizes)
return REFTABLE_OUT_OF_MEMORY_ERROR; return REFTABLE_OUT_OF_MEMORY_ERROR;