aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--refs/reftable-backend.c7
-rw-r--r--reftable/reftable-writer.h6
-rw-r--r--reftable/stack.c49
3 files changed, 45 insertions, 17 deletions
diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index 7d86d92097..2e774176ed 100644
--- a/refs/reftable-backend.c
+++ b/refs/reftable-backend.c
@@ -24,6 +24,7 @@
#include "../setup.h"
#include "../strmap.h"
#include "../trace2.h"
+#include "../write-or-die.h"
#include "parse.h"
#include "refs-internal.h"
@@ -273,6 +274,11 @@ static int reftable_be_config(const char *var, const char *value,
return 0;
}
+static int reftable_be_fsync(int fd)
+{
+ return fsync_component(FSYNC_COMPONENT_REFERENCE, fd);
+}
+
static struct ref_store *reftable_be_init(struct repository *repo,
const char *gitdir,
unsigned int store_flags)
@@ -304,6 +310,7 @@ static struct ref_store *reftable_be_init(struct repository *repo,
refs->write_options.disable_auto_compact =
!git_env_bool("GIT_TEST_REFTABLE_AUTOCOMPACTION", 1);
refs->write_options.lock_timeout_ms = 100;
+ refs->write_options.fsync = reftable_be_fsync;
git_config(reftable_be_config, &refs->write_options);
diff --git a/reftable/reftable-writer.h b/reftable/reftable-writer.h
index 211860d08a..c85ef5a5bd 100644
--- a/reftable/reftable-writer.h
+++ b/reftable/reftable-writer.h
@@ -62,6 +62,12 @@ struct reftable_write_options {
* negative value will cause us to block indefinitely.
*/
long lock_timeout_ms;
+
+ /*
+ * Optional callback used to fsync files to disk. Falls back to using
+ * fsync(3P) when unset.
+ */
+ int (*fsync)(int fd);
};
/* reftable_block_stats holds statistics for a single block type */
diff --git a/reftable/stack.c b/reftable/stack.c
index 9ae716ff37..c67bdd952c 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"
@@ -43,17 +42,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,
@@ -765,7 +775,7 @@ int reftable_addition_commit(struct reftable_addition *add)
goto done;
}
- err = fsync_component(FSYNC_COMPONENT_REFERENCE, lock_file_fd);
+ err = stack_fsync(&add->stack->opts, lock_file_fd);
if (err < 0) {
err = REFTABLE_IO_ERROR;
goto done;
@@ -858,8 +868,10 @@ int reftable_addition_add(struct reftable_addition *add,
struct reftable_buf next_name = REFTABLE_BUF_INIT;
struct reftable_writer *wr = NULL;
struct tempfile *tab_file = NULL;
+ struct fd_writer writer = {
+ .opts = &add->stack->opts,
+ };
int err = 0;
- int tab_fd;
reftable_buf_reset(&next_name);
@@ -887,10 +899,10 @@ int reftable_addition_add(struct reftable_addition *add,
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 = get_tempfile_fd(tab_file);
+ err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush,
+ &writer, &add->stack->opts);
if (err < 0)
goto done;
@@ -973,8 +985,11 @@ static int stack_compact_locked(struct reftable_stack *st,
struct reftable_buf next_name = REFTABLE_BUF_INIT;
struct reftable_buf tab_file_path = REFTABLE_BUF_INIT;
struct reftable_writer *wr = NULL;
+ struct fd_writer writer= {
+ .opts = &st->opts,
+ };
struct tempfile *tab_file;
- int tab_fd, err = 0;
+ int err = 0;
err = format_name(&next_name, reftable_reader_min_update_index(st->readers[first]),
reftable_reader_max_update_index(st->readers[last]));
@@ -994,7 +1009,6 @@ static int stack_compact_locked(struct reftable_stack *st,
err = REFTABLE_IO_ERROR;
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) {
@@ -1002,8 +1016,9 @@ static int stack_compact_locked(struct reftable_stack *st,
goto done;
}
- err = reftable_writer_new(&wr, reftable_fd_write, reftable_fd_flush,
- &tab_fd, &st->opts);
+ writer.fd = get_tempfile_fd(tab_file);
+ err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush,
+ &writer, &st->opts);
if (err < 0)
goto done;
@@ -1460,7 +1475,7 @@ 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, get_lock_file_fd(&tables_list_lock));
if (err < 0) {
err = REFTABLE_IO_ERROR;
unlink(new_table_path.buf);