git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 4/7] reftable/stack: stop using `fsync_component()` directly

From
Patrick Steinhardt <ps@pks.im>
Date
Nov 18, 2024, 15:34 UTC
Message-ID
<7782652b97545f95c83aef08786c70384e5cfa52.1731943954.git.ps@pks.im>
In-Reply-To
<cover.1731943954.git.ps@pks.im>

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>
---
 refs/reftable-backend.c    |  7 ++++++
 reftable/reftable-writer.h |  6 +++++
 reftable/stack.c           | 49 +++++++++++++++++++++++++-------------
 3 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index 7d86d920970..2e774176eda 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 211860d08a4..c85ef5a5bd1 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 9ae716ff375..c67bdd952ca 100644
--- a/reftable/stack.c
+++ b/reftable/stack.c
@@ -8,7 +8,6 @@ license that can be found in the LICENSE file or at
 
 #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);
-- 
2.47.0.274.g962d0b743d.dirty
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 38 of 43 in “reftable: stop using Git subsystems”
  1. 0/7 reftable: stop using Git subsystemsPatrick Steinhardt, Oct 23, 2024
  2. 1/7 reftable/system: move "dir.h" to its only userPatrick Steinhardt, Oct 23, 2024
  3. Eric SunshineOct 24, 2024
  4. 2/7 reftable: explicitly handle hash format IDsPatrick Steinhardt, Oct 23, 2024
  5. Justin ToblerNov 7, 2024
  6. 3/7 reftable/system: stop depending on "hash.h"Patrick Steinhardt, Oct 23, 2024
  7. Justin ToblerNov 8, 2024
  8. Patrick SteinhardtNov 8, 2024
  9. 4/7 reftable/stack: stop using `fsync_component()` directlyPatrick Steinhardt, Oct 23, 2024
  10. Justin ToblerNov 8, 2024
  11. Patrick SteinhardtNov 8, 2024
  12. 5/7 reftable/system: provide thin wrapper for tempfile subsystemPatrick Steinhardt, Oct 23, 2024
  13. 6/7 reftable/stack: drop only use of `get_locked_file_path()`Patrick Steinhardt, Oct 23, 2024
  14. 7/7 reftable/system: provide thin wrapper for lockfile subsystemPatrick Steinhardt, Oct 23, 2024
  15. 0/7 reftable: stop using Git subsystemsPatrick Steinhardt, Nov 8, 2024
  16. 1/7 reftable/system: move "dir.h" to its only userPatrick Steinhardt, Nov 8, 2024
  17. 2/7 reftable: explicitly handle hash format IDsPatrick Steinhardt, Nov 8, 2024
  18. karthik nayakNov 18, 2024
  19. 3/7 reftable/system: stop depending on "hash.h"Patrick Steinhardt, Nov 8, 2024
  20. Junio C HamanoNov 12, 2024
  21. karthik nayakNov 18, 2024
  22. 4/7 reftable/stack: stop using `fsync_component()` directlyPatrick Steinhardt, Nov 8, 2024
  23. karthik nayakNov 18, 2024
  24. Patrick SteinhardtNov 18, 2024
  25. 5/7 reftable/system: provide thin wrapper for tempfile subsystemPatrick Steinhardt, Nov 8, 2024
  26. karthik nayakNov 18, 2024
  27. karthik nayakNov 18, 2024
  28. 6/7 reftable/stack: drop only use of `get_locked_file_path()`Patrick Steinhardt, Nov 8, 2024
  29. 7/7 reftable/system: provide thin wrapper for lockfile subsystemPatrick Steinhardt, Nov 8, 2024
  30. Justin ToblerNov 8, 2024
  31. Junio C HamanoNov 11, 2024
  32. karthik nayakNov 18, 2024
  33. Patrick SteinhardtNov 18, 2024
  34. 0/7 reftable: stop using Git subsystemsPatrick Steinhardt, Nov 18, 2024
  35. 1/7 reftable/system: move "dir.h" to its only userPatrick Steinhardt, Nov 18, 2024
  36. 2/7 reftable: explicitly handle hash format IDsPatrick Steinhardt, Nov 18, 2024
  37. 3/7 reftable/system: stop depending on "hash.h"Patrick Steinhardt, Nov 18, 2024
  38. 4/7 reftable/stack: stop using `fsync_component()` directlyPatrick Steinhardt, Nov 18, 2024
  39. 5/7 reftable/system: provide thin wrapper for tempfile subsystemPatrick Steinhardt, Nov 18, 2024
  40. 6/7 reftable/stack: drop only use of `get_locked_file_path()`Patrick Steinhardt, Nov 18, 2024
  41. 7/7 reftable/system: provide thin wrapper for lockfile subsystemPatrick Steinhardt, Nov 18, 2024
  42. karthik nayakNov 19, 2024
  43. Junio C HamanoNov 20, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.