fsmonitor: store fsmonitor bitmap before splitting index
authorAlex Vandiver <alexmv@dropbox.com>
Thu, 9 Nov 2017 19:58:10 +0000 (11:58 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 10 Nov 2017 05:05:01 +0000 (14:05 +0900)
ba1b9cac ("fsmonitor: delay updating state until after split index
is merged", 2017-10-27) resolved the problem of the fsmonitor data
being applied to the non-base index when reading; however, a similar
problem exists when writing the index. Specifically, writing of the
fsmonitor extension happens only after the work to split the index
has been applied -- as such, the information in the index is only
for the non-"base" index, and thus the extension information
contains only partial data.

When saving, compute the ewah bitmap before the index is split, and
store it in the fsmonitor_dirty field, mirroring the behavior that
occurred during reading. fsmonitor_dirty is kept from being leaked by
being freed when the extension data is written -- which always happens
precisely once, no matter the split index configuration.

Signed-off-by: Alex Vandiver <alexmv@dropbox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
fsmonitor.c
fsmonitor.h
read-cache.c
t/t7519-status-fsmonitor.sh
index f494a866d59d98fb8d36004a79dd24976850dc0e..0af7c4edba37fd9f6a8cee83cd2715c3fa08b488 100644 (file)
@@ -54,12 +54,19 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data,
        return 0;
 }
 
+void fill_fsmonitor_bitmap(struct index_state *istate)
+{
+       int i;
+       istate->fsmonitor_dirty = ewah_new();
+       for (i = 0; i < istate->cache_nr; i++)
+               if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID))
+                       ewah_set(istate->fsmonitor_dirty, i);
+}
+
 void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
 {
        uint32_t hdr_version;
        uint64_t tm;
-       struct ewah_bitmap *bitmap;
-       int i;
        uint32_t ewah_start;
        uint32_t ewah_size = 0;
        int fixup = 0;
@@ -73,12 +80,9 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
        strbuf_add(sb, &ewah_size, sizeof(uint32_t)); /* we'll fix this up later */
 
        ewah_start = sb->len;
-       bitmap = ewah_new();
-       for (i = 0; i < istate->cache_nr; i++)
-               if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID))
-                       ewah_set(bitmap, i);
-       ewah_serialize_strbuf(bitmap, sb);
-       ewah_free(bitmap);
+       ewah_serialize_strbuf(istate->fsmonitor_dirty, sb);
+       ewah_free(istate->fsmonitor_dirty);
+       istate->fsmonitor_dirty = NULL;
 
        /* fix up size field */
        put_be32(&ewah_size, sb->len - ewah_start);
index 0de644e01aaea7e6082dc5b63015d498f324d271..cd3cc0ccf228c9d601621685042d51368a71c707 100644 (file)
@@ -10,7 +10,14 @@ extern struct trace_key trace_fsmonitor;
 extern int read_fsmonitor_extension(struct index_state *istate, const void *data, unsigned long sz);
 
 /*
- * Write the CE_FSMONITOR_VALID state into the fsmonitor index extension.
+ * Fill the fsmonitor_dirty ewah bits with their state from the index,
+ * before it is split during writing.
+ */
+extern void fill_fsmonitor_bitmap(struct index_state *istate);
+
+/*
+ * Write the CE_FSMONITOR_VALID state into the fsmonitor index
+ * extension.  Reads from the fsmonitor_dirty ewah in the index.
  */
 extern void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate);
 
index 05c0a33fddfa6989f1cd630f744686500dce12ea..0724ea8c9b807eed87b571e3837a9be254c3b71b 100644 (file)
@@ -2525,6 +2525,9 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
        int new_shared_index, ret;
        struct split_index *si = istate->split_index;
 
+       if (istate->fsmonitor_last_update)
+               fill_fsmonitor_bitmap(istate);
+
        if (!si || alternate_index_output ||
            (istate->cache_changed & ~EXTMASK)) {
                if (si)
index c6df85af5ee2d401d69a4eeabd3a48dc73030963..eb2d13bbcf8abefd7af2be6f9cb3bf97e389ab15 100755 (executable)
@@ -301,4 +301,17 @@ do
        done
 done
 
+# test that splitting the index dosn't interfere
+test_expect_success 'splitting the index results in the same state' '
+       write_integration_script &&
+       dirty_repo &&
+       git update-index --fsmonitor  &&
+       git ls-files -f >expect &&
+       test-dump-fsmonitor >&2 && echo &&
+       git update-index --fsmonitor --split-index &&
+       test-dump-fsmonitor >&2 && echo &&
+       git ls-files -f >actual &&
+       test_cmp expect actual
+'
+
 test_done