diff options
author | Alex Vandiver <alexmv@dropbox.com> | 2017-10-27 16:26:37 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-11-01 13:28:20 +0900 |
commit | ba1b9caca69909b3c048bda1bbfab4fefb070bff (patch) | |
tree | ef919abbc8d153cd613c69ca6b394df277d06294 | |
parent | bd76afd13dcee4a07ba5136704ac8592af26d332 (diff) | |
download | git-ba1b9caca69909b3c048bda1bbfab4fefb070bff.tar.gz |
fsmonitor: delay updating state until after split index is merged
If the fsmonitor extension is used in conjunction with the split index
extension, the set of entries in the index when it is first loaded is
only a subset of the real index. This leads to only the non-"base"
index being marked as CE_FSMONITOR_VALID.
Delay the expansion of the ewah bitmap until after tweak_split_index
has been called to merge in the base index as well.
The new fsmonitor_dirty is kept from being leaked by dint of being
cleaned up in post_read_index_from, which is guaranteed to be called
after do_read_index in read_index_from.
Signed-off-by: Alex Vandiver <alexmv@dropbox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | cache.h | 1 | ||||
-rw-r--r-- | fsmonitor.c | 40 |
2 files changed, 25 insertions, 16 deletions
@@ -347,6 +347,7 @@ struct index_state { unsigned char sha1[20]; struct untracked_cache *untracked; uint64_t fsmonitor_last_update; + struct ewah_bitmap *fsmonitor_dirty; }; extern struct index_state the_index; diff --git a/fsmonitor.c b/fsmonitor.c index 4ea44dcc6a..f494a866d5 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -26,7 +26,6 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data, uint32_t hdr_version; uint32_t ewah_size; struct ewah_bitmap *fsmonitor_dirty; - int i; int ret; if (sz < sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint32_t)) @@ -49,20 +48,7 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data, ewah_free(fsmonitor_dirty); return error("failed to parse ewah bitmap reading fsmonitor index extension"); } - - if (git_config_get_fsmonitor()) { - /* Mark all entries valid */ - for (i = 0; i < istate->cache_nr; i++) - istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID; - - /* Mark all previously saved entries as dirty */ - ewah_each_bit(fsmonitor_dirty, fsmonitor_ewah_callback, istate); - - /* Now mark the untracked cache for fsmonitor usage */ - if (istate->untracked) - istate->untracked->use_fsmonitor = 1; - } - ewah_free(fsmonitor_dirty); + istate->fsmonitor_dirty = fsmonitor_dirty; trace_printf_key(&trace_fsmonitor, "read fsmonitor extension successful"); return 0; @@ -239,7 +225,29 @@ void remove_fsmonitor(struct index_state *istate) void tweak_fsmonitor(struct index_state *istate) { - switch (git_config_get_fsmonitor()) { + int i; + int fsmonitor_enabled = git_config_get_fsmonitor(); + + if (istate->fsmonitor_dirty) { + if (fsmonitor_enabled) { + /* Mark all entries valid */ + for (i = 0; i < istate->cache_nr; i++) { + istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID; + } + + /* Mark all previously saved entries as dirty */ + ewah_each_bit(istate->fsmonitor_dirty, fsmonitor_ewah_callback, istate); + + /* Now mark the untracked cache for fsmonitor usage */ + if (istate->untracked) + istate->untracked->use_fsmonitor = 1; + } + + ewah_free(istate->fsmonitor_dirty); + istate->fsmonitor_dirty = NULL; + } + + switch (fsmonitor_enabled) { case -1: /* keep: do nothing */ break; case 0: /* false */ |