diff options
Diffstat (limited to 'packfile.c')
| -rw-r--r-- | packfile.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/packfile.c b/packfile.c index 2d80d80cb3..70c7208f02 100644 --- a/packfile.c +++ b/packfile.c @@ -19,11 +19,12 @@ #include "tree-walk.h" #include "tree.h" #include "object-file.h" -#include "object-store-ll.h" +#include "object-store.h" #include "midx.h" #include "commit-graph.h" #include "pack-revindex.h" #include "promisor-remote.h" +#include "pack-mtimes.h" char *odb_pack_name(struct repository *r, struct strbuf *buf, const unsigned char *hash, const char *ext) @@ -736,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; @@ -1597,17 +1609,12 @@ int packed_object_info(struct repository *r, struct packed_git *p, *oi->disk_sizep = pack_pos_to_offset(p, pos + 1) - obj_offset; } - if (oi->typep || oi->type_name) { + if (oi->typep) { enum object_type ptot; ptot = packed_to_object_type(r, p, obj_offset, type, &w_curs, curpos); if (oi->typep) *oi->typep = ptot; - if (oi->type_name) { - const char *tn = type_name(ptot); - if (tn) - strbuf_addstr(oi->type_name, tn); - } if (ptot < 0) { type = OBJ_BAD; goto out; @@ -2107,7 +2114,7 @@ static void maybe_invalidate_kept_pack_cache(struct repository *r, r->objects->kept_pack_cache.flags = 0; } -static struct packed_git **kept_pack_cache(struct repository *r, unsigned flags) +struct packed_git **kept_pack_cache(struct repository *r, unsigned flags) { maybe_invalidate_kept_pack_cache(r, flags); |
