3 #include "pack-mtimes.h"
4 #include "object-store.h"
7 static char *pack_mtimes_filename(struct packed_git
*p
)
10 if (!strip_suffix(p
->pack_name
, ".pack", &len
))
11 BUG("pack_name does not end in .pack");
12 return xstrfmt("%.*s.mtimes", (int)len
, p
->pack_name
);
15 #define MTIMES_HEADER_SIZE (12)
17 struct mtimes_header
{
23 static int load_pack_mtimes_file(char *mtimes_file
,
25 const uint32_t **data_p
, size_t *len_p
)
29 uint32_t *data
= NULL
;
30 size_t mtimes_size
, expected_size
;
31 struct mtimes_header header
;
33 fd
= git_open(mtimes_file
);
40 ret
= error_errno(_("failed to read %s"), mtimes_file
);
44 mtimes_size
= xsize_t(st
.st_size
);
46 if (mtimes_size
< MTIMES_HEADER_SIZE
) {
47 ret
= error(_("mtimes file %s is too small"), mtimes_file
);
51 data
= xmmap(NULL
, mtimes_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
53 header
.signature
= ntohl(data
[0]);
54 header
.version
= ntohl(data
[1]);
55 header
.hash_id
= ntohl(data
[2]);
57 if (header
.signature
!= MTIMES_SIGNATURE
) {
58 ret
= error(_("mtimes file %s has unknown signature"), mtimes_file
);
62 if (header
.version
!= 1) {
63 ret
= error(_("mtimes file %s has unsupported version %"PRIu32
),
64 mtimes_file
, header
.version
);
68 if (!(header
.hash_id
== 1 || header
.hash_id
== 2)) {
69 ret
= error(_("mtimes file %s has unsupported hash id %"PRIu32
),
70 mtimes_file
, header
.hash_id
);
75 expected_size
= MTIMES_HEADER_SIZE
;
76 expected_size
= st_add(expected_size
, st_mult(sizeof(uint32_t), num_objects
));
77 expected_size
= st_add(expected_size
, 2 * (header
.hash_id
== 1 ? GIT_SHA1_RAWSZ
: GIT_SHA256_RAWSZ
));
79 if (mtimes_size
!= expected_size
) {
80 ret
= error(_("mtimes file %s is corrupt"), mtimes_file
);
87 munmap(data
, mtimes_size
);
98 int load_pack_mtimes(struct packed_git
*p
)
100 char *mtimes_name
= NULL
;
104 return ret
; /* not a cruft pack */
106 return ret
; /* already loaded */
108 ret
= open_pack_index(p
);
112 mtimes_name
= pack_mtimes_filename(p
);
113 ret
= load_pack_mtimes_file(mtimes_name
,
122 uint32_t nth_packed_mtime(struct packed_git
*p
, uint32_t pos
)
125 BUG("pack .mtimes file not loaded for %s", p
->pack_name
);
126 if (p
->num_objects
<= pos
)
127 BUG("pack .mtimes out-of-bounds (%"PRIu32
" vs %"PRIu32
")",
128 pos
, p
->num_objects
);
130 return get_be32(p
->mtimes_map
+ pos
+ 3);