git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v4 0/6] Fix the racy split index problem

From
SZEDER Gábor <szeder.dev@gmail.com>
Date
Oct 11, 2018, 09:43 UTC
Message-ID
<20181011094309.18626-1-szeder.dev@gmail.com>
In-Reply-To
<20180928162459.17138-1-szeder.dev@gmail.com>

Fourth and hopefully final round of fixing occasional test failures when run with 'GIT_TEST_SPLIT_INDEX=yes'. The only code change is the extraction of a helper function to compare two cache entries' content, and then a couple of minor log message clarifications. The range-diff below is rather clear on that.

I will send a 7/6 follow-up patch shortly as well.
SZEDER Gábor (6):
  t1700-split-index: document why FSMONITOR is disabled in this test
    script
  split-index: add tests to demonstrate the racy split index problem
  t1700-split-index: date back files to avoid racy situations
  split-index: count the number of deleted entries
  split-index: don't compare cached data of entries already marked for
    split index
  split-index: smudge and add racily clean cache entries to split index
 cache.h                     |   2 +
 read-cache.c                |   2 +-
 split-index.c               | 131 +++++++++++++++++++---
 t/t1700-split-index.sh      |  52 +++++----
 t/t1701-racy-split-index.sh | 214 ++++++++++++++++++++++++++++++++++++
 5 files changed, 361 insertions(+), 40 deletions(-)
 create mode 100755 t/t1701-racy-split-index.sh
Range-diff:
1:  ba2b1bdf16 = 1:  ba2b1bdf16 t1700-split-index: document why FSMONITOR is disabled in this test script
2:  bf1b038f10 ! 2:  c7cb9d9115 split-index: add tests to demonstrate the racy split index problem
    @@ -136,13 +136,20 @@
              git commands will then erroneously consider the file clean.
     
         Note that in the last two 'test_expect_failure' cases I omitted the
    -    '#' (as in nr. of trial) from the tests' name on purpose for now, as
    -    it confuses 'prove' into thinking that those tests failed
    -    unexpectedly.
    +    '#' (as in nr. of trial) from the tests' description on purpose for
    +    now, as it breakes the TAP output [2]; it will be added at the end of
    +    the series, when those two tests will be flipped to
    +    'test_expect_success'.
     
         [1] In the branch leading to the merge commit v2.1.0-rc0~45 (Merge
             branch 'nd/split-index', 2014-07-16).
     
    +    [2] In the TAP output a '#' should separate the test's description
    +        from the TODO directive emitted by 'test_expect_failure'.  The
    +        additional '#' in "#$trial" interferes with this, the test harness
    +        won't recognize the TODO directive, and will report that those
    +        tests failed unexpectedly.
    +
         Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
     
      diff --git a/t/t1701-racy-split-index.sh b/t/t1701-racy-split-index.sh
3:  e7f7fb6e2d = 3:  ce803d8064 t1700-split-index: date back files to avoid racy situations
4:  6dc0b01ad3 = 4:  1d12d718d1 split-index: count the number of deleted entries
5:  9c420f9c66 ! 5:  0dd448c707 split-index: don't compare stat data of entries already marked for split index
    @@ -1,6 +1,6 @@
     Author: SZEDER Gábor <szeder.dev@gmail.com>
     
    -    split-index: don't compare stat data of entries already marked for split index
    +    split-index: don't compare cached data of entries already marked for split index
     
         When unpack_trees() constructs a new index, it copies cache entries
         from the original index [1].  prepare_to_write_split_index() has to
    @@ -20,7 +20,9 @@
     
         So modify prepare_to_write_split_index() to check the copied cache
         entries' CE_UPDATE_IN_BASE flag first, and skip the thorough
    -    comparison of cached data if the flag is already set.
    +    comparison of cached data if the flag is already set.  Those couple of
    +    lines comparing the cached data would then have too many levels of
    +    indentation, so extract them into a helper function.
     
         Note that comparing the cached data in copied and original entries in
         the shared index might actually be entirely unnecessary.  In theory
    @@ -62,6 +64,37 @@
      diff --git a/split-index.c b/split-index.c
      --- a/split-index.c
      +++ b/split-index.c
    +@@
    + 	si->saved_cache_nr = 0;
    + }
    + 
    ++/*
    ++ * Compare most of the fields in two cache entries, i.e. all except the
    ++ * hashmap_entry and the name.
    ++ */
    ++static int compare_ce_content(struct cache_entry *a, struct cache_entry *b)
    ++{
    ++	const unsigned int ondisk_flags = CE_STAGEMASK | CE_VALID |
    ++					  CE_EXTENDED_FLAGS;
    ++	unsigned int ce_flags = a->ce_flags;
    ++	unsigned int base_flags = b->ce_flags;
    ++	int ret;
    ++
    ++	/* only on-disk flags matter */
    ++	a->ce_flags &= ondisk_flags;
    ++	b->ce_flags &= ondisk_flags;
    ++	ret = memcmp(&a->ce_stat_data, &b->ce_stat_data,
    ++		     offsetof(struct cache_entry, name) -
    ++		     offsetof(struct cache_entry, ce_stat_data));
    ++	a->ce_flags = ce_flags;
    ++	b->ce_flags = base_flags;
    ++
    ++	return ret;
    ++}
    ++
    + void prepare_to_write_split_index(struct index_state *istate)
    + {
    + 	struct split_index *si = init_split_index(istate);
     @@
      		 */
      		for (i = 0; i < istate->cache_nr; i++) {
    @@ -137,21 +170,7 @@
     +				 * code paths modifying the cached data do
     +				 * set CE_UPDATE_IN_BASE as well.
     +				 */
    -+				const unsigned int ondisk_flags =
    -+					CE_STAGEMASK | CE_VALID |
    -+					CE_EXTENDED_FLAGS;
    -+				unsigned int ce_flags, base_flags, ret;
    -+				ce_flags = ce->ce_flags;
    -+				base_flags = base->ce_flags;
    -+				/* only on-disk flags matter */
    -+				ce->ce_flags   &= ondisk_flags;
    -+				base->ce_flags &= ondisk_flags;
    -+				ret = memcmp(&ce->ce_stat_data, &base->ce_stat_data,
    -+					     offsetof(struct cache_entry, name) -
    -+					     offsetof(struct cache_entry, ce_stat_data));
    -+				ce->ce_flags = ce_flags;
    -+				base->ce_flags = base_flags;
    -+				if (ret)
    ++				if (compare_ce_content(ce, base))
     +					ce->ce_flags |= CE_UPDATE_IN_BASE;
     +			}
      			discard_cache_entry(base);
6:  52c755f210 ! 6:  384b440345 split-index: smudge and add racily clean cache entries to split index
    @@ -46,6 +46,11 @@
         racily clean cache entries as well, and will then write them with
         smudged stat data to the new split index.
     
    +    This change makes all tests in 't1701-racy-split-index.sh' pass, so
    +    flip the two 'test_expect_failure' tests to success.  Also add the '#'
    +    (as in nr. of trial) to those tests' description that were omitted
    +    when the tests expected failure.
    +
         Note that after this change if the index is split when it contains a
         racily clean cache entry, then a smudged cache entry will be written
         both to the new shared and to the new split indexes.  This doesn't
-- 
2.19.1.465.gaff195083f
Previous: Junio C HamanoNext: SZEDER Gábor
Message 32 of 42 in “Fix the racy split index problem”
  1. 0/5 Fix the racy split index problemSZEDER Gábor, Sep 27, 2018
  2. 1/5 split-index: add tests to demonstrate the racy split index problemSZEDER Gábor, Sep 27, 2018
  3. SZEDER GáborSep 28, 2018
  4. SZEDER GáborSep 28, 2018
  5. Junio C HamanoSep 28, 2018
  6. 2/5 t1700-split-index: date back files to avoid racy situationsSZEDER Gábor, Sep 27, 2018
  7. 3/5 split-index: count the number of deleted entriesSZEDER Gábor, Sep 27, 2018
  8. 4/5 split-index: don't compare stat data of entries already marked for split indexSZEDER Gábor, Sep 27, 2018
  9. SZEDER GáborSep 27, 2018
  10. 5/5 split-index: smudge and add racily clean cache entries to split indexSZEDER Gábor, Sep 27, 2018
  11. Ævar Arnfjörð BjarmasonSep 27, 2018
  12. SZEDER GáborSep 27, 2018
  13. Ævar Arnfjörð BjarmasonSep 27, 2018
  14. Ævar Arnfjörð BjarmasonSep 28, 2018
  15. SZEDER GáborSep 28, 2018
  16. Ævar Arnfjörð BjarmasonOct 8, 2018
  17. SZEDER GáborOct 8, 2018
  18. 0/6 Fix the racy split index problemSZEDER Gábor, Sep 28, 2018
  19. 1/6 t1700-split-index: document why FSMONITOR is disabled in this test scriptSZEDER Gábor, Sep 28, 2018
  20. 2/6 split-index: add tests to demonstrate the racy split index problemSZEDER Gábor, Sep 28, 2018
  21. 3/6 t1700-split-index: date back files to avoid racy situationsSZEDER Gábor, Sep 28, 2018
  22. 4/6 split-index: count the number of deleted entriesSZEDER Gábor, Sep 28, 2018
  23. 5/6 split-index: don't compare stat data of entries already marked for split indexSZEDER Gábor, Sep 28, 2018
  24. Duy NguyenSep 29, 2018
  25. SZEDER GáborSep 29, 2018
  26. SZEDER GáborSep 29, 2018
  27. 6/6 split-index: smudge and add racily clean cache entries to split indexSZEDER Gábor, Sep 28, 2018
  28. Duy NguyenSep 29, 2018
  29. SZEDER GáborSep 29, 2018
  30. SZEDER GáborSep 30, 2018
  31. Junio C HamanoOct 5, 2018
  32. 0/6 Fix the racy split index problemSZEDER Gábor, Oct 11, 2018
  33. 1/6 t1700-split-index: document why FSMONITOR is disabled in this test scriptSZEDER Gábor, Oct 11, 2018
  34. 3/6 t1700-split-index: date back files to avoid racy situationsSZEDER Gábor, Oct 11, 2018
  35. 2/6 split-index: add tests to demonstrate the racy split index problemSZEDER Gábor, Oct 11, 2018
  36. 4/6 split-index: count the number of deleted entriesSZEDER Gábor, Oct 11, 2018
  37. 5/6 split-index: don't compare cached data of entries already marked for split indexSZEDER Gábor, Oct 11, 2018
  38. 6/6 split-index: smudge and add racily clean cache entries to split indexSZEDER Gábor, Oct 11, 2018
  39. 7/6 split-index: BUG() when cache entry refers to non-existing shared entrySZEDER Gábor, Oct 11, 2018
  40. Ævar Arnfjörð BjarmasonOct 11, 2018
  41. SZEDER GáborOct 11, 2018
  42. Junio C HamanoOct 12, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.