reftable/stack: register compacted tables as tempfiles
We do not register tables resulting from stack compaction with the tempfile API. Those tables will thus not be deleted in case Git gets killed. Refactor the code to register compacted tables as tempfiles. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Mar 7, 2024 at 14:10 UTC
60c4c425155c61a081cc035240ee649aa2cb2e37
1 file changed
+30
-24
reftable/stack.c
+30
-24
@@ -827,51 +827,56 @@ uint64_t reftable_stack_next_update_index(struct reftable_stack *st)
827
828
static int stack_compact_locked(struct reftable_stack *st,
829
size_t first, size_t last,
830
- struct strbuf *temp_tab,
831
- struct reftable_log_expiry_config *config)
830
+ struct reftable_log_expiry_config *config,
831
+ struct tempfile **tab_file_out)
832
{
833
struct strbuf next_name = STRBUF_INIT;
834
- int tab_fd = -1;
834
+ struct strbuf tab_file_path = STRBUF_INIT;
835
struct reftable_writer *wr = NULL;
836
- int err = 0;
836
+ struct tempfile *tab_file;
837
+ int tab_fd, err = 0;
838
839
format_name(&next_name,
840
reftable_reader_min_update_index(st->readers[first]),
841
reftable_reader_max_update_index(st->readers[last]));
842
+ stack_filename(&tab_file_path, st, next_name.buf);
843
+ strbuf_addstr(&tab_file_path, ".temp.XXXXXX");
844
842
- stack_filename(temp_tab, st, next_name.buf);
843
- strbuf_addstr(temp_tab, ".temp.XXXXXX");
845
+ tab_file = mks_tempfile(tab_file_path.buf);
846
+ if (!tab_file) {
847
+ err = REFTABLE_IO_ERROR;
848
+ goto done;
849
+ }
850
+ tab_fd = get_tempfile_fd(tab_file);
851
845
- tab_fd = mkstemp(temp_tab->buf);
852
if (st->config.default_permissions &&
847
- chmod(temp_tab->buf, st->config.default_permissions) < 0) {
853
+ chmod(get_tempfile_path(tab_file), st->config.default_permissions) < 0) {
854
err = REFTABLE_IO_ERROR;
855
goto done;
856
}
857
852
- wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush, &tab_fd, &st->config);
853
-
858
+ wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush,
859
+ &tab_fd, &st->config);
860
err = stack_write_compact(st, wr, first, last, config);
861
if (err < 0)
862
goto done;
863
+
864
err = reftable_writer_close(wr);
865
if (err < 0)
866
goto done;
867
861
- err = close(tab_fd);
862
- tab_fd = 0;
868
+ err = close_tempfile_gently(tab_file);
869
+ if (err < 0)
870
+ goto done;
871
+
872
+ *tab_file_out = tab_file;
873
+ tab_file = NULL;
874
875
done:
876
+ delete_tempfile(&tab_file);
877
reftable_writer_free(wr);
866
- if (tab_fd > 0) {
867
- close(tab_fd);
868
- tab_fd = 0;
869
- }
870
- if (err != 0 && temp_tab->len > 0) {
871
- unlink(temp_tab->buf);
872
- strbuf_release(temp_tab);
873
- }
878
strbuf_release(&next_name);
879
+ strbuf_release(&tab_file_path);
880
return err;
881
}
882
@@ -979,12 +984,12 @@ static int stack_compact_range(struct reftable_stack *st,
984
struct reftable_log_expiry_config *expiry)
985
{
986
struct strbuf tables_list_buf = STRBUF_INIT;
982
- struct strbuf new_table_temp_path = STRBUF_INIT;
987
struct strbuf new_table_name = STRBUF_INIT;
988
struct strbuf new_table_path = STRBUF_INIT;
989
struct strbuf table_name = STRBUF_INIT;
990
struct lock_file tables_list_lock = LOCK_INIT;
991
struct lock_file *table_locks = NULL;
992
+ struct tempfile *new_table = NULL;
993
int is_empty_table = 0, err = 0;
994
size_t i;
995
@@ -1059,7 +1064,7 @@ static int stack_compact_range(struct reftable_stack *st,
1064
* these tables may end up with an empty new table in case tombstones
1065
* end up cancelling out all refs in that range.
1066
*/
1062
- err = stack_compact_locked(st, first, last, &new_table_temp_path, expiry);
1067
+ err = stack_compact_locked(st, first, last, expiry, &new_table);
1068
if (err < 0) {
1069
if (err != REFTABLE_EMPTY_TABLE_ERROR)
1070
goto done;
@@ -1099,7 +1104,7 @@ static int stack_compact_range(struct reftable_stack *st,
1104
strbuf_addstr(&new_table_name, ".ref");
1105
stack_filename(&new_table_path, st, new_table_name.buf);
1106
1102
- err = rename(new_table_temp_path.buf, new_table_path.buf);
1107
+ err = rename_tempfile(&new_table, new_table_path.buf);
1108
if (err < 0) {
1109
err = REFTABLE_IO_ERROR;
1110
goto done;
@@ -1166,9 +1171,10 @@ done:
1171
rollback_lock_file(&table_locks[i - first]);
1172
reftable_free(table_locks);
1173
1174
+ delete_tempfile(&new_table);
1175
strbuf_release(&new_table_name);
1176
strbuf_release(&new_table_path);
1171
- strbuf_release(&new_table_temp_path);
1177
+
1178
strbuf_release(&tables_list_buf);
1179
strbuf_release(&table_name);
1180
return err;