1 #include "git-compat-util.h"
3 #include "pack-mtimes.h"
4 #include "object-file.h"
5 #include "object-store.h"
8 static char *pack_mtimes_filename(struct packed_git
*p
)
11 if (!strip_suffix(p
->pack_name
, ".pack", &len
))
12 BUG("pack_name does not end in .pack");
13 return xstrfmt("%.*s.mtimes", (int)len
, p
->pack_name
);
16 #define MTIMES_HEADER_SIZE (12)
18 struct mtimes_header
{
24 static int load_pack_mtimes_file(char *mtimes_file
,
26 const uint32_t **data_p
, size_t *len_p
)
30 uint32_t *data
= NULL
;
31 size_t mtimes_size
, expected_size
;
32 struct mtimes_header header
;
34 fd
= git_open(mtimes_file
);
41 ret
= error_errno(_("failed to read %s"), mtimes_file
);
45 mtimes_size
= xsize_t(st
.st_size
);
47 if (mtimes_size
< MTIMES_HEADER_SIZE
) {
48 ret
= error(_("mtimes file %s is too small"), mtimes_file
);
52 data
= xmmap(NULL
, mtimes_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
54 header
.signature
= ntohl(data
[0]);
55 header
.version
= ntohl(data
[1]);
56 header
.hash_id
= ntohl(data
[2]);
58 if (header
.signature
!= MTIMES_SIGNATURE
) {
59 ret
= error(_("mtimes file %s has unknown signature"), mtimes_file
);
63 if (header
.version
!= 1) {
64 ret
= error(_("mtimes file %s has unsupported version %"PRIu32
),
65 mtimes_file
, header
.version
);
69 if (!(header
.hash_id
== 1 || header
.hash_id
== 2)) {
70 ret
= error(_("mtimes file %s has unsupported hash id %"PRIu32
),
71 mtimes_file
, header
.hash_id
);
76 expected_size
= MTIMES_HEADER_SIZE
;
77 expected_size
= st_add(expected_size
, st_mult(sizeof(uint32_t), num_objects
));
78 expected_size
= st_add(expected_size
, 2 * (header
.hash_id
== 1 ? GIT_SHA1_RAWSZ
: GIT_SHA256_RAWSZ
));
80 if (mtimes_size
!= expected_size
) {
81 ret
= error(_("mtimes file %s is corrupt"), mtimes_file
);
88 munmap(data
, mtimes_size
);
99 int load_pack_mtimes(struct packed_git
*p
)
101 char *mtimes_name
= NULL
;
105 return ret
; /* not a cruft pack */
107 return ret
; /* already loaded */
109 ret
= open_pack_index(p
);
113 mtimes_name
= pack_mtimes_filename(p
);
114 ret
= load_pack_mtimes_file(mtimes_name
,
123 uint32_t nth_packed_mtime(struct packed_git
*p
, uint32_t pos
)
126 BUG("pack .mtimes file not loaded for %s", p
->pack_name
);
127 if (p
->num_objects
<= pos
)
128 BUG("pack .mtimes out-of-bounds (%"PRIu32
" vs %"PRIu32
")",
129 pos
, p
->num_objects
);
131 return get_be32(p
->mtimes_map
+ pos
+ 3);