Skip to content

Commit 591c6a6

Browse files
pks-tttaylorr
authored andcommitted
reftable/stack: adapt stack_filename() to handle allocation failures
The `stack_filename()` function cannot pass any errors to the caller as it has a `void` return type. Adapt it and its callers such that we can handle errors and start handling allocation failures. There are two interesting edge cases in `reftable_stack_destroy()` and `reftable_addition_close()`. Both of these are trying to tear down their respective structures, and while doing so they try to unlink some of the tables they have been keeping alive. Any earlier attempts to do that may fail on Windows because it keeps us from deleting such tables while they are still open, and thus we re-try on close. It's okay and even expected that this can fail when the tables are still open by another process, so we handle the allocation failures gracefully and just skip over any file whose name we couldn't figure out. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent 4abc802 commit 591c6a6

File tree

1 file changed

+45
-17
lines changed

1 file changed

+45
-17
lines changed

reftable/stack.c

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,16 @@ static void reftable_addition_close(struct reftable_addition *add);
3131
static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,
3232
int reuse_open);
3333

34-
static void stack_filename(struct reftable_buf *dest, struct reftable_stack *st,
35-
const char *name)
34+
static int stack_filename(struct reftable_buf *dest, struct reftable_stack *st,
35+
const char *name)
3636
{
37+
int err;
3738
reftable_buf_reset(dest);
38-
reftable_buf_addstr(dest, st->reftable_dir);
39-
reftable_buf_addstr(dest, "/");
40-
reftable_buf_addstr(dest, name);
39+
if ((err = reftable_buf_addstr(dest, st->reftable_dir)) < 0 ||
40+
(err = reftable_buf_addstr(dest, "/")) < 0 ||
41+
(err = reftable_buf_addstr(dest, name)) < 0)
42+
return err;
43+
return 0;
4144
}
4245

4346
static ssize_t reftable_fd_write(void *arg, const void *data, size_t sz)
@@ -211,13 +214,16 @@ void reftable_stack_destroy(struct reftable_stack *st)
211214
struct reftable_buf filename = REFTABLE_BUF_INIT;
212215
for (i = 0; i < st->readers_len; i++) {
213216
const char *name = reader_name(st->readers[i]);
217+
int try_unlinking = 1;
218+
214219
reftable_buf_reset(&filename);
215220
if (names && !has_name(names, name)) {
216-
stack_filename(&filename, st, name);
221+
if (stack_filename(&filename, st, name) < 0)
222+
try_unlinking = 0;
217223
}
218224
reftable_reader_decref(st->readers[i]);
219225

220-
if (filename.len) {
226+
if (try_unlinking && filename.len) {
221227
/* On Windows, can only unlink after closing. */
222228
unlink(filename.buf);
223229
}
@@ -310,7 +316,10 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
310316

311317
if (!rd) {
312318
struct reftable_block_source src = { NULL };
313-
stack_filename(&table_path, st, name);
319+
320+
err = stack_filename(&table_path, st, name);
321+
if (err < 0)
322+
goto done;
314323

315324
err = reftable_block_source_from_file(&src,
316325
table_path.buf);
@@ -341,7 +350,11 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
341350
for (i = 0; i < cur_len; i++) {
342351
if (cur[i]) {
343352
const char *name = reader_name(cur[i]);
344-
stack_filename(&table_path, st, name);
353+
354+
err = stack_filename(&table_path, st, name);
355+
if (err < 0)
356+
goto done;
357+
345358
reftable_reader_decref(cur[i]);
346359
unlink(table_path.buf);
347360
}
@@ -700,8 +713,8 @@ static void reftable_addition_close(struct reftable_addition *add)
700713
size_t i;
701714

702715
for (i = 0; i < add->new_tables_len; i++) {
703-
stack_filename(&nm, add->stack, add->new_tables[i]);
704-
unlink(nm.buf);
716+
if (!stack_filename(&nm, add->stack, add->new_tables[i]))
717+
unlink(nm.buf);
705718
reftable_free(add->new_tables[i]);
706719
add->new_tables[i] = NULL;
707720
}
@@ -851,7 +864,9 @@ int reftable_addition_add(struct reftable_addition *add,
851864
if (err < 0)
852865
goto done;
853866

854-
stack_filename(&temp_tab_file_name, add->stack, next_name.buf);
867+
err = stack_filename(&temp_tab_file_name, add->stack, next_name.buf);
868+
if (err < 0)
869+
goto done;
855870
reftable_buf_addstr(&temp_tab_file_name, ".temp.XXXXXX");
856871

857872
tab_file = mks_tempfile(temp_tab_file_name.buf);
@@ -900,7 +915,10 @@ int reftable_addition_add(struct reftable_addition *add,
900915
if (err < 0)
901916
goto done;
902917
reftable_buf_addstr(&next_name, ".ref");
903-
stack_filename(&tab_file_name, add->stack, next_name.buf);
918+
919+
err = stack_filename(&tab_file_name, add->stack, next_name.buf);
920+
if (err < 0)
921+
goto done;
904922

905923
/*
906924
On windows, this relies on rand() picking a unique destination name.
@@ -954,7 +972,9 @@ static int stack_compact_locked(struct reftable_stack *st,
954972
if (err < 0)
955973
goto done;
956974

957-
stack_filename(&tab_file_path, st, next_name.buf);
975+
err = stack_filename(&tab_file_path, st, next_name.buf);
976+
if (err < 0)
977+
goto done;
958978
reftable_buf_addstr(&tab_file_path, ".temp.XXXXXX");
959979

960980
tab_file = mks_tempfile(tab_file_path.buf);
@@ -1174,7 +1194,9 @@ static int stack_compact_range(struct reftable_stack *st,
11741194
}
11751195

11761196
for (i = last + 1; i > first; i--) {
1177-
stack_filename(&table_name, st, reader_name(st->readers[i - 1]));
1197+
err = stack_filename(&table_name, st, reader_name(st->readers[i - 1]));
1198+
if (err < 0)
1199+
goto done;
11781200

11791201
err = hold_lock_file_for_update(&table_locks[nlocks],
11801202
table_name.buf, LOCK_NO_DEREF);
@@ -1383,7 +1405,10 @@ static int stack_compact_range(struct reftable_stack *st,
13831405
goto done;
13841406

13851407
reftable_buf_addstr(&new_table_name, ".ref");
1386-
stack_filename(&new_table_path, st, new_table_name.buf);
1408+
1409+
err = stack_filename(&new_table_path, st, new_table_name.buf);
1410+
if (err < 0)
1411+
goto done;
13871412

13881413
err = rename_tempfile(&new_table, new_table_path.buf);
13891414
if (err < 0) {
@@ -1677,7 +1702,10 @@ static void remove_maybe_stale_table(struct reftable_stack *st, uint64_t max,
16771702
struct reftable_block_source src = { NULL };
16781703
struct reftable_reader *rd = NULL;
16791704
struct reftable_buf table_path = REFTABLE_BUF_INIT;
1680-
stack_filename(&table_path, st, name);
1705+
1706+
err = stack_filename(&table_path, st, name);
1707+
if (err < 0)
1708+
goto done;
16811709

16821710
err = reftable_block_source_from_file(&src, table_path.buf);
16831711
if (err < 0)

0 commit comments

Comments
 (0)