reftable/stack: stop using `fsync_component()` directly

We're executing `fsync_component()` directly in the reftable library so that we can fsync data to disk depending on "core.fsync". But as we're in the process of converting the reftable library to become standalone we cannot use that function in the library anymore. Refactor the code such that users of the library can inject a custom fsync function via the write options. This allows us to get rid of the dependency on "write-or-die.h". Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Nov 18, 2024 at 16:34 UTC 86b770b0bbf1aba3c8e43401936258c58648703a
3 files changed +45 -17
refs/reftable-backend.c
+7
@@ -24,6 +24,7 @@
24 #include "../setup.h"
25 #include "../strmap.h"
26 #include "../trace2.h"
27 +#include "../write-or-die.h"
28 #include "parse.h"
29 #include "refs-internal.h"
30
@@ -273,6 +274,11 @@ static int reftable_be_config(const char *var, const char *value,
274 return 0;
275 }
276
277 +static int reftable_be_fsync(int fd)
278 +{
279 + return fsync_component(FSYNC_COMPONENT_REFERENCE, fd);
280 +}
281 +
282 static struct ref_store *reftable_be_init(struct repository *repo,
283 const char *gitdir,
284 unsigned int store_flags)
@@ -304,6 +310,7 @@ static struct ref_store *reftable_be_init(struct repository *repo,
310 refs->write_options.disable_auto_compact =
311 !git_env_bool("GIT_TEST_REFTABLE_AUTOCOMPACTION", 1);
312 refs->write_options.lock_timeout_ms = 100;
313 + refs->write_options.fsync = reftable_be_fsync;
314
315 git_config(reftable_be_config, &refs->write_options);
316
reftable/reftable-writer.h
+6
@@ -62,6 +62,12 @@ struct reftable_write_options {
62 * negative value will cause us to block indefinitely.
63 */
64 long lock_timeout_ms;
65 +
66 + /*
67 + * Optional callback used to fsync files to disk. Falls back to using
68 + * fsync(3P) when unset.
69 + */
70 + int (*fsync)(int fd);
71 };
72
73 /* reftable_block_stats holds statistics for a single block type */
reftable/stack.c
+32 -17
@@ -8,7 +8,6 @@ https://developers.google.com/open-source/licenses/bsd
8
9 #include "stack.h"
10
11 -#include "../write-or-die.h"
11 #include "system.h"
12 #include "constants.h"
13 #include "merged.h"
@@ -43,17 +42,28 @@ static int stack_filename(struct reftable_buf *dest, struct reftable_stack *st,
42 return 0;
43 }
44
46 -static ssize_t reftable_fd_write(void *arg, const void *data, size_t sz)
45 +static int stack_fsync(const struct reftable_write_options *opts, int fd)
46 {
48 - int *fdp = (int *)arg;
49 - return write_in_full(*fdp, data, sz);
47 + if (opts->fsync)
48 + return opts->fsync(fd);
49 + return fsync(fd);
50 }
51
52 -static int reftable_fd_flush(void *arg)
52 +struct fd_writer {
53 + const struct reftable_write_options *opts;
54 + int fd;
55 +};
56 +
57 +static ssize_t fd_writer_write(void *arg, const void *data, size_t sz)
58 {
54 - int *fdp = (int *)arg;
59 + struct fd_writer *writer = arg;
60 + return write_in_full(writer->fd, data, sz);
61 +}
62
56 - return fsync_component(FSYNC_COMPONENT_REFERENCE, *fdp);
63 +static int fd_writer_flush(void *arg)
64 +{
65 + struct fd_writer *writer = arg;
66 + return stack_fsync(writer->opts, writer->fd);
67 }
68
69 int reftable_new_stack(struct reftable_stack **dest, const char *dir,
@@ -765,7 +775,7 @@ int reftable_addition_commit(struct reftable_addition *add)
775 goto done;
776 }
777
768 - err = fsync_component(FSYNC_COMPONENT_REFERENCE, lock_file_fd);
778 + err = stack_fsync(&add->stack->opts, lock_file_fd);
779 if (err < 0) {
780 err = REFTABLE_IO_ERROR;
781 goto done;
@@ -858,8 +868,10 @@ int reftable_addition_add(struct reftable_addition *add,
868 struct reftable_buf next_name = REFTABLE_BUF_INIT;
869 struct reftable_writer *wr = NULL;
870 struct tempfile *tab_file = NULL;
871 + struct fd_writer writer = {
872 + .opts = &add->stack->opts,
873 + };
874 int err = 0;
862 - int tab_fd;
875
876 reftable_buf_reset(&next_name);
877
@@ -887,10 +899,10 @@ int reftable_addition_add(struct reftable_addition *add,
899 goto done;
900 }
901 }
890 - tab_fd = get_tempfile_fd(tab_file);
902
892 - err = reftable_writer_new(&wr, reftable_fd_write, reftable_fd_flush,
893 - &tab_fd, &add->stack->opts);
903 + writer.fd = get_tempfile_fd(tab_file);
904 + err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush,
905 + &writer, &add->stack->opts);
906 if (err < 0)
907 goto done;
908
@@ -973,8 +985,11 @@ static int stack_compact_locked(struct reftable_stack *st,
985 struct reftable_buf next_name = REFTABLE_BUF_INIT;
986 struct reftable_buf tab_file_path = REFTABLE_BUF_INIT;
987 struct reftable_writer *wr = NULL;
988 + struct fd_writer writer= {
989 + .opts = &st->opts,
990 + };
991 struct tempfile *tab_file;
977 - int tab_fd, err = 0;
992 + int err = 0;
993
994 err = format_name(&next_name, reftable_reader_min_update_index(st->readers[first]),
995 reftable_reader_max_update_index(st->readers[last]));
@@ -994,7 +1009,6 @@ static int stack_compact_locked(struct reftable_stack *st,
1009 err = REFTABLE_IO_ERROR;
1010 goto done;
1011 }
997 - tab_fd = get_tempfile_fd(tab_file);
1012
1013 if (st->opts.default_permissions &&
1014 chmod(get_tempfile_path(tab_file), st->opts.default_permissions) < 0) {
@@ -1002,8 +1016,9 @@ static int stack_compact_locked(struct reftable_stack *st,
1016 goto done;
1017 }
1018
1005 - err = reftable_writer_new(&wr, reftable_fd_write, reftable_fd_flush,
1006 - &tab_fd, &st->opts);
1019 + writer.fd = get_tempfile_fd(tab_file);
1020 + err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush,
1021 + &writer, &st->opts);
1022 if (err < 0)
1023 goto done;
1024
@@ -1460,7 +1475,7 @@ static int stack_compact_range(struct reftable_stack *st,
1475 goto done;
1476 }
1477
1463 - err = fsync_component(FSYNC_COMPONENT_REFERENCE, get_lock_file_fd(&tables_list_lock));
1478 + err = stack_fsync(&st->opts, get_lock_file_fd(&tables_list_lock));
1479 if (err < 0) {
1480 err = REFTABLE_IO_ERROR;
1481 unlink(new_table_path.buf);