Subject: Re: [PATCH v11 0/8] fsmonitor: add Linux support using inotify

From: Paul Tarjan <[email-masked]>
Date: Tue, 31 Mar 2026 00:17:54 -0600

Junio C Hamano <[email-masked]> writes:

> In any case, when this topic is merged to 'seen', it seem to break
> linux-TEST-vars CI job, which essentially runs the build and test
> with these settings:
>
>         export GIT_TEST_SPLIT_INDEX=yes
>         [...]
>
> and t9210 fails with this topic merged (abfd972), and succeeds
> without (4b8355c6f8).

Thanks for the pointer. The failure is:

  BUG: fsmonitor.c:27: fsmonitor_dirty has more entries than the
  index (2 > 0)

It's a pre-existing bug in the interaction between fsmonitor and
split-index, now exposed because fsmonitor-linux enables the
daemon on Linux for the first time (so scalar clone actually
starts it). It needs the interaction with
ps/setup-wo-the-repository in seen to trigger.

This is related to the issue that 05f28e4b3c ("scalar: use
index.skipHash=true for performance", 2025-06-04) worked around
by disabling GIT_TEST_SPLIT_INDEX in t9210, noting "the issue
should be resolved in a series focused on the split index." My
fix covers the fsmonitor bitmap side; the index.skipHash
interaction remains.

The fsmonitor_dirty EWAH bitmap can reference positions from a
previous index state. With split-index, cache_nr can be smaller
than the bitmap expects. Two places hit this:

1. tweak_fsmonitor() calls assert_index_minimum() without the
   !istate->split_index guard that the read path (line 98) and
   write path (line 128) already have.

2. fsmonitor_ewah_callback() unconditionally asserts and then
   accesses istate->cache[pos], which is out of bounds when
   split-index hasn't merged all entries yet.

I reproduced this in a Fedora container by merging fsmonitor-linux
into seen and running t9210 with GIT_TEST_SPLIT_INDEX=yes. Fails
without the fix, passes with it.

Fix is pushed as a new commit at the end of the series:

  fsmonitor_ewah_callback():
  -  assert_index_minimum(istate, pos + 1);
  +  if (pos >= istate->cache_nr)
  +      return;

  tweak_fsmonitor():
  -  assert_index_minimum(istate, istate->fsmonitor_dirty->bit_size);
  +  if (!istate->split_index)
  +      assert_index_minimum(istate, istate->fsmonitor_dirty->bit_size);

Paul