aboutsummaryrefslogtreecommitdiffstats
path: root/packfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'packfile.c')
-rw-r--r--packfile.c23
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);