Skip to content

Commit ba1b9ca

Browse files
Alex Vandivergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bd76afd commit ba1b9ca

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ struct index_state {
347347
unsigned char sha1[20];
348348
struct untracked_cache *untracked;
349349
uint64_t fsmonitor_last_update;
350+
struct ewah_bitmap *fsmonitor_dirty;
350351
};
351352

352353
extern struct index_state the_index;

fsmonitor.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data,
2626
uint32_t hdr_version;
2727
uint32_t ewah_size;
2828
struct ewah_bitmap *fsmonitor_dirty;
29-
int i;
3029
int ret;
3130

3231
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,
4948
ewah_free(fsmonitor_dirty);
5049
return error("failed to parse ewah bitmap reading fsmonitor index extension");
5150
}
52-
53-
if (git_config_get_fsmonitor()) {
54-
/* Mark all entries valid */
55-
for (i = 0; i < istate->cache_nr; i++)
56-
istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID;
57-
58-
/* Mark all previously saved entries as dirty */
59-
ewah_each_bit(fsmonitor_dirty, fsmonitor_ewah_callback, istate);
60-
61-
/* Now mark the untracked cache for fsmonitor usage */
62-
if (istate->untracked)
63-
istate->untracked->use_fsmonitor = 1;
64-
}
65-
ewah_free(fsmonitor_dirty);
51+
istate->fsmonitor_dirty = fsmonitor_dirty;
6652

6753
trace_printf_key(&trace_fsmonitor, "read fsmonitor extension successful");
6854
return 0;
@@ -239,7 +225,29 @@ void remove_fsmonitor(struct index_state *istate)
239225

240226
void tweak_fsmonitor(struct index_state *istate)
241227
{
242-
switch (git_config_get_fsmonitor()) {
228+
int i;
229+
int fsmonitor_enabled = git_config_get_fsmonitor();
230+
231+
if (istate->fsmonitor_dirty) {
232+
if (fsmonitor_enabled) {
233+
/* Mark all entries valid */
234+
for (i = 0; i < istate->cache_nr; i++) {
235+
istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID;
236+
}
237+
238+
/* Mark all previously saved entries as dirty */
239+
ewah_each_bit(istate->fsmonitor_dirty, fsmonitor_ewah_callback, istate);
240+
241+
/* Now mark the untracked cache for fsmonitor usage */
242+
if (istate->untracked)
243+
istate->untracked->use_fsmonitor = 1;
244+
}
245+
246+
ewah_free(istate->fsmonitor_dirty);
247+
istate->fsmonitor_dirty = NULL;
248+
}
249+
250+
switch (fsmonitor_enabled) {
243251
case -1: /* keep: do nothing */
244252
break;
245253
case 0: /* false */

0 commit comments

Comments
 (0)