From b45ea595e6f6b03a749abc2c8e508504429a4cf3 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 2 Apr 2026 09:31:15 +0200 Subject: reftable/stack: provide fsync(3p) via system header Users of the reftable library are expected to provide their own function callback in cases they want to sync(3p) data to disk via the reftable write options. But if no such function was provided we end up calling fsync(3p) directly, which may not even be available on some systems. While dropping the explicit call to fsync(3p) would work, it would lead to an unsafe default behaviour where a project may have forgotten to set up the callback function, and that could lead to potential data loss. So this is not a great solution. Instead, drop the callback function and make it mandatory for the project to define fsync(3p). In the case of Git, we can then easily inject our custom implementation via the "reftable-system.h" header so that we continue to use `fsync_component()`. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- reftable/stack.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'reftable/stack.c') diff --git a/reftable/stack.c b/reftable/stack.c index 1c9f21dfe1..fa87b46c37 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -29,13 +29,6 @@ static int stack_filename(struct reftable_buf *dest, struct reftable_stack *st, return 0; } -static int stack_fsync(const struct reftable_write_options *opts, int fd) -{ - if (opts->fsync) - return opts->fsync(fd); - return fsync(fd); -} - static ssize_t reftable_write_data(int fd, const void *data, size_t size) { size_t total_written = 0; @@ -69,7 +62,7 @@ static ssize_t fd_writer_write(void *arg, const void *data, size_t sz) static int fd_writer_flush(void *arg) { struct fd_writer *writer = arg; - return stack_fsync(writer->opts, writer->fd); + return fsync(writer->fd); } static int fd_read_lines(int fd, char ***namesp) @@ -812,7 +805,7 @@ int reftable_addition_commit(struct reftable_addition *add) goto done; } - err = stack_fsync(&add->stack->opts, add->tables_list_lock.fd); + err = fsync(add->tables_list_lock.fd); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -1480,7 +1473,7 @@ static int stack_compact_range(struct reftable_stack *st, goto done; } - err = stack_fsync(&st->opts, tables_list_lock.fd); + err = fsync(tables_list_lock.fd); if (err < 0) { err = REFTABLE_IO_ERROR; unlink(new_table_path.buf); -- cgit v1.3 From cb0882de1979522b2fc3dc4c3064b0ad21d50b06 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 2 Apr 2026 09:31:17 +0200 Subject: reftable/system: add abstraction to retrieve time in milliseconds We directly call gettimeofday(3p), which may not be available on some platforms. Provide the infrastructure to let projects easily use their own implementations of this function. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- reftable/stack.c | 27 ++++----------------------- reftable/system.c | 6 ++++++ reftable/system.h | 3 +++ 3 files changed, 13 insertions(+), 23 deletions(-) (limited to 'reftable/stack.c') diff --git a/reftable/stack.c b/reftable/stack.c index fa87b46c37..1fba96ddb3 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -365,45 +365,26 @@ done: return err; } -/* return negative if a before b. */ -static int tv_cmp(struct timeval *a, struct timeval *b) -{ - time_t diff = a->tv_sec - b->tv_sec; - int udiff = a->tv_usec - b->tv_usec; - - if (diff != 0) - return diff; - - return udiff; -} - static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st, int reuse_open) { char **names = NULL, **names_after = NULL; - struct timeval deadline; + uint64_t deadline; int64_t delay = 0; int tries = 0, err; int fd = -1; - err = gettimeofday(&deadline, NULL); - if (err < 0) - goto out; - deadline.tv_sec += 3; + deadline = reftable_time_ms() + 3000; while (1) { - struct timeval now; - - err = gettimeofday(&now, NULL); - if (err < 0) - goto out; + uint64_t now = reftable_time_ms(); /* * Only look at deadlines after the first few times. This * simplifies debugging in GDB. */ tries++; - if (tries > 3 && tv_cmp(&now, &deadline) >= 0) + if (tries > 3 && now >= deadline) goto out; fd = open(st->list_file, O_RDONLY); diff --git a/reftable/system.c b/reftable/system.c index 4d7e366b55..cd76e56be8 100644 --- a/reftable/system.c +++ b/reftable/system.c @@ -4,6 +4,7 @@ #include "basics.h" #include "reftable-error.h" #include "../lockfile.h" +#include "../trace.h" #include "../tempfile.h" #include "../write-or-die.h" @@ -137,3 +138,8 @@ int reftable_fsync(int fd) { return fsync_component(FSYNC_COMPONENT_REFERENCE, fd); } + +uint64_t reftable_time_ms(void) +{ + return getnanotime() / 1000000; +} diff --git a/reftable/system.h b/reftable/system.h index a7eb6acd4a..071bfa3d58 100644 --- a/reftable/system.h +++ b/reftable/system.h @@ -111,4 +111,7 @@ int flock_release(struct reftable_flock *l); */ int flock_commit(struct reftable_flock *l); +/* Report the time in milliseconds. */ +uint64_t reftable_time_ms(void); + #endif -- cgit v1.3