OSDN Git Service

pack: move add_packed_git()
[git-core/git.git] / packfile.c
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,
7                     const char *ext)
8 {
9         strbuf_reset(buf);
10         strbuf_addf(buf, "%s/pack/pack-%s.%s", get_object_directory(),
11                     sha1_to_hex(sha1), ext);
12         return buf->buf;
13 }
14
15 char *sha1_pack_name(const unsigned char *sha1)
16 {
17         static struct strbuf buf = STRBUF_INIT;
18         return odb_pack_name(&buf, sha1, "pack");
19 }
20
21 char *sha1_pack_index_name(const unsigned char *sha1)
22 {
23         static struct strbuf buf = STRBUF_INIT;
24         return odb_pack_name(&buf, sha1, "idx");
25 }
26
27 static unsigned int pack_used_ctr;
28 static unsigned int pack_mmap_calls;
29 static unsigned int peak_pack_open_windows;
30 static unsigned int pack_open_windows;
31 unsigned int pack_open_fds;
32 static unsigned int pack_max_fds;
33 static size_t peak_pack_mapped;
34 static size_t pack_mapped;
35 struct packed_git *packed_git;
36
37 static struct mru packed_git_mru_storage;
38 struct mru *packed_git_mru = &packed_git_mru_storage;
39
40 #define SZ_FMT PRIuMAX
41 static inline uintmax_t sz_fmt(size_t s) { return s; }
42
43 void pack_report(void)
44 {
45         fprintf(stderr,
46                 "pack_report: getpagesize()            = %10" SZ_FMT "\n"
47                 "pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n"
48                 "pack_report: core.packedGitLimit      = %10" SZ_FMT "\n",
49                 sz_fmt(getpagesize()),
50                 sz_fmt(packed_git_window_size),
51                 sz_fmt(packed_git_limit));
52         fprintf(stderr,
53                 "pack_report: pack_used_ctr            = %10u\n"
54                 "pack_report: pack_mmap_calls          = %10u\n"
55                 "pack_report: pack_open_windows        = %10u / %10u\n"
56                 "pack_report: pack_mapped              = "
57                         "%10" SZ_FMT " / %10" SZ_FMT "\n",
58                 pack_used_ctr,
59                 pack_mmap_calls,
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 }
211
212 static void scan_windows(struct packed_git *p,
213         struct packed_git **lru_p,
214         struct pack_window **lru_w,
215         struct pack_window **lru_l)
216 {
217         struct pack_window *w, *w_l;
218
219         for (w_l = NULL, w = p->windows; w; w = w->next) {
220                 if (!w->inuse_cnt) {
221                         if (!*lru_w || w->last_used < (*lru_w)->last_used) {
222                                 *lru_p = p;
223                                 *lru_w = w;
224                                 *lru_l = w_l;
225                         }
226                 }
227                 w_l = w;
228         }
229 }
230
231 static int unuse_one_window(struct packed_git *current)
232 {
233         struct packed_git *p, *lru_p = NULL;
234         struct pack_window *lru_w = NULL, *lru_l = NULL;
235
236         if (current)
237                 scan_windows(current, &lru_p, &lru_w, &lru_l);
238         for (p = packed_git; p; p = p->next)
239                 scan_windows(p, &lru_p, &lru_w, &lru_l);
240         if (lru_p) {
241                 munmap(lru_w->base, lru_w->len);
242                 pack_mapped -= lru_w->len;
243                 if (lru_l)
244                         lru_l->next = lru_w->next;
245                 else
246                         lru_p->windows = lru_w->next;
247                 free(lru_w);
248                 pack_open_windows--;
249                 return 1;
250         }
251         return 0;
252 }
253
254 void release_pack_memory(size_t need)
255 {
256         size_t cur = pack_mapped;
257         while (need >= (cur - pack_mapped) && unuse_one_window(NULL))
258                 ; /* nothing */
259 }
260
261 void close_pack_windows(struct packed_git *p)
262 {
263         while (p->windows) {
264                 struct pack_window *w = p->windows;
265
266                 if (w->inuse_cnt)
267                         die("pack '%s' still has open windows to it",
268                             p->pack_name);
269                 munmap(w->base, w->len);
270                 pack_mapped -= w->len;
271                 pack_open_windows--;
272                 p->windows = w->next;
273                 free(w);
274         }
275 }
276
277 static int close_pack_fd(struct packed_git *p)
278 {
279         if (p->pack_fd < 0)
280                 return 0;
281
282         close(p->pack_fd);
283         pack_open_fds--;
284         p->pack_fd = -1;
285
286         return 1;
287 }
288
289 void close_pack_index(struct packed_git *p)
290 {
291         if (p->index_data) {
292                 munmap((void *)p->index_data, p->index_size);
293                 p->index_data = NULL;
294         }
295 }
296
297 static void close_pack(struct packed_git *p)
298 {
299         close_pack_windows(p);
300         close_pack_fd(p);
301         close_pack_index(p);
302 }
303
304 void close_all_packs(void)
305 {
306         struct packed_git *p;
307
308         for (p = packed_git; p; p = p->next)
309                 if (p->do_not_close)
310                         die("BUG: want to close pack marked 'do-not-close'");
311                 else
312                         close_pack(p);
313 }
314
315 /*
316  * The LRU pack is the one with the oldest MRU window, preferring packs
317  * with no used windows, or the oldest mtime if it has no windows allocated.
318  */
319 static void find_lru_pack(struct packed_git *p, struct packed_git **lru_p, struct pack_window **mru_w, int *accept_windows_inuse)
320 {
321         struct pack_window *w, *this_mru_w;
322         int has_windows_inuse = 0;
323
324         /*
325          * Reject this pack if it has windows and the previously selected
326          * one does not.  If this pack does not have windows, reject
327          * it if the pack file is newer than the previously selected one.
328          */
329         if (*lru_p && !*mru_w && (p->windows || p->mtime > (*lru_p)->mtime))
330                 return;
331
332         for (w = this_mru_w = p->windows; w; w = w->next) {
333                 /*
334                  * Reject this pack if any of its windows are in use,
335                  * but the previously selected pack did not have any
336                  * inuse windows.  Otherwise, record that this pack
337                  * has windows in use.
338                  */
339                 if (w->inuse_cnt) {
340                         if (*accept_windows_inuse)
341                                 has_windows_inuse = 1;
342                         else
343                                 return;
344                 }
345
346                 if (w->last_used > this_mru_w->last_used)
347                         this_mru_w = w;
348
349                 /*
350                  * Reject this pack if it has windows that have been
351                  * used more recently than the previously selected pack.
352                  * If the previously selected pack had windows inuse and
353                  * we have not encountered a window in this pack that is
354                  * inuse, skip this check since we prefer a pack with no
355                  * inuse windows to one that has inuse windows.
356                  */
357                 if (*mru_w && *accept_windows_inuse == has_windows_inuse &&
358                     this_mru_w->last_used > (*mru_w)->last_used)
359                         return;
360         }
361
362         /*
363          * Select this pack.
364          */
365         *mru_w = this_mru_w;
366         *lru_p = p;
367         *accept_windows_inuse = has_windows_inuse;
368 }
369
370 static int close_one_pack(void)
371 {
372         struct packed_git *p, *lru_p = NULL;
373         struct pack_window *mru_w = NULL;
374         int accept_windows_inuse = 1;
375
376         for (p = packed_git; p; p = p->next) {
377                 if (p->pack_fd == -1)
378                         continue;
379                 find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse);
380         }
381
382         if (lru_p)
383                 return close_pack_fd(lru_p);
384
385         return 0;
386 }
387
388 static unsigned int get_max_fd_limit(void)
389 {
390 #ifdef RLIMIT_NOFILE
391         {
392                 struct rlimit lim;
393
394                 if (!getrlimit(RLIMIT_NOFILE, &lim))
395                         return lim.rlim_cur;
396         }
397 #endif
398
399 #ifdef _SC_OPEN_MAX
400         {
401                 long open_max = sysconf(_SC_OPEN_MAX);
402                 if (0 < open_max)
403                         return open_max;
404                 /*
405                  * Otherwise, we got -1 for one of the two
406                  * reasons:
407                  *
408                  * (1) sysconf() did not understand _SC_OPEN_MAX
409                  *     and signaled an error with -1; or
410                  * (2) sysconf() said there is no limit.
411                  *
412                  * We _could_ clear errno before calling sysconf() to
413                  * tell these two cases apart and return a huge number
414                  * in the latter case to let the caller cap it to a
415                  * value that is not so selfish, but letting the
416                  * fallback OPEN_MAX codepath take care of these cases
417                  * is a lot simpler.
418                  */
419         }
420 #endif
421
422 #ifdef OPEN_MAX
423         return OPEN_MAX;
424 #else
425         return 1; /* see the caller ;-) */
426 #endif
427 }
428
429 /*
430  * Do not call this directly as this leaks p->pack_fd on error return;
431  * call open_packed_git() instead.
432  */
433 static int open_packed_git_1(struct packed_git *p)
434 {
435         struct stat st;
436         struct pack_header hdr;
437         unsigned char sha1[20];
438         unsigned char *idx_sha1;
439         long fd_flag;
440
441         if (!p->index_data && open_pack_index(p))
442                 return error("packfile %s index unavailable", p->pack_name);
443
444         if (!pack_max_fds) {
445                 unsigned int max_fds = get_max_fd_limit();
446
447                 /* Save 3 for stdin/stdout/stderr, 22 for work */
448                 if (25 < max_fds)
449                         pack_max_fds = max_fds - 25;
450                 else
451                         pack_max_fds = 1;
452         }
453
454         while (pack_max_fds <= pack_open_fds && close_one_pack())
455                 ; /* nothing */
456
457         p->pack_fd = git_open(p->pack_name);
458         if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
459                 return -1;
460         pack_open_fds++;
461
462         /* If we created the struct before we had the pack we lack size. */
463         if (!p->pack_size) {
464                 if (!S_ISREG(st.st_mode))
465                         return error("packfile %s not a regular file", p->pack_name);
466                 p->pack_size = st.st_size;
467         } else if (p->pack_size != st.st_size)
468                 return error("packfile %s size changed", p->pack_name);
469
470         /* We leave these file descriptors open with sliding mmap;
471          * there is no point keeping them open across exec(), though.
472          */
473         fd_flag = fcntl(p->pack_fd, F_GETFD, 0);
474         if (fd_flag < 0)
475                 return error("cannot determine file descriptor flags");
476         fd_flag |= FD_CLOEXEC;
477         if (fcntl(p->pack_fd, F_SETFD, fd_flag) == -1)
478                 return error("cannot set FD_CLOEXEC");
479
480         /* Verify we recognize this pack file format. */
481         if (read_in_full(p->pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
482                 return error("file %s is far too short to be a packfile", p->pack_name);
483         if (hdr.hdr_signature != htonl(PACK_SIGNATURE))
484                 return error("file %s is not a GIT packfile", p->pack_name);
485         if (!pack_version_ok(hdr.hdr_version))
486                 return error("packfile %s is version %"PRIu32" and not"
487                         " supported (try upgrading GIT to a newer version)",
488                         p->pack_name, ntohl(hdr.hdr_version));
489
490         /* Verify the pack matches its index. */
491         if (p->num_objects != ntohl(hdr.hdr_entries))
492                 return error("packfile %s claims to have %"PRIu32" objects"
493                              " while index indicates %"PRIu32" objects",
494                              p->pack_name, ntohl(hdr.hdr_entries),
495                              p->num_objects);
496         if (lseek(p->pack_fd, p->pack_size - sizeof(sha1), SEEK_SET) == -1)
497                 return error("end of packfile %s is unavailable", p->pack_name);
498         if (read_in_full(p->pack_fd, sha1, sizeof(sha1)) != sizeof(sha1))
499                 return error("packfile %s signature is unavailable", p->pack_name);
500         idx_sha1 = ((unsigned char *)p->index_data) + p->index_size - 40;
501         if (hashcmp(sha1, idx_sha1))
502                 return error("packfile %s does not match index", p->pack_name);
503         return 0;
504 }
505
506 int open_packed_git(struct packed_git *p)
507 {
508         if (!open_packed_git_1(p))
509                 return 0;
510         close_pack_fd(p);
511         return -1;
512 }
513
514 static int in_window(struct pack_window *win, off_t offset)
515 {
516         /* We must promise at least 20 bytes (one hash) after the
517          * offset is available from this window, otherwise the offset
518          * is not actually in this window and a different window (which
519          * has that one hash excess) must be used.  This is to support
520          * the object header and delta base parsing routines below.
521          */
522         off_t win_off = win->offset;
523         return win_off <= offset
524                 && (offset + 20) <= (win_off + win->len);
525 }
526
527 unsigned char *use_pack(struct packed_git *p,
528                 struct pack_window **w_cursor,
529                 off_t offset,
530                 unsigned long *left)
531 {
532         struct pack_window *win = *w_cursor;
533
534         /* Since packfiles end in a hash of their content and it's
535          * pointless to ask for an offset into the middle of that
536          * hash, and the in_window function above wouldn't match
537          * don't allow an offset too close to the end of the file.
538          */
539         if (!p->pack_size && p->pack_fd == -1 && open_packed_git(p))
540                 die("packfile %s cannot be accessed", p->pack_name);
541         if (offset > (p->pack_size - 20))
542                 die("offset beyond end of packfile (truncated pack?)");
543         if (offset < 0)
544                 die(_("offset before end of packfile (broken .idx?)"));
545
546         if (!win || !in_window(win, offset)) {
547                 if (win)
548                         win->inuse_cnt--;
549                 for (win = p->windows; win; win = win->next) {
550                         if (in_window(win, offset))
551                                 break;
552                 }
553                 if (!win) {
554                         size_t window_align = packed_git_window_size / 2;
555                         off_t len;
556
557                         if (p->pack_fd == -1 && open_packed_git(p))
558                                 die("packfile %s cannot be accessed", p->pack_name);
559
560                         win = xcalloc(1, sizeof(*win));
561                         win->offset = (offset / window_align) * window_align;
562                         len = p->pack_size - win->offset;
563                         if (len > packed_git_window_size)
564                                 len = packed_git_window_size;
565                         win->len = (size_t)len;
566                         pack_mapped += win->len;
567                         while (packed_git_limit < pack_mapped
568                                 && unuse_one_window(p))
569                                 ; /* nothing */
570                         win->base = xmmap(NULL, win->len,
571                                 PROT_READ, MAP_PRIVATE,
572                                 p->pack_fd, win->offset);
573                         if (win->base == MAP_FAILED)
574                                 die_errno("packfile %s cannot be mapped",
575                                           p->pack_name);
576                         if (!win->offset && win->len == p->pack_size
577                                 && !p->do_not_close)
578                                 close_pack_fd(p);
579                         pack_mmap_calls++;
580                         pack_open_windows++;
581                         if (pack_mapped > peak_pack_mapped)
582                                 peak_pack_mapped = pack_mapped;
583                         if (pack_open_windows > peak_pack_open_windows)
584                                 peak_pack_open_windows = pack_open_windows;
585                         win->next = p->windows;
586                         p->windows = win;
587                 }
588         }
589         if (win != *w_cursor) {
590                 win->last_used = pack_used_ctr++;
591                 win->inuse_cnt++;
592                 *w_cursor = win;
593         }
594         offset -= win->offset;
595         if (left)
596                 *left = win->len - xsize_t(offset);
597         return win->base + offset;
598 }
599
600 void unuse_pack(struct pack_window **w_cursor)
601 {
602         struct pack_window *w = *w_cursor;
603         if (w) {
604                 w->inuse_cnt--;
605                 *w_cursor = NULL;
606         }
607 }
608
609 static void try_to_free_pack_memory(size_t size)
610 {
611         release_pack_memory(size);
612 }
613
614 struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
615 {
616         static int have_set_try_to_free_routine;
617         struct stat st;
618         size_t alloc;
619         struct packed_git *p;
620
621         if (!have_set_try_to_free_routine) {
622                 have_set_try_to_free_routine = 1;
623                 set_try_to_free_routine(try_to_free_pack_memory);
624         }
625
626         /*
627          * Make sure a corresponding .pack file exists and that
628          * the index looks sane.
629          */
630         if (!strip_suffix_mem(path, &path_len, ".idx"))
631                 return NULL;
632
633         /*
634          * ".pack" is long enough to hold any suffix we're adding (and
635          * the use xsnprintf double-checks that)
636          */
637         alloc = st_add3(path_len, strlen(".pack"), 1);
638         p = alloc_packed_git(alloc);
639         memcpy(p->pack_name, path, path_len);
640
641         xsnprintf(p->pack_name + path_len, alloc - path_len, ".keep");
642         if (!access(p->pack_name, F_OK))
643                 p->pack_keep = 1;
644
645         xsnprintf(p->pack_name + path_len, alloc - path_len, ".pack");
646         if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
647                 free(p);
648                 return NULL;
649         }
650
651         /* ok, it looks sane as far as we can check without
652          * actually mapping the pack file.
653          */
654         p->pack_size = st.st_size;
655         p->pack_local = local;
656         p->mtime = st.st_mtime;
657         if (path_len < 40 || get_sha1_hex(path + path_len - 40, p->sha1))
658                 hashclr(p->sha1);
659         return p;
660 }