pack: move open_pack_index(), parse_pack_index()
alloc_packed_git() in packfile.c is duplicated from sha1_file.c. In a subsequent commit, alloc_packed_git() will be removed from sha1_file.c. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jonathan Tan committed
Aug 18, 2017 at 15:20 UTC
0317f45576a0b48c90c4b023fa572a000633946c
10 files changed
+163
-148
builtin/count-objects.c
+1
@@ -10,6 +10,7 @@
10
#include "builtin.h"
11
#include "parse-options.h"
12
#include "quote.h"
13
+#include "packfile.h"
14
15
static unsigned long garbage;
16
static off_t size_garbage;
builtin/fsck.c
+1
@@ -15,6 +15,7 @@
15
#include "progress.h"
16
#include "streaming.h"
17
#include "decorate.h"
18
+#include "packfile.h"
19
20
#define REACHABLE 0x0001
21
#define SEEN 0x0002
builtin/pack-objects.c
+1
@@ -25,6 +25,7 @@
25
#include "sha1-array.h"
26
#include "argv-array.h"
27
#include "mru.h"
28
+#include "packfile.h"
29
30
static const char *pack_usage[] = {
31
N_("git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"),
cache.h
-8
@@ -1605,8 +1605,6 @@ struct pack_entry {
1605
struct packed_git *p;
1606
};
1607
1608
-extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
1609
-
1608
/* A hook to report invalid files in pack directory */
1609
#define PACKDIR_FILE_PACK 1
1610
#define PACKDIR_FILE_IDX 2
@@ -1641,12 +1639,6 @@ extern int odb_mkstemp(struct strbuf *template, const char *pattern);
1639
*/
1640
extern int odb_pack_keep(const char *name);
1641
1644
-/*
1645
- * mmap the index file for the specified packfile (if it is not
1646
- * already mmapped). Return 0 on success.
1647
- */
1648
-extern int open_pack_index(struct packed_git *);
1649
-
1642
/*
1643
* munmap the index file for the specified packfile (if it is
1644
* currently mmapped).
pack-bitmap.c
+1
@@ -9,6 +9,7 @@
9
#include "pack-bitmap.h"
10
#include "pack-revindex.h"
11
#include "pack-objects.h"
12
+#include "packfile.h"
13
14
/*
15
* An entry on the bitmap index, representing the bitmap for a given
pack-check.c
+1
@@ -2,6 +2,7 @@
2
#include "pack.h"
3
#include "pack-revindex.h"
4
#include "progress.h"
5
+#include "packfile.h"
6
7
struct idx_entry {
8
off_t offset;
packfile.c
+149
@@ -1,5 +1,6 @@
1
#include "cache.h"
2
#include "mru.h"
3
+#include "pack.h"
4
5
char *odb_pack_name(struct strbuf *buf,
6
const unsigned char *sha1,
@@ -59,3 +60,151 @@ void pack_report(void)
60
pack_open_windows, peak_pack_open_windows,
61
sz_fmt(pack_mapped), sz_fmt(peak_pack_mapped));
62
}
63
+
64
+/*
65
+ * Open and mmap the index file at path, perform a couple of
66
+ * consistency checks, then record its information to p. Return 0 on
67
+ * success.
68
+ */
69
+static int check_packed_git_idx(const char *path, struct packed_git *p)
70
+{
71
+ void *idx_map;
72
+ struct pack_idx_header *hdr;
73
+ size_t idx_size;
74
+ uint32_t version, nr, i, *index;
75
+ int fd = git_open(path);
76
+ struct stat st;
77
+
78
+ if (fd < 0)
79
+ return -1;
80
+ if (fstat(fd, &st)) {
81
+ close(fd);
82
+ return -1;
83
+ }
84
+ idx_size = xsize_t(st.st_size);
85
+ if (idx_size < 4 * 256 + 20 + 20) {
86
+ close(fd);
87
+ return error("index file %s is too small", path);
88
+ }
89
+ idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0);
90
+ close(fd);
91
+
92
+ hdr = idx_map;
93
+ if (hdr->idx_signature == htonl(PACK_IDX_SIGNATURE)) {
94
+ version = ntohl(hdr->idx_version);
95
+ if (version < 2 || version > 2) {
96
+ munmap(idx_map, idx_size);
97
+ return error("index file %s is version %"PRIu32
98
+ " and is not supported by this binary"
99
+ " (try upgrading GIT to a newer version)",
100
+ path, version);
101
+ }
102
+ } else
103
+ version = 1;
104
+
105
+ nr = 0;
106
+ index = idx_map;
107
+ if (version > 1)
108
+ index += 2; /* skip index header */
109
+ for (i = 0; i < 256; i++) {
110
+ uint32_t n = ntohl(index[i]);
111
+ if (n < nr) {
112
+ munmap(idx_map, idx_size);
113
+ return error("non-monotonic index %s", path);
114
+ }
115
+ nr = n;
116
+ }
117
+
118
+ if (version == 1) {
119
+ /*
120
+ * Total size:
121
+ * - 256 index entries 4 bytes each
122
+ * - 24-byte entries * nr (20-byte sha1 + 4-byte offset)
123
+ * - 20-byte SHA1 of the packfile
124
+ * - 20-byte SHA1 file checksum
125
+ */
126
+ if (idx_size != 4*256 + nr * 24 + 20 + 20) {
127
+ munmap(idx_map, idx_size);
128
+ return error("wrong index v1 file size in %s", path);
129
+ }
130
+ } else if (version == 2) {
131
+ /*
132
+ * Minimum size:
133
+ * - 8 bytes of header
134
+ * - 256 index entries 4 bytes each
135
+ * - 20-byte sha1 entry * nr
136
+ * - 4-byte crc entry * nr
137
+ * - 4-byte offset entry * nr
138
+ * - 20-byte SHA1 of the packfile
139
+ * - 20-byte SHA1 file checksum
140
+ * And after the 4-byte offset table might be a
141
+ * variable sized table containing 8-byte entries
142
+ * for offsets larger than 2^31.
143
+ */
144
+ unsigned long min_size = 8 + 4*256 + nr*(20 + 4 + 4) + 20 + 20;
145
+ unsigned long max_size = min_size;
146
+ if (nr)
147
+ max_size += (nr - 1)*8;
148
+ if (idx_size < min_size || idx_size > max_size) {
149
+ munmap(idx_map, idx_size);
150
+ return error("wrong index v2 file size in %s", path);
151
+ }
152
+ if (idx_size != min_size &&
153
+ /*
154
+ * make sure we can deal with large pack offsets.
155
+ * 31-bit signed offset won't be enough, neither
156
+ * 32-bit unsigned one will be.
157
+ */
158
+ (sizeof(off_t) <= 4)) {
159
+ munmap(idx_map, idx_size);
160
+ return error("pack too large for current definition of off_t in %s", path);
161
+ }
162
+ }
163
+
164
+ p->index_version = version;
165
+ p->index_data = idx_map;
166
+ p->index_size = idx_size;
167
+ p->num_objects = nr;
168
+ return 0;
169
+}
170
+
171
+int open_pack_index(struct packed_git *p)
172
+{
173
+ char *idx_name;
174
+ size_t len;
175
+ int ret;
176
+
177
+ if (p->index_data)
178
+ return 0;
179
+
180
+ if (!strip_suffix(p->pack_name, ".pack", &len))
181
+ die("BUG: pack_name does not end in .pack");
182
+ idx_name = xstrfmt("%.*s.idx", (int)len, p->pack_name);
183
+ ret = check_packed_git_idx(idx_name, p);
184
+ free(idx_name);
185
+ return ret;
186
+}
187
+
188
+static struct packed_git *alloc_packed_git(int extra)
189
+{
190
+ struct packed_git *p = xmalloc(st_add(sizeof(*p), extra));
191
+ memset(p, 0, sizeof(*p));
192
+ p->pack_fd = -1;
193
+ return p;
194
+}
195
+
196
+struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
197
+{
198
+ const char *path = sha1_pack_name(sha1);
199
+ size_t alloc = st_add(strlen(path), 1);
200
+ struct packed_git *p = alloc_packed_git(alloc);
201
+
202
+ memcpy(p->pack_name, path, alloc); /* includes NUL */
203
+ hashcpy(p->sha1, sha1);
204
+ if (check_packed_git_idx(idx_path, p)) {
205
+ free(p);
206
+ return NULL;
207
+ }
208
+
209
+ return p;
210
+}
packfile.h
+8
@@ -33,6 +33,14 @@ extern unsigned int pack_max_fds;
33
extern size_t peak_pack_mapped;
34
extern size_t pack_mapped;
35
36
+extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
37
+
38
extern void pack_report(void);
39
40
+/*
41
+ * mmap the index file for the specified packfile (if it is not
42
+ * already mmapped). Return 0 on success.
43
+ */
44
+extern int open_pack_index(struct packed_git *);
45
+
46
#endif
sha1_file.c
-140
@@ -681,130 +681,6 @@ static int has_loose_object(const unsigned char *sha1)
681
return check_and_freshen(sha1, 0);
682
}
683
684
-/*
685
- * Open and mmap the index file at path, perform a couple of
686
- * consistency checks, then record its information to p. Return 0 on
687
- * success.
688
- */
689
-static int check_packed_git_idx(const char *path, struct packed_git *p)
690
-{
691
- void *idx_map;
692
- struct pack_idx_header *hdr;
693
- size_t idx_size;
694
- uint32_t version, nr, i, *index;
695
- int fd = git_open(path);
696
- struct stat st;
697
-
698
- if (fd < 0)
699
- return -1;
700
- if (fstat(fd, &st)) {
701
- close(fd);
702
- return -1;
703
- }
704
- idx_size = xsize_t(st.st_size);
705
- if (idx_size < 4 * 256 + 20 + 20) {
706
- close(fd);
707
- return error("index file %s is too small", path);
708
- }
709
- idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0);
710
- close(fd);
711
-
712
- hdr = idx_map;
713
- if (hdr->idx_signature == htonl(PACK_IDX_SIGNATURE)) {
714
- version = ntohl(hdr->idx_version);
715
- if (version < 2 || version > 2) {
716
- munmap(idx_map, idx_size);
717
- return error("index file %s is version %"PRIu32
718
- " and is not supported by this binary"
719
- " (try upgrading GIT to a newer version)",
720
- path, version);
721
- }
722
- } else
723
- version = 1;
724
-
725
- nr = 0;
726
- index = idx_map;
727
- if (version > 1)
728
- index += 2; /* skip index header */
729
- for (i = 0; i < 256; i++) {
730
- uint32_t n = ntohl(index[i]);
731
- if (n < nr) {
732
- munmap(idx_map, idx_size);
733
- return error("non-monotonic index %s", path);
734
- }
735
- nr = n;
736
- }
737
-
738
- if (version == 1) {
739
- /*
740
- * Total size:
741
- * - 256 index entries 4 bytes each
742
- * - 24-byte entries * nr (20-byte sha1 + 4-byte offset)
743
- * - 20-byte SHA1 of the packfile
744
- * - 20-byte SHA1 file checksum
745
- */
746
- if (idx_size != 4*256 + nr * 24 + 20 + 20) {
747
- munmap(idx_map, idx_size);
748
- return error("wrong index v1 file size in %s", path);
749
- }
750
- } else if (version == 2) {
751
- /*
752
- * Minimum size:
753
- * - 8 bytes of header
754
- * - 256 index entries 4 bytes each
755
- * - 20-byte sha1 entry * nr
756
- * - 4-byte crc entry * nr
757
- * - 4-byte offset entry * nr
758
- * - 20-byte SHA1 of the packfile
759
- * - 20-byte SHA1 file checksum
760
- * And after the 4-byte offset table might be a
761
- * variable sized table containing 8-byte entries
762
- * for offsets larger than 2^31.
763
- */
764
- unsigned long min_size = 8 + 4*256 + nr*(20 + 4 + 4) + 20 + 20;
765
- unsigned long max_size = min_size;
766
- if (nr)
767
- max_size += (nr - 1)*8;
768
- if (idx_size < min_size || idx_size > max_size) {
769
- munmap(idx_map, idx_size);
770
- return error("wrong index v2 file size in %s", path);
771
- }
772
- if (idx_size != min_size &&
773
- /*
774
- * make sure we can deal with large pack offsets.
775
- * 31-bit signed offset won't be enough, neither
776
- * 32-bit unsigned one will be.
777
- */
778
- (sizeof(off_t) <= 4)) {
779
- munmap(idx_map, idx_size);
780
- return error("pack too large for current definition of off_t in %s", path);
781
- }
782
- }
783
-
784
- p->index_version = version;
785
- p->index_data = idx_map;
786
- p->index_size = idx_size;
787
- p->num_objects = nr;
788
- return 0;
789
-}
790
-
791
-int open_pack_index(struct packed_git *p)
792
-{
793
- char *idx_name;
794
- size_t len;
795
- int ret;
796
-
797
- if (p->index_data)
798
- return 0;
799
-
800
- if (!strip_suffix(p->pack_name, ".pack", &len))
801
- die("BUG: pack_name does not end in .pack");
802
- idx_name = xstrfmt("%.*s.idx", (int)len, p->pack_name);
803
- ret = check_packed_git_idx(idx_name, p);
804
- free(idx_name);
805
- return ret;
806
-}
807
-
684
static void scan_windows(struct packed_git *p,
685
struct packed_git **lru_p,
686
struct pack_window **lru_w,
@@ -1302,22 +1178,6 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
1178
return p;
1179
}
1180
1305
-struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
1306
-{
1307
- const char *path = sha1_pack_name(sha1);
1308
- size_t alloc = st_add(strlen(path), 1);
1309
- struct packed_git *p = alloc_packed_git(alloc);
1310
-
1311
- memcpy(p->pack_name, path, alloc); /* includes NUL */
1312
- hashcpy(p->sha1, sha1);
1313
- if (check_packed_git_idx(idx_path, p)) {
1314
- free(p);
1315
- return NULL;
1316
- }
1317
-
1318
- return p;
1319
-}
1320
-
1181
void install_packed_git(struct packed_git *pack)
1182
{
1183
if (pack->pack_fd != -1)
sha1_name.c
+1
@@ -9,6 +9,7 @@
9
#include "remote.h"
10
#include "dir.h"
11
#include "sha1-array.h"
12
+#include "packfile.h"
13
14
static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);
15