Merge branch 'jc/reftable-core-fsync'

The write codepath for the reftable data learned to honor
core.fsync configuration.

* jc/reftable-core-fsync:
  reftable/stack: fsync "tables.list" during compaction
  reftable: honor core.fsync
This commit is contained in:
Junio C Hamano 2024-02-06 14:31:20 -08:00
commit b6fdf9aafa
9 changed files with 54 additions and 19 deletions

View file

@ -42,7 +42,7 @@ static void write_test_table(struct strbuf *buf,
}
}
w = reftable_new_writer(&strbuf_add_void, buf, &opts);
w = reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts);
reftable_writer_set_limits(w, min, max);
for (i = 0; i < n; i++) {
@ -70,7 +70,7 @@ static void write_test_log_table(struct strbuf *buf,
.exact_log_message = 1,
};
struct reftable_writer *w = NULL;
w = reftable_new_writer(&strbuf_add_void, buf, &opts);
w = reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts);
reftable_writer_set_limits(w, update_index, update_index);
for (i = 0; i < n; i++) {
@ -412,7 +412,7 @@ static void test_default_write_opts(void)
struct reftable_write_options opts = { 0 };
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
struct reftable_ref_record rec = {
.refname = "master",

View file

@ -51,7 +51,7 @@ static void write_table(char ***names, struct strbuf *buf, int N,
.hash_id = hash_id,
};
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts);
struct reftable_ref_record ref = { NULL };
int i = 0, n;
struct reftable_log_record log = { NULL };
@ -130,7 +130,7 @@ static void test_log_buffer_size(void)
.message = "commit: 9\n",
} } };
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
/* This tests buffer extension for log compression. Must use a random
hash, to ensure that the compressed part is larger than the original.
@ -171,7 +171,7 @@ static void test_log_overflow(void)
.message = msg,
} } };
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
uint8_t hash1[GIT_SHA1_RAWSZ] = {1}, hash2[GIT_SHA1_RAWSZ] = { 2 };
@ -202,7 +202,7 @@ static void test_log_write_read(void)
struct reftable_block_source source = { NULL };
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
const struct reftable_stats *stats = NULL;
reftable_writer_set_limits(w, 0, N);
for (i = 0; i < N; i++) {
@ -294,7 +294,7 @@ static void test_log_zlib_corruption(void)
struct reftable_block_source source = { 0 };
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
const struct reftable_stats *stats = NULL;
uint8_t hash1[GIT_SHA1_RAWSZ] = { 1 };
uint8_t hash2[GIT_SHA1_RAWSZ] = { 2 };
@ -535,7 +535,7 @@ static void test_table_refs_for(int indexed)
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
struct reftable_iterator it = { NULL };
int j;
@ -628,7 +628,7 @@ static void test_write_empty_table(void)
struct reftable_write_options opts = { 0 };
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
struct reftable_block_source source = { NULL };
struct reftable_reader *rd = NULL;
struct reftable_ref_record rec = { NULL };
@ -666,7 +666,7 @@ static void test_write_object_id_min_length(void)
};
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
struct reftable_ref_record ref = {
.update_index = 1,
.value_type = REFTABLE_REF_VAL1,
@ -701,7 +701,7 @@ static void test_write_object_id_length(void)
};
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
struct reftable_ref_record ref = {
.update_index = 1,
.value_type = REFTABLE_REF_VAL1,
@ -735,7 +735,7 @@ static void test_write_empty_key(void)
struct reftable_write_options opts = { 0 };
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
struct reftable_ref_record ref = {
.refname = "",
.update_index = 1,
@ -758,7 +758,7 @@ static void test_write_key_order(void)
struct reftable_write_options opts = { 0 };
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
struct reftable_ref_record refs[2] = {
{
.refname = "b",
@ -801,7 +801,7 @@ static void test_write_multiple_indices(void)
struct reftable_reader *reader;
int err, i;
writer = reftable_new_writer(&strbuf_add_void, &writer_buf, &opts);
writer = reftable_new_writer(&strbuf_add_void, &noop_flush, &writer_buf, &opts);
reftable_writer_set_limits(writer, 1, 1);
for (i = 0; i < 100; i++) {
struct reftable_ref_record ref = {

View file

@ -30,7 +30,7 @@ static void test_conflict(void)
struct reftable_write_options opts = { 0 };
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
struct reftable_ref_record rec = {
.refname = "a/b",
.value_type = REFTABLE_REF_SYMREF,

View file

@ -88,6 +88,7 @@ struct reftable_stats {
/* reftable_new_writer creates a new writer */
struct reftable_writer *
reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t),
int (*flush_func)(void *),
void *writer_arg, struct reftable_write_options *opts);
/* Set the range of update indices for the records we will add. When writing a

View file

@ -8,6 +8,7 @@ license that can be found in the LICENSE file or at
#include "stack.h"
#include "../write-or-die.h"
#include "system.h"
#include "merged.h"
#include "reader.h"
@ -16,7 +17,6 @@ license that can be found in the LICENSE file or at
#include "reftable-record.h"
#include "reftable-merged.h"
#include "writer.h"
#include "tempfile.h"
static int stack_try_add(struct reftable_stack *st,
@ -47,6 +47,13 @@ static ssize_t reftable_fd_write(void *arg, const void *data, size_t sz)
return write_in_full(*fdp, data, sz);
}
static int reftable_fd_flush(void *arg)
{
int *fdp = (int *)arg;
return fsync_component(FSYNC_COMPONENT_REFERENCE, *fdp);
}
int reftable_new_stack(struct reftable_stack **dest, const char *dir,
struct reftable_write_options config)
{
@ -653,6 +660,9 @@ int reftable_addition_commit(struct reftable_addition *add)
goto done;
}
fsync_component_or_die(FSYNC_COMPONENT_REFERENCE, lock_file_fd,
get_tempfile_path(add->lock_file));
err = rename_tempfile(&add->lock_file, add->stack->list_file);
if (err < 0) {
err = REFTABLE_IO_ERROR;
@ -747,7 +757,7 @@ int reftable_addition_add(struct reftable_addition *add,
goto done;
}
}
wr = reftable_new_writer(reftable_fd_write, &tab_fd,
wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush, &tab_fd,
&add->stack->config);
err = write_table(wr, arg);
if (err < 0)
@ -839,7 +849,7 @@ static int stack_compact_locked(struct reftable_stack *st, int first, int last,
strbuf_addstr(temp_tab, ".temp.XXXXXX");
tab_fd = mkstemp(temp_tab->buf);
wr = reftable_new_writer(reftable_fd_write, &tab_fd, &st->config);
wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush, &tab_fd, &st->config);
err = stack_write_compact(st, wr, first, last, config);
if (err < 0)
@ -1116,6 +1126,14 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last,
unlink(new_table_path.buf);
goto done;
}
err = fsync_component(FSYNC_COMPONENT_REFERENCE, lock_file_fd);
if (err < 0) {
err = REFTABLE_IO_ERROR;
unlink(new_table_path.buf);
goto done;
}
err = close(lock_file_fd);
lock_file_fd = -1;
if (err < 0) {

View file

@ -20,3 +20,8 @@ ssize_t strbuf_add_void(void *b, const void *data, size_t sz)
strbuf_add(b, data, sz);
return sz;
}
int noop_flush(void *arg)
{
return 0;
}

View file

@ -56,4 +56,6 @@ void set_test_hash(uint8_t *p, int i);
*/
ssize_t strbuf_add_void(void *b, const void *data, size_t sz);
int noop_flush(void *);
#endif

View file

@ -121,6 +121,7 @@ static struct strbuf reftable_empty_strbuf = STRBUF_INIT;
struct reftable_writer *
reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t),
int (*flush_func)(void *),
void *writer_arg, struct reftable_write_options *opts)
{
struct reftable_writer *wp =
@ -136,6 +137,7 @@ reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t),
wp->write = writer_func;
wp->write_arg = writer_arg;
wp->opts = *opts;
wp->flush = flush_func;
writer_reinit_block_writer(wp, BLOCK_TYPE_REF);
return wp;
@ -603,6 +605,12 @@ int reftable_writer_close(struct reftable_writer *w)
put_be32(p, crc32(0, footer, p - footer));
p += 4;
err = w->flush(w->write_arg);
if (err < 0) {
err = REFTABLE_IO_ERROR;
goto done;
}
err = padded_write(w, footer, footer_size(writer_version(w)), 0);
if (err < 0)
goto done;

View file

@ -16,6 +16,7 @@ license that can be found in the LICENSE file or at
struct reftable_writer {
ssize_t (*write)(void *, const void *, size_t);
int (*flush)(void *);
void *write_arg;
int pending_padding;
struct strbuf last_key;