]> git.ipfire.org Git - thirdparty/git.git/commitdiff
core.fsync: new option to harden the index
authorNeeraj Singh <neerajsi@microsoft.com>
Thu, 10 Mar 2022 22:43:23 +0000 (22:43 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 10 Mar 2022 23:10:22 +0000 (15:10 -0800)
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
cache.h
config.c
read-cache.c

diff --git a/cache.h b/cache.h
index 7ac1959258d5b02e82dec11939ee3fdf3c02a206..e08eeac6c15d2784611a91846c0f16044a686947 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1004,6 +1004,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 | \
index 94a4598b5fcf49801f7537e80738835166c14765..80f33c91982f36196c0da9addc8dc95c9431fd97 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1331,6 +1331,7 @@ static const struct fsync_component_name {
        { "pack", FSYNC_COMPONENT_PACK },
        { "pack-metadata", FSYNC_COMPONENT_PACK_METADATA },
        { "commit-graph", FSYNC_COMPONENT_COMMIT_GRAPH },
+       { "index", FSYNC_COMPONENT_INDEX },
 };
 
 static enum fsync_component parse_fsync_components(const char *var, const char *string)
index df869691fd4fd00514eef3650cf234d6b3d276ee..7683b6792583a7cc64f5d7ab6fc22c53526ab1c5 100644 (file)
@@ -2842,7 +2842,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;
@@ -2856,6 +2856,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;
@@ -3089,7 +3090,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;
@@ -3144,7 +3151,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));
 
@@ -3238,7 +3245,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;
@@ -3248,7 +3255,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));
 
@@ -3357,7 +3364,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))