aboutsummaryrefslogtreecommitdiff
path: root/packfile.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-05-30 11:59:18 -0700
committerJunio C Hamano <gitster@pobox.com>2025-05-30 11:59:18 -0700
commit9a43523dc39f88567e7e4e01fcde72194df7e467 (patch)
treedbcf4146a43b6501ec27a74fa22f890fb936d2e5 /packfile.c
parent1a140c870d1fe069387d13c68d5e219b466a0af6 (diff)
parent1f34bf3e082741e053d25b76a0ffe31d9d967594 (diff)
downloadgit-9a43523dc39f88567e7e4e01fcde72194df7e467.tar.xz
Merge branch 'ps/midx-negative-packfile-cache'
When a stale .midx file refers to .pack files that no longer exist, we ended up checking for these non-existent files repeatedly, which has been optimized by memoizing the non-existence. * ps/midx-negative-packfile-cache: midx: stop repeatedly looking up nonexistent packfiles packfile: explain ordering of how we look up auxiliary pack files
Diffstat (limited to 'packfile.c')
-rw-r--r--packfile.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/packfile.c b/packfile.c
index 80e35f1032..70c7208f02 100644
--- a/packfile.c
+++ b/packfile.c
@@ -737,6 +737,17 @@ struct packed_git *add_packed_git(struct repository *r, const char *path,
p = alloc_packed_git(r, alloc);
memcpy(p->pack_name, path, path_len);
+ /*
+ * Note that we have to check auxiliary data structures before we check
+ * for the ".pack" file to exist to avoid races with a packfile that is
+ * in the process of being deleted. The ".pack" file is unlinked before
+ * its auxiliary data structures, so we know that we either get a
+ * consistent snapshot of all data structures or that we'll fail to
+ * stat(3p) the packfile itself and thus return `NULL`.
+ *
+ * As such, we cannot bail out before the access(3p) calls in case the
+ * packfile doesn't exist without doing two stat(3p) calls for it.
+ */
xsnprintf(p->pack_name + path_len, alloc - path_len, ".keep");
if (!access(p->pack_name, F_OK))
p->pack_keep = 1;