1 #include "git-compat-util.h"
2 #include "pack-mtimes.h"
3 #include "object-store.h"
6 static char *pack_mtimes_filename(struct packed_git
*p
)
9 if (!strip_suffix(p
->pack_name
, ".pack", &len
))
10 BUG("pack_name does not end in .pack");
11 return xstrfmt("%.*s.mtimes", (int)len
, p
->pack_name
);
14 #define MTIMES_HEADER_SIZE (12)
16 struct mtimes_header
{
22 static int load_pack_mtimes_file(char *mtimes_file
,
24 const uint32_t **data_p
, size_t *len_p
)
28 uint32_t *data
= NULL
;
29 size_t mtimes_size
, expected_size
;
30 struct mtimes_header header
;
32 fd
= git_open(mtimes_file
);
39 ret
= error_errno(_("failed to read %s"), mtimes_file
);
43 mtimes_size
= xsize_t(st
.st_size
);
45 if (mtimes_size
< MTIMES_HEADER_SIZE
) {
46 ret
= error(_("mtimes file %s is too small"), mtimes_file
);
50 data
= xmmap(NULL
, mtimes_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
52 header
.signature
= ntohl(data
[0]);
53 header
.version
= ntohl(data
[1]);
54 header
.hash_id
= ntohl(data
[2]);
56 if (header
.signature
!= MTIMES_SIGNATURE
) {
57 ret
= error(_("mtimes file %s has unknown signature"), mtimes_file
);
61 if (header
.version
!= 1) {
62 ret
= error(_("mtimes file %s has unsupported version %"PRIu32
),
63 mtimes_file
, header
.version
);
67 if (!(header
.hash_id
== 1 || header
.hash_id
== 2)) {
68 ret
= error(_("mtimes file %s has unsupported hash id %"PRIu32
),
69 mtimes_file
, header
.hash_id
);
74 expected_size
= MTIMES_HEADER_SIZE
;
75 expected_size
= st_add(expected_size
, st_mult(sizeof(uint32_t), num_objects
));
76 expected_size
= st_add(expected_size
, 2 * (header
.hash_id
== 1 ? GIT_SHA1_RAWSZ
: GIT_SHA256_RAWSZ
));
78 if (mtimes_size
!= expected_size
) {
79 ret
= error(_("mtimes file %s is corrupt"), mtimes_file
);
86 munmap(data
, mtimes_size
);
97 int load_pack_mtimes(struct packed_git
*p
)
99 char *mtimes_name
= NULL
;
103 return ret
; /* not a cruft pack */
105 return ret
; /* already loaded */
107 ret
= open_pack_index(p
);
111 mtimes_name
= pack_mtimes_filename(p
);
112 ret
= load_pack_mtimes_file(mtimes_name
,
121 uint32_t nth_packed_mtime(struct packed_git
*p
, uint32_t pos
)
124 BUG("pack .mtimes file not loaded for %s", p
->pack_name
);
125 if (p
->num_objects
<= pos
)
126 BUG("pack .mtimes out-of-bounds (%"PRIu32
" vs %"PRIu32
")",
127 pos
, p
->num_objects
);
129 return get_be32(p
->mtimes_map
+ pos
+ 3);