1 #include "git-compat-util.h"
3 #include "pack-mtimes.h"
4 #include "object-file.h"
5 #include "object-store-ll.h"
9 static char *pack_mtimes_filename(struct packed_git
*p
)
12 if (!strip_suffix(p
->pack_name
, ".pack", &len
))
13 BUG("pack_name does not end in .pack");
14 return xstrfmt("%.*s.mtimes", (int)len
, p
->pack_name
);
17 #define MTIMES_HEADER_SIZE (12)
19 struct mtimes_header
{
25 static int load_pack_mtimes_file(char *mtimes_file
,
27 const uint32_t **data_p
, size_t *len_p
)
31 uint32_t *data
= NULL
;
32 size_t mtimes_size
, expected_size
;
33 struct mtimes_header header
;
35 fd
= git_open(mtimes_file
);
42 ret
= error_errno(_("failed to read %s"), mtimes_file
);
46 mtimes_size
= xsize_t(st
.st_size
);
48 if (mtimes_size
< MTIMES_HEADER_SIZE
) {
49 ret
= error(_("mtimes file %s is too small"), mtimes_file
);
53 data
= xmmap(NULL
, mtimes_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
55 header
.signature
= ntohl(data
[0]);
56 header
.version
= ntohl(data
[1]);
57 header
.hash_id
= ntohl(data
[2]);
59 if (header
.signature
!= MTIMES_SIGNATURE
) {
60 ret
= error(_("mtimes file %s has unknown signature"), mtimes_file
);
64 if (header
.version
!= 1) {
65 ret
= error(_("mtimes file %s has unsupported version %"PRIu32
),
66 mtimes_file
, header
.version
);
70 if (!(header
.hash_id
== 1 || header
.hash_id
== 2)) {
71 ret
= error(_("mtimes file %s has unsupported hash id %"PRIu32
),
72 mtimes_file
, header
.hash_id
);
77 expected_size
= MTIMES_HEADER_SIZE
;
78 expected_size
= st_add(expected_size
, st_mult(sizeof(uint32_t), num_objects
));
79 expected_size
= st_add(expected_size
, 2 * (header
.hash_id
== 1 ? GIT_SHA1_RAWSZ
: GIT_SHA256_RAWSZ
));
81 if (mtimes_size
!= expected_size
) {
82 ret
= error(_("mtimes file %s is corrupt"), mtimes_file
);
89 munmap(data
, mtimes_size
);
100 int load_pack_mtimes(struct packed_git
*p
)
102 char *mtimes_name
= NULL
;
106 return ret
; /* not a cruft pack */
108 return ret
; /* already loaded */
110 ret
= open_pack_index(p
);
114 mtimes_name
= pack_mtimes_filename(p
);
115 ret
= load_pack_mtimes_file(mtimes_name
,
124 uint32_t nth_packed_mtime(struct packed_git
*p
, uint32_t pos
)
127 BUG("pack .mtimes file not loaded for %s", p
->pack_name
);
128 if (p
->num_objects
<= pos
)
129 BUG("pack .mtimes out-of-bounds (%"PRIu32
" vs %"PRIu32
")",
130 pos
, p
->num_objects
);
132 return get_be32(p
->mtimes_map
+ pos
+ 3);