Skip to content

Commit

Permalink
core.fsync: new option to harden the index
Browse files Browse the repository at this point in the history
This commit introduces the new ability for the user to harden
the index. In the event of a system crash, the index must be
durable for the user to actually find a file that has been added
to the repo and then deleted from the working tree.

We use the presence of the COMMIT_LOCK flag and absence of the
alternate_index_output as a proxy for determining whether we're
updating the persistent index of the repo or some temporary
index. We don't sync these temporary indexes.

Signed-off-by: Neeraj Singh <neerajsi@microsoft.com>
  • Loading branch information
neerajsi-msft committed Dec 6, 2021
1 parent b4851e6 commit eb38385
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 7 deletions.
1 change: 1 addition & 0 deletions Documentation/config/core.txt
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ core.fsync::
* `pack` hardens objects added to the repo in packfile form.
* `pack-metadata` hardens packfile bitmaps and indexes.
* `commit-graph` hardens the commit graph file.
* `index` hardens the index when it is modified.
* `objects` is an aggregate option that includes `loose-objects`, `pack`,
`pack-metadata`, and `commit-graph`.
* `default` is an aggregate option that is equivalent to `objects,-loose-object`
Expand Down
4 changes: 3 additions & 1 deletion cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,7 @@ enum fsync_component {
FSYNC_COMPONENT_PACK = 1 << 1,
FSYNC_COMPONENT_PACK_METADATA = 1 << 2,
FSYNC_COMPONENT_COMMIT_GRAPH = 1 << 3,
FSYNC_COMPONENT_INDEX = 1 << 4,
};

#define FSYNC_COMPONENTS_DEFAULT (FSYNC_COMPONENT_PACK | \
Expand All @@ -1010,7 +1011,8 @@ enum fsync_component {
#define FSYNC_COMPONENTS_ALL (FSYNC_COMPONENT_LOOSE_OBJECT | \
FSYNC_COMPONENT_PACK | \
FSYNC_COMPONENT_PACK_METADATA | \
FSYNC_COMPONENT_COMMIT_GRAPH)
FSYNC_COMPONENT_COMMIT_GRAPH | \
FSYNC_COMPONENT_INDEX)


/*
Expand Down
1 change: 1 addition & 0 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,7 @@ static const struct fsync_component_entry {
{ "pack", FSYNC_COMPONENT_PACK },
{ "pack-metadata", FSYNC_COMPONENT_PACK_METADATA },
{ "commit-graph", FSYNC_COMPONENT_COMMIT_GRAPH },
{ "index", FSYNC_COMPONENT_INDEX },
{ "objects", FSYNC_COMPONENTS_OBJECTS },
{ "default", FSYNC_COMPONENTS_DEFAULT },
{ "all", FSYNC_COMPONENTS_ALL },
Expand Down
19 changes: 13 additions & 6 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -2816,7 +2816,7 @@ static int record_ieot(void)
* rely on it.
*/
static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
int strip_extensions)
int strip_extensions, unsigned flags)
{
uint64_t start = getnanotime();
struct hashfile *f;
Expand All @@ -2830,6 +2830,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;
int drop_cache_tree = istate->drop_cache_tree;
off_t offset;
int csum_fsync_flag;
int ieot_entries = 1;
struct index_entry_offset_table *ieot = NULL;
int nr, nr_threads;
Expand Down Expand Up @@ -3060,7 +3061,13 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
return -1;
}

finalize_hashfile(f, istate->oid.hash, FSYNC_COMPONENT_NONE, CSUM_HASH_IN_STREAM);
csum_fsync_flag = 0;
if (!alternate_index_output && (flags & COMMIT_LOCK))
csum_fsync_flag = CSUM_FSYNC;

finalize_hashfile(f, istate->oid.hash, FSYNC_COMPONENT_INDEX,
CSUM_HASH_IN_STREAM | csum_fsync_flag);

if (close_tempfile_gently(tempfile)) {
error(_("could not close '%s'"), get_tempfile_path(tempfile));
return -1;
Expand Down Expand Up @@ -3115,7 +3122,7 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
*/
trace2_region_enter_printf("index", "do_write_index", the_repository,
"%s", get_lock_file_path(lock));
ret = do_write_index(istate, lock->tempfile, 0);
ret = do_write_index(istate, lock->tempfile, 0, flags);
trace2_region_leave_printf("index", "do_write_index", the_repository,
"%s", get_lock_file_path(lock));

Expand Down Expand Up @@ -3209,7 +3216,7 @@ static int clean_shared_index_files(const char *current_hex)
}

static int write_shared_index(struct index_state *istate,
struct tempfile **temp)
struct tempfile **temp, unsigned flags)
{
struct split_index *si = istate->split_index;
int ret, was_full = !istate->sparse_index;
Expand All @@ -3219,7 +3226,7 @@ static int write_shared_index(struct index_state *istate,

trace2_region_enter_printf("index", "shared/do_write_index",
the_repository, "%s", get_tempfile_path(*temp));
ret = do_write_index(si->base, *temp, 1);
ret = do_write_index(si->base, *temp, 1, flags);
trace2_region_leave_printf("index", "shared/do_write_index",
the_repository, "%s", get_tempfile_path(*temp));

Expand Down Expand Up @@ -3328,7 +3335,7 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
ret = do_write_locked_index(istate, lock, flags);
goto out;
}
ret = write_shared_index(istate, &temp);
ret = write_shared_index(istate, &temp, flags);

saved_errno = errno;
if (is_tempfile_active(temp))
Expand Down

0 comments on commit eb38385

Please sign in to comment.