Skip to content

Commit a51f8ad

Browse files
committed
Merge branch 'ps/midx-negative-packfile-cache' into tb/prepare-midx-pack-cleanup
* ps/midx-negative-packfile-cache: midx: stop repeatedly looking up nonexistent packfiles packfile: explain ordering of how we look up auxiliary pack files
2 parents 845c48a + 73fe088 commit a51f8ad

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

midx.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ void close_midx(struct multi_pack_index *m)
405405
munmap((unsigned char *)m->data, m->data_len);
406406

407407
for (i = 0; i < m->num_packs; i++) {
408-
if (m->packs[i])
408+
if (m->packs[i] && m->packs[i] != (void *)(intptr_t)-1)
409409
m->packs[i]->multi_pack_index = 0;
410410
}
411411
FREE_AND_NULL(m->packs);
@@ -458,6 +458,8 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
458458

459459
pack_int_id = midx_for_pack(&m, pack_int_id);
460460

461+
if (m->packs[pack_int_id] == (void *)(intptr_t)-1)
462+
return 1;
461463
if (m->packs[pack_int_id])
462464
return 0;
463465

@@ -482,8 +484,10 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
482484
strbuf_release(&pack_name);
483485
strbuf_release(&key);
484486

485-
if (!p)
487+
if (!p) {
488+
m->packs[pack_int_id] = (void *)(intptr_t)-1;
486489
return 1;
490+
}
487491

488492
p->multi_pack_index = 1;
489493
m->packs[pack_int_id] = p;
@@ -495,6 +499,8 @@ struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
495499
uint32_t pack_int_id)
496500
{
497501
uint32_t local_pack_int_id = midx_for_pack(&m, pack_int_id);
502+
if (m->packs[local_pack_int_id] == (void *)(intptr_t)-1)
503+
return NULL;
498504
return m->packs[local_pack_int_id];
499505
}
500506

packfile.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,17 @@ struct packed_git *add_packed_git(struct repository *r, const char *path,
737737
p = alloc_packed_git(r, alloc);
738738
memcpy(p->pack_name, path, path_len);
739739

740+
/*
741+
* Note that we have to check auxiliary data structures before we check
742+
* for the ".pack" file to exist to avoid races with a packfile that is
743+
* in the process of being deleted. The ".pack" file is unlinked before
744+
* its auxiliary data structures, so we know that we either get a
745+
* consistent snapshot of all data structures or that we'll fail to
746+
* stat(3p) the packfile itself and thus return `NULL`.
747+
*
748+
* As such, we cannot bail out before the access(3p) calls in case the
749+
* packfile doesn't exist without doing two stat(3p) calls for it.
750+
*/
740751
xsnprintf(p->pack_name + path_len, alloc - path_len, ".keep");
741752
if (!access(p->pack_name, F_OK))
742753
p->pack_keep = 1;

0 commit comments

Comments
 (0)