]> git.ipfire.org Git - thirdparty/git.git/blobdiff - reftable/stack.c
Merge branch 'jc/orphan-unborn' into maint-2.43
[thirdparty/git.git] / reftable / stack.c
index f0cadad490e08dc1dae00fa4564635d74f49c45a..16bab82063d2b3e228abe05b3a8a26ffd310767c 100644 (file)
@@ -17,6 +17,8 @@ https://developers.google.com/open-source/licenses/bsd
 #include "reftable-merged.h"
 #include "writer.h"
 
+#include "tempfile.h"
+
 static int stack_try_add(struct reftable_stack *st,
                         int (*write_table)(struct reftable_writer *wr,
                                            void *arg),
@@ -204,6 +206,7 @@ static int reftable_stack_reload_once(struct reftable_stack *st, char **names,
                reftable_calloc(sizeof(struct reftable_table) * names_len);
        int new_readers_len = 0;
        struct reftable_merged_table *new_merged = NULL;
+       struct strbuf table_path = STRBUF_INIT;
        int i;
 
        while (*names) {
@@ -223,13 +226,10 @@ static int reftable_stack_reload_once(struct reftable_stack *st, char **names,
 
                if (!rd) {
                        struct reftable_block_source src = { NULL };
-                       struct strbuf table_path = STRBUF_INIT;
                        stack_filename(&table_path, st, name);
 
                        err = reftable_block_source_from_file(&src,
                                                              table_path.buf);
-                       strbuf_release(&table_path);
-
                        if (err < 0)
                                goto done;
 
@@ -267,16 +267,13 @@ static int reftable_stack_reload_once(struct reftable_stack *st, char **names,
        for (i = 0; i < cur_len; i++) {
                if (cur[i]) {
                        const char *name = reader_name(cur[i]);
-                       struct strbuf filename = STRBUF_INIT;
-                       stack_filename(&filename, st, name);
+                       stack_filename(&table_path, st, name);
 
                        reader_close(cur[i]);
                        reftable_reader_free(cur[i]);
 
                        /* On Windows, can only unlink after closing. */
-                       unlink(filename.buf);
-
-                       strbuf_release(&filename);
+                       unlink(table_path.buf);
                }
        }
 
@@ -288,6 +285,7 @@ done:
        reftable_free(new_readers);
        reftable_free(new_tables);
        reftable_free(cur);
+       strbuf_release(&table_path);
        return err;
 }
 
@@ -436,7 +434,7 @@ int reftable_stack_add(struct reftable_stack *st,
 static void format_name(struct strbuf *dest, uint64_t min, uint64_t max)
 {
        char buf[100];
-       uint32_t rnd = (uint32_t)rand();
+       uint32_t rnd = (uint32_t)git_rand();
        snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64 "-%08x",
                 min, max, rnd);
        strbuf_reset(dest);
@@ -444,8 +442,7 @@ static void format_name(struct strbuf *dest, uint64_t min, uint64_t max)
 }
 
 struct reftable_addition {
-       int lock_file_fd;
-       struct strbuf lock_file_name;
+       struct tempfile *lock_file;
        struct reftable_stack *stack;
 
        char **new_tables;
@@ -453,24 +450,19 @@ struct reftable_addition {
        uint64_t next_update_index;
 };
 
-#define REFTABLE_ADDITION_INIT                \
-       {                                     \
-               .lock_file_name = STRBUF_INIT \
-       }
+#define REFTABLE_ADDITION_INIT {0}
 
 static int reftable_stack_init_addition(struct reftable_addition *add,
                                        struct reftable_stack *st)
 {
+       struct strbuf lock_file_name = STRBUF_INIT;
        int err = 0;
        add->stack = st;
 
-       strbuf_reset(&add->lock_file_name);
-       strbuf_addstr(&add->lock_file_name, st->list_file);
-       strbuf_addstr(&add->lock_file_name, ".lock");
+       strbuf_addf(&lock_file_name, "%s.lock", st->list_file);
 
-       add->lock_file_fd = open(add->lock_file_name.buf,
-                                O_EXCL | O_CREAT | O_WRONLY, 0666);
-       if (add->lock_file_fd < 0) {
+       add->lock_file = create_tempfile(lock_file_name.buf);
+       if (!add->lock_file) {
                if (errno == EEXIST) {
                        err = REFTABLE_LOCK_ERROR;
                } else {
@@ -479,7 +471,7 @@ static int reftable_stack_init_addition(struct reftable_addition *add,
                goto done;
        }
        if (st->config.default_permissions) {
-               if (chmod(add->lock_file_name.buf, st->config.default_permissions) < 0) {
+               if (chmod(add->lock_file->filename.buf, st->config.default_permissions) < 0) {
                        err = REFTABLE_IO_ERROR;
                        goto done;
                }
@@ -499,6 +491,7 @@ done:
        if (err) {
                reftable_addition_close(add);
        }
+       strbuf_release(&lock_file_name);
        return err;
 }
 
@@ -516,15 +509,7 @@ static void reftable_addition_close(struct reftable_addition *add)
        add->new_tables = NULL;
        add->new_tables_len = 0;
 
-       if (add->lock_file_fd > 0) {
-               close(add->lock_file_fd);
-               add->lock_file_fd = 0;
-       }
-       if (add->lock_file_name.len > 0) {
-               unlink(add->lock_file_name.buf);
-               strbuf_release(&add->lock_file_name);
-       }
-
+       delete_tempfile(&add->lock_file);
        strbuf_release(&nm);
 }
 
@@ -540,8 +525,10 @@ void reftable_addition_destroy(struct reftable_addition *add)
 int reftable_addition_commit(struct reftable_addition *add)
 {
        struct strbuf table_list = STRBUF_INIT;
+       int lock_file_fd = get_tempfile_fd(add->lock_file);
        int i = 0;
        int err = 0;
+
        if (add->new_tables_len == 0)
                goto done;
 
@@ -554,28 +541,20 @@ int reftable_addition_commit(struct reftable_addition *add)
                strbuf_addstr(&table_list, "\n");
        }
 
-       err = write_in_full(add->lock_file_fd, table_list.buf, table_list.len);
+       err = write_in_full(lock_file_fd, table_list.buf, table_list.len);
        strbuf_release(&table_list);
        if (err < 0) {
                err = REFTABLE_IO_ERROR;
                goto done;
        }
 
-       err = close(add->lock_file_fd);
-       add->lock_file_fd = 0;
-       if (err < 0) {
-               err = REFTABLE_IO_ERROR;
-               goto done;
-       }
-
-       err = rename(add->lock_file_name.buf, add->stack->list_file);
+       err = rename_tempfile(&add->lock_file, add->stack->list_file);
        if (err < 0) {
                err = REFTABLE_IO_ERROR;
                goto done;
        }
 
        /* success, no more state to clean up. */
-       strbuf_release(&add->lock_file_name);
        for (i = 0; i < add->new_tables_len; i++) {
                reftable_free(add->new_tables[i]);
        }
@@ -584,6 +563,12 @@ int reftable_addition_commit(struct reftable_addition *add)
        add->new_tables_len = 0;
 
        err = reftable_stack_reload(add->stack);
+       if (err)
+               goto done;
+
+       if (!add->stack->disable_auto_compact)
+               err = reftable_stack_auto_compact(add->stack);
+
 done:
        reftable_addition_close(add);
        return err;