diff mbox series

[10/12] fsmonitor: support case-insensitive non-directory events

Message ID bf18401f56c8df0432a1ba52ae79f5e68d81cdb9.1707857541.git.gitgitgadget@gmail.com (mailing list archive)
State Superseded
Headers show
Series FSMonitor edge cases on case-insensitive file systems | expand

Commit Message

Jeff Hostetler Feb. 13, 2024, 8:52 p.m. UTC
From: Jeff Hostetler <jeffhostetler@github.com>

Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
---
 fsmonitor.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/fsmonitor.c b/fsmonitor.c
index cb27bae8aa8..a7847f07a40 100644
--- a/fsmonitor.c
+++ b/fsmonitor.c
@@ -336,6 +336,36 @@  static int fsmonitor_refresh_callback_unqualified(
 	}
 }
 
+/*
+ * On a case-insensitive FS, use the name-hash to map the case of
+ * the observed path to the canonical case expected by the index.
+ *
+ * The given pathname DOES NOT include the trailing slash.
+ *
+ * Return the number of cache-entries that we invalidated.
+ */
+static int fsmonitor_refresh_callback_unqualified_icase(
+	struct index_state *istate, const char *name, int len)
+{
+	int nr_in_cone;
+
+	/*
+	 * Look for a case-incorrect match for this non-directory
+	 * pathname.
+	 */
+	nr_in_cone = my_callback_name_hash(istate, name, len);
+	if (nr_in_cone)
+		return nr_in_cone;
+
+	/*
+	 * Try the directory name-hash and see if there is a
+	 * case-incorrect directory with this pathanme.
+	 * (len) because we don't have a trailing slash.
+	 */
+	nr_in_cone = my_callback_dir_name_hash(istate, name, len);
+	return nr_in_cone;
+}
+
 /*
  * The daemon can decorate directory events, such as a move or rename,
  * by adding a trailing slash to the observed name.  Use this to
@@ -434,7 +464,9 @@  static void fsmonitor_refresh_callback(struct index_state *istate, char *name)
 		if (ignore_case && !nr_in_cone)
 			fsmonitor_refresh_callback_slash_icase(istate, name, len);
 	} else {
-		fsmonitor_refresh_callback_unqualified(istate, name, len, pos);
+		nr_in_cone = fsmonitor_refresh_callback_unqualified(istate, name, len, pos);
+		if (ignore_case && !nr_in_cone)
+			fsmonitor_refresh_callback_unqualified_icase(istate, name, len);
 	}
 }