diff options
| author | Junio C Hamano <gitster@pobox.com> | 2024-12-10 10:04:56 +0900 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2024-12-10 10:04:56 +0900 |
| commit | de9278127e107455fda269d2db280782d77e5eba (patch) | |
| tree | d6b91c410d041a5b24e8a3c25f9fdba59c629a97 /reftable/stack.c | |
| parent | 35f40385e441d5aa885f5aa813539d5ed9dc2d26 (diff) | |
| parent | 988e7f5e952bbb7b6ae885f4da744f536f22693f (diff) | |
| download | git-de9278127e107455fda269d2db280782d77e5eba.tar.gz | |
Merge branch 'ps/reftable-detach'
Isolates the reftable subsystem from the rest of Git's codebase by
using fewer pieces of Git's infrastructure.
* ps/reftable-detach:
reftable/system: provide thin wrapper for lockfile subsystem
reftable/stack: drop only use of `get_locked_file_path()`
reftable/system: provide thin wrapper for tempfile subsystem
reftable/stack: stop using `fsync_component()` directly
reftable/system: stop depending on "hash.h"
reftable: explicitly handle hash format IDs
reftable/system: move "dir.h" to its only user
Diffstat (limited to 'reftable/stack.c')
| -rw-r--r-- | reftable/stack.c | 171 |
1 files changed, 86 insertions, 85 deletions
diff --git a/reftable/stack.c b/reftable/stack.c index c33979536e..10d45e89d0 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -8,7 +8,6 @@ https://developers.google.com/open-source/licenses/bsd #include "stack.h" -#include "../write-or-die.h" #include "system.h" #include "constants.h" #include "merged.h" @@ -17,7 +16,6 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable-record.h" #include "reftable-merged.h" #include "writer.h" -#include "tempfile.h" static int stack_try_add(struct reftable_stack *st, int (*write_table)(struct reftable_writer *wr, @@ -43,17 +41,28 @@ static int stack_filename(struct reftable_buf *dest, struct reftable_stack *st, return 0; } -static ssize_t reftable_fd_write(void *arg, const void *data, size_t sz) +static int stack_fsync(const struct reftable_write_options *opts, int fd) { - int *fdp = (int *)arg; - return write_in_full(*fdp, data, sz); + if (opts->fsync) + return opts->fsync(fd); + return fsync(fd); } -static int reftable_fd_flush(void *arg) +struct fd_writer { + const struct reftable_write_options *opts; + int fd; +}; + +static ssize_t fd_writer_write(void *arg, const void *data, size_t sz) { - int *fdp = (int *)arg; + struct fd_writer *writer = arg; + return write_in_full(writer->fd, data, sz); +} - return fsync_component(FSYNC_COMPONENT_REFERENCE, *fdp); +static int fd_writer_flush(void *arg) +{ + struct fd_writer *writer = arg; + return stack_fsync(writer->opts, writer->fd); } int reftable_new_stack(struct reftable_stack **dest, const char *dir, @@ -73,7 +82,7 @@ int reftable_new_stack(struct reftable_stack **dest, const char *dir, if (_opts) opts = *_opts; if (opts.hash_id == 0) - opts.hash_id = GIT_SHA1_FORMAT_ID; + opts.hash_id = REFTABLE_HASH_SHA1; *dest = NULL; @@ -648,7 +657,7 @@ static int format_name(struct reftable_buf *dest, uint64_t min, uint64_t max) } struct reftable_addition { - struct lock_file tables_list_lock; + struct reftable_flock tables_list_lock; struct reftable_stack *stack; char **new_tables; @@ -667,10 +676,8 @@ static int reftable_stack_init_addition(struct reftable_addition *add, add->stack = st; - err = hold_lock_file_for_update_timeout(&add->tables_list_lock, - st->list_file, - LOCK_NO_DEREF, - st->opts.lock_timeout_ms); + err = flock_acquire(&add->tables_list_lock, st->list_file, + st->opts.lock_timeout_ms); if (err < 0) { if (errno == EEXIST) { err = REFTABLE_LOCK_ERROR; @@ -680,7 +687,7 @@ static int reftable_stack_init_addition(struct reftable_addition *add, goto done; } if (st->opts.default_permissions) { - if (chmod(get_lock_file_path(&add->tables_list_lock), + if (chmod(add->tables_list_lock.path, st->opts.default_permissions) < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -724,7 +731,7 @@ static void reftable_addition_close(struct reftable_addition *add) add->new_tables_len = 0; add->new_tables_cap = 0; - rollback_lock_file(&add->tables_list_lock); + flock_release(&add->tables_list_lock); reftable_buf_release(&nm); } @@ -740,7 +747,6 @@ void reftable_addition_destroy(struct reftable_addition *add) int reftable_addition_commit(struct reftable_addition *add) { struct reftable_buf table_list = REFTABLE_BUF_INIT; - int lock_file_fd = get_lock_file_fd(&add->tables_list_lock); int err = 0; size_t i; @@ -758,20 +764,20 @@ int reftable_addition_commit(struct reftable_addition *add) goto done; } - err = write_in_full(lock_file_fd, table_list.buf, table_list.len); + err = write_in_full(add->tables_list_lock.fd, table_list.buf, table_list.len); reftable_buf_release(&table_list); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; } - err = fsync_component(FSYNC_COMPONENT_REFERENCE, lock_file_fd); + err = stack_fsync(&add->stack->opts, add->tables_list_lock.fd); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; } - err = commit_lock_file(&add->tables_list_lock); + err = flock_commit(&add->tables_list_lock); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -857,9 +863,11 @@ int reftable_addition_add(struct reftable_addition *add, struct reftable_buf tab_file_name = REFTABLE_BUF_INIT; struct reftable_buf next_name = REFTABLE_BUF_INIT; struct reftable_writer *wr = NULL; - struct tempfile *tab_file = NULL; + struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT; + struct fd_writer writer = { + .opts = &add->stack->opts, + }; int err = 0; - int tab_fd; reftable_buf_reset(&next_name); @@ -875,22 +883,20 @@ int reftable_addition_add(struct reftable_addition *add, if (err < 0) goto done; - tab_file = mks_tempfile(temp_tab_file_name.buf); - if (!tab_file) { - err = REFTABLE_IO_ERROR; + err = tmpfile_from_pattern(&tab_file, temp_tab_file_name.buf); + if (err < 0) goto done; - } if (add->stack->opts.default_permissions) { - if (chmod(get_tempfile_path(tab_file), + if (chmod(tab_file.path, add->stack->opts.default_permissions)) { err = REFTABLE_IO_ERROR; goto done; } } - tab_fd = get_tempfile_fd(tab_file); - err = reftable_writer_new(&wr, reftable_fd_write, reftable_fd_flush, - &tab_fd, &add->stack->opts); + writer.fd = tab_file.fd; + err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush, + &writer, &add->stack->opts); if (err < 0) goto done; @@ -906,11 +912,9 @@ int reftable_addition_add(struct reftable_addition *add, if (err < 0) goto done; - err = close_tempfile_gently(tab_file); - if (err < 0) { - err = REFTABLE_IO_ERROR; + err = tmpfile_close(&tab_file); + if (err < 0) goto done; - } if (wr->min_update_index < add->next_update_index) { err = REFTABLE_API_ERROR; @@ -933,11 +937,9 @@ int reftable_addition_add(struct reftable_addition *add, On windows, this relies on rand() picking a unique destination name. Maybe we should do retry loop as well? */ - err = rename_tempfile(&tab_file, tab_file_name.buf); - if (err < 0) { - err = REFTABLE_IO_ERROR; + err = tmpfile_rename(&tab_file, tab_file_name.buf); + if (err < 0) goto done; - } REFTABLE_ALLOC_GROW(add->new_tables, add->new_tables_len + 1, add->new_tables_cap); @@ -948,7 +950,7 @@ int reftable_addition_add(struct reftable_addition *add, add->new_tables[add->new_tables_len++] = reftable_buf_detach(&next_name); done: - delete_tempfile(&tab_file); + tmpfile_delete(&tab_file); reftable_buf_release(&temp_tab_file_name); reftable_buf_release(&tab_file_name); reftable_buf_release(&next_name); @@ -968,13 +970,16 @@ uint64_t reftable_stack_next_update_index(struct reftable_stack *st) static int stack_compact_locked(struct reftable_stack *st, size_t first, size_t last, struct reftable_log_expiry_config *config, - struct tempfile **tab_file_out) + struct reftable_tmpfile *tab_file_out) { struct reftable_buf next_name = REFTABLE_BUF_INIT; struct reftable_buf tab_file_path = REFTABLE_BUF_INIT; struct reftable_writer *wr = NULL; - struct tempfile *tab_file; - int tab_fd, err = 0; + struct fd_writer writer= { + .opts = &st->opts, + }; + struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT; + int err = 0; err = format_name(&next_name, reftable_reader_min_update_index(st->readers[first]), reftable_reader_max_update_index(st->readers[last])); @@ -989,21 +994,19 @@ static int stack_compact_locked(struct reftable_stack *st, if (err < 0) goto done; - tab_file = mks_tempfile(tab_file_path.buf); - if (!tab_file) { - err = REFTABLE_IO_ERROR; + err = tmpfile_from_pattern(&tab_file, tab_file_path.buf); + if (err < 0) goto done; - } - tab_fd = get_tempfile_fd(tab_file); if (st->opts.default_permissions && - chmod(get_tempfile_path(tab_file), st->opts.default_permissions) < 0) { + chmod(tab_file.path, st->opts.default_permissions) < 0) { err = REFTABLE_IO_ERROR; goto done; } - err = reftable_writer_new(&wr, reftable_fd_write, reftable_fd_flush, - &tab_fd, &st->opts); + writer.fd = tab_file.fd; + err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush, + &writer, &st->opts); if (err < 0) goto done; @@ -1015,15 +1018,15 @@ static int stack_compact_locked(struct reftable_stack *st, if (err < 0) goto done; - err = close_tempfile_gently(tab_file); + err = tmpfile_close(&tab_file); if (err < 0) goto done; *tab_file_out = tab_file; - tab_file = NULL; + tab_file = REFTABLE_TMPFILE_INIT; done: - delete_tempfile(&tab_file); + tmpfile_delete(&tab_file); reftable_writer_free(wr); reftable_buf_release(&next_name); reftable_buf_release(&tab_file_path); @@ -1154,9 +1157,9 @@ static int stack_compact_range(struct reftable_stack *st, struct reftable_buf new_table_name = REFTABLE_BUF_INIT; struct reftable_buf new_table_path = REFTABLE_BUF_INIT; struct reftable_buf table_name = REFTABLE_BUF_INIT; - struct lock_file tables_list_lock = LOCK_INIT; - struct lock_file *table_locks = NULL; - struct tempfile *new_table = NULL; + struct reftable_flock tables_list_lock = REFTABLE_FLOCK_INIT; + struct reftable_flock *table_locks = NULL; + struct reftable_tmpfile new_table = REFTABLE_TMPFILE_INIT; int is_empty_table = 0, err = 0; size_t first_to_replace, last_to_replace; size_t i, nlocks = 0; @@ -1173,10 +1176,7 @@ static int stack_compact_range(struct reftable_stack *st, * Hold the lock so that we can read "tables.list" and lock all tables * which are part of the user-specified range. */ - err = hold_lock_file_for_update_timeout(&tables_list_lock, - st->list_file, - LOCK_NO_DEREF, - st->opts.lock_timeout_ms); + err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); if (err < 0) { if (errno == EEXIST) err = REFTABLE_LOCK_ERROR; @@ -1199,19 +1199,20 @@ static int stack_compact_range(struct reftable_stack *st, * older process is still busy compacting tables which are preexisting * from the point of view of the newer process. */ - REFTABLE_CALLOC_ARRAY(table_locks, last - first + 1); + REFTABLE_ALLOC_ARRAY(table_locks, last - first + 1); if (!table_locks) { err = REFTABLE_OUT_OF_MEMORY_ERROR; goto done; } + for (i = 0; i < last - first + 1; i++) + table_locks[i] = REFTABLE_FLOCK_INIT; for (i = last + 1; i > first; i--) { err = stack_filename(&table_name, st, reader_name(st->readers[i - 1])); if (err < 0) goto done; - err = hold_lock_file_for_update(&table_locks[nlocks], - table_name.buf, LOCK_NO_DEREF); + err = flock_acquire(&table_locks[nlocks], table_name.buf, 0); if (err < 0) { /* * When the table is locked already we may do a @@ -1247,7 +1248,7 @@ static int stack_compact_range(struct reftable_stack *st, * run into file descriptor exhaustion when we compress a lot * of tables. */ - err = close_lock_file_gently(&table_locks[nlocks++]); + err = flock_close(&table_locks[nlocks++]); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -1259,7 +1260,7 @@ static int stack_compact_range(struct reftable_stack *st, * "tables.list" lock while compacting the locked tables. This allows * concurrent updates to the stack to proceed. */ - err = rollback_lock_file(&tables_list_lock); + err = flock_release(&tables_list_lock); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -1282,10 +1283,7 @@ static int stack_compact_range(struct reftable_stack *st, * "tables.list". We'll then replace the compacted range of tables with * the new table. */ - err = hold_lock_file_for_update_timeout(&tables_list_lock, - st->list_file, - LOCK_NO_DEREF, - st->opts.lock_timeout_ms); + err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); if (err < 0) { if (errno == EEXIST) err = REFTABLE_LOCK_ERROR; @@ -1295,7 +1293,7 @@ static int stack_compact_range(struct reftable_stack *st, } if (st->opts.default_permissions) { - if (chmod(get_lock_file_path(&tables_list_lock), + if (chmod(tables_list_lock.path, st->opts.default_permissions) < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -1424,11 +1422,9 @@ static int stack_compact_range(struct reftable_stack *st, if (err < 0) goto done; - err = rename_tempfile(&new_table, new_table_path.buf); - if (err < 0) { - err = REFTABLE_IO_ERROR; + err = tmpfile_rename(&new_table, new_table_path.buf); + if (err < 0) goto done; - } } /* @@ -1452,7 +1448,7 @@ static int stack_compact_range(struct reftable_stack *st, goto done; } - err = write_in_full(get_lock_file_fd(&tables_list_lock), + err = write_in_full(tables_list_lock.fd, tables_list_buf.buf, tables_list_buf.len); if (err < 0) { err = REFTABLE_IO_ERROR; @@ -1460,14 +1456,14 @@ static int stack_compact_range(struct reftable_stack *st, goto done; } - err = fsync_component(FSYNC_COMPONENT_REFERENCE, get_lock_file_fd(&tables_list_lock)); + err = stack_fsync(&st->opts, tables_list_lock.fd); if (err < 0) { err = REFTABLE_IO_ERROR; unlink(new_table_path.buf); goto done; } - err = commit_lock_file(&tables_list_lock); + err = flock_commit(&tables_list_lock); if (err < 0) { err = REFTABLE_IO_ERROR; unlink(new_table_path.buf); @@ -1488,19 +1484,24 @@ static int stack_compact_range(struct reftable_stack *st, * readers, so it is expected that unlinking tables may fail. */ for (i = 0; i < nlocks; i++) { - struct lock_file *table_lock = &table_locks[i]; - char *table_path = get_locked_file_path(table_lock); - unlink(table_path); - reftable_free(table_path); + struct reftable_flock *table_lock = &table_locks[i]; + + reftable_buf_reset(&table_name); + err = reftable_buf_add(&table_name, table_lock->path, + strlen(table_lock->path) - strlen(".lock")); + if (err) + continue; + + unlink(table_name.buf); } done: - rollback_lock_file(&tables_list_lock); + flock_release(&tables_list_lock); for (i = 0; table_locks && i < nlocks; i++) - rollback_lock_file(&table_locks[i]); + flock_release(&table_locks[i]); reftable_free(table_locks); - delete_tempfile(&new_table); + tmpfile_delete(&new_table); reftable_buf_release(&new_table_name); reftable_buf_release(&new_table_path); reftable_buf_release(&tables_list_buf); @@ -1603,7 +1604,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n, static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack *st) { - int version = (st->opts.hash_id == GIT_SHA1_FORMAT_ID) ? 1 : 2; + int version = (st->opts.hash_id == REFTABLE_HASH_SHA1) ? 1 : 2; int overhead = header_size(version) - 1; uint64_t *sizes; |
