Changeset 782 for git/branches/dmik/sha1_file.c
- Timestamp:
- Jun 23, 2014, 9:45:51 PM (11 years ago)
- Location:
- git/branches/dmik
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
git/branches/dmik ¶
- Property svn:mergeinfo changed
/git/vendor/2.0.0 (added) merged: 777 /git/vendor/current merged: 772,774,776
- Property svn:mergeinfo changed
-
TabularUnified git/branches/dmik/sha1_file.c ¶
r626 r782 8 8 */ 9 9 #include "cache.h" 10 #include "string-list.h" 10 11 #include "delta.h" 11 12 #include "pack.h" … … 20 21 #include "sha1-lookup.h" 21 22 #include "bulk-checkin.h" 23 #include "streaming.h" 24 #include "dir.h" 22 25 23 26 #ifndef O_NOATIME … … 33 36 34 37 const unsigned char null_sha1[20]; 38 39 static const char *no_log_pack_access = "no_log_pack_access"; 40 static const char *log_pack_access; 35 41 36 42 /* … … 55 61 }; 56 62 63 /* 64 * A pointer to the last packed_git in which an object was found. 65 * When an object is sought, we look in this packfile first, because 66 * objects that are looked up at similar times are often in the same 67 * packfile as one another. 68 */ 57 69 static struct packed_git *last_found_pack; 58 70 … … 100 112 } 101 113 102 int safe_create_leading_directories(char *path) 103 { 104 char *pos = path + offset_1st_component(path); 105 struct stat st; 106 107 while (pos) { 108 pos = strchr(pos, '/'); 109 if (!pos) 114 enum scld_error safe_create_leading_directories(char *path) 115 { 116 char *next_component = path + offset_1st_component(path); 117 enum scld_error ret = SCLD_OK; 118 119 while (ret == SCLD_OK && next_component) { 120 struct stat st; 121 char *slash = next_component, slash_character; 122 123 while (*slash && !is_dir_sep(*slash)) 124 slash++; 125 126 if (!*slash) 110 127 break; 111 while (*++pos == '/') 112 ; 113 if (!*pos) 128 129 next_component = slash + 1; 130 while (is_dir_sep(*next_component)) 131 next_component++; 132 if (!*next_component) 114 133 break; 115 *--pos = '\0'; 134 135 slash_character = *slash; 136 *slash = '\0'; 116 137 if (!stat(path, &st)) { 117 138 /* path exists */ 118 if (!S_ISDIR(st.st_mode)) { 119 *pos = '/'; 120 return -3; 121 } 122 } 123 else if (mkdir(path, 0777)) { 124 *pos = '/'; 125 return -1; 126 } 127 else if (adjust_shared_perm(path)) { 128 *pos = '/'; 129 return -2; 130 } 131 *pos++ = '/'; 132 } 133 return 0; 134 } 135 136 int safe_create_leading_directories_const(const char *path) 139 if (!S_ISDIR(st.st_mode)) 140 ret = SCLD_EXISTS; 141 } else if (mkdir(path, 0777)) { 142 if (errno == EEXIST && 143 !stat(path, &st) && S_ISDIR(st.st_mode)) 144 ; /* somebody created it since we checked */ 145 else if (errno == ENOENT) 146 /* 147 * Either mkdir() failed because 148 * somebody just pruned the containing 149 * directory, or stat() failed because 150 * the file that was in our way was 151 * just removed. Either way, inform 152 * the caller that it might be worth 153 * trying again: 154 */ 155 ret = SCLD_VANISHED; 156 else 157 ret = SCLD_FAILED; 158 } else if (adjust_shared_perm(path)) { 159 ret = SCLD_PERMS; 160 } 161 *slash = slash_character; 162 } 163 return ret; 164 } 165 166 enum scld_error safe_create_leading_directories_const(const char *path) 137 167 { 138 168 /* path points to cache entries, so xstrdup before messing with it */ 139 169 char *buf = xstrdup(path); 140 intresult = safe_create_leading_directories(buf);170 enum scld_error result = safe_create_leading_directories(buf); 141 171 free(buf); 142 172 return result; … … 155 185 } 156 186 157 /* 158 * NOTE! This returns a statically allocated buffer, so you have to be 159 * careful about using it. Do an "xstrdup()" if you need to save the 160 * filename. 161 * 162 * Also note that this returns the location for creating. Reading 163 * SHA1 file can happen from any alternate directory listed in the 164 * DB_ENVIRONMENT environment variable if it is not found in 165 * the primary object database. 166 */ 167 char *sha1_file_name(const unsigned char *sha1) 187 const char *sha1_file_name(const unsigned char *sha1) 168 188 { 169 189 static char buf[PATH_MAX]; … … 185 205 } 186 206 207 /* 208 * Return the name of the pack or index file with the specified sha1 209 * in its filename. *base and *name are scratch space that must be 210 * provided by the caller. which should be "pack" or "idx". 211 */ 187 212 static char *sha1_get_pack_name(const unsigned char *sha1, 188 213 char **name, char **base, const char *which) … … 228 253 struct alternate_object_database *alt_odb_list; 229 254 static struct alternate_object_database **alt_odb_tail; 230 231 static void read_info_alternates(const char * alternates, int depth);232 static int git_open_noatime(const char *name);233 255 234 256 /* … … 247 269 * terminating NUL. 248 270 */ 249 static int link_alt_odb_entry(const char * entry, int len, const char *relative_base, int depth)271 static int link_alt_odb_entry(const char *entry, const char *relative_base, int depth) 250 272 { 251 273 const char *objdir = get_object_directory(); … … 259 281 strbuf_addch(&pathbuf, '/'); 260 282 } 261 strbuf_add (&pathbuf, entry, len);283 strbuf_addstr(&pathbuf, entry); 262 284 263 285 normalize_path_copy(pathbuf.buf, pathbuf.buf); … … 299 321 } 300 322 } 301 if (! memcmp(ent->base, objdir, pfxlen)) {323 if (!strcmp(ent->base, objdir)) { 302 324 free(ent); 303 325 return -1; … … 317 339 } 318 340 319 static void link_alt_odb_entries(const char *alt, const char *ep, int sep,341 static void link_alt_odb_entries(const char *alt, int len, int sep, 320 342 const char *relative_base, int depth) 321 343 { 322 const char *cp, *last; 344 struct string_list entries = STRING_LIST_INIT_NODUP; 345 char *alt_copy; 346 int i; 323 347 324 348 if (depth > 5) { … … 328 352 } 329 353 330 last = alt; 331 while (last < ep) { 332 cp = last; 333 if (cp < ep && *cp == '#') { 334 while (cp < ep && *cp != sep) 335 cp++; 336 last = cp + 1; 354 alt_copy = xmemdupz(alt, len); 355 string_list_split_in_place(&entries, alt_copy, sep, -1); 356 for (i = 0; i < entries.nr; i++) { 357 const char *entry = entries.items[i].string; 358 if (entry[0] == '\0' || entry[0] == '#') 337 359 continue; 338 } 339 while (cp < ep && *cp != sep) 340 cp++; 341 if (last != cp) { 342 if (!is_absolute_path(last) && depth) { 343 error("%s: ignoring relative alternate object store %s", 344 relative_base, last); 345 } else { 346 link_alt_odb_entry(last, cp - last, 347 relative_base, depth); 348 } 349 } 350 while (cp < ep && *cp == sep) 351 cp++; 352 last = cp; 353 } 354 } 355 356 static void read_info_alternates(const char * relative_base, int depth) 360 if (!is_absolute_path(entry) && depth) { 361 error("%s: ignoring relative alternate object store %s", 362 relative_base, entry); 363 } else { 364 link_alt_odb_entry(entry, relative_base, depth); 365 } 366 } 367 string_list_clear(&entries, 0); 368 free(alt_copy); 369 } 370 371 void read_info_alternates(const char * relative_base, int depth) 357 372 { 358 373 char *map; … … 378 393 close(fd); 379 394 380 link_alt_odb_entries(map, map + mapsz, '\n', relative_base, depth);395 link_alt_odb_entries(map, mapsz, '\n', relative_base, depth); 381 396 382 397 munmap(map, mapsz); … … 392 407 die("could not close alternates file"); 393 408 if (alt_odb_tail) 394 link_alt_odb_entries(alt, alt +strlen(alt), '\n', NULL, 0);409 link_alt_odb_entries(alt, strlen(alt), '\n', NULL, 0); 395 410 } 396 411 … … 416 431 417 432 alt_odb_tail = &alt_odb_list; 418 link_alt_odb_entries(alt, alt +strlen(alt), PATH_SEP, NULL, 0);433 link_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0); 419 434 420 435 read_info_alternates(get_object_directory(), 0); … … 423 438 static int has_loose_object_local(const unsigned char *sha1) 424 439 { 425 char *name = sha1_file_name(sha1); 426 return !access(name, F_OK); 440 return !access(sha1_file_name(sha1), F_OK); 427 441 } 428 442 … … 476 490 } 477 491 478 static int check_packed_git_idx(const char *path, struct packed_git *p) 492 /* 493 * Open and mmap the index file at path, perform a couple of 494 * consistency checks, then record its information to p. Return 0 on 495 * success. 496 */ 497 static int check_packed_git_idx(const char *path, struct packed_git *p) 479 498 { 480 499 void *idx_map; … … 612 631 } 613 632 614 static int unuse_one_window(struct packed_git *current , int keep_fd)633 static int unuse_one_window(struct packed_git *current) 615 634 { 616 635 struct packed_git *p, *lru_p = NULL; … … 626 645 if (lru_l) 627 646 lru_l->next = lru_w->next; 628 else {647 else 629 648 lru_p->windows = lru_w->next; 630 if (!lru_p->windows && lru_p->pack_fd != -1631 && lru_p->pack_fd != keep_fd) {632 close(lru_p->pack_fd);633 pack_open_fds--;634 lru_p->pack_fd = -1;635 }636 }637 649 free(lru_w); 638 650 pack_open_windows--; … … 642 654 } 643 655 644 void release_pack_memory(size_t need , int fd)656 void release_pack_memory(size_t need) 645 657 { 646 658 size_t cur = pack_mapped; 647 while (need >= (cur - pack_mapped) && unuse_one_window(NULL , fd))659 while (need >= (cur - pack_mapped) && unuse_one_window(NULL)) 648 660 ; /* nothing */ 649 661 } … … 656 668 if (!length) 657 669 return NULL; 658 release_pack_memory(length , fd);670 release_pack_memory(length); 659 671 ret = mmap(start, length, prot, flags, fd, offset); 660 672 if (ret == MAP_FAILED) … … 680 692 } 681 693 694 /* 695 * The LRU pack is the one with the oldest MRU window, preferring packs 696 * with no used windows, or the oldest mtime if it has no windows allocated. 697 */ 698 static void find_lru_pack(struct packed_git *p, struct packed_git **lru_p, struct pack_window **mru_w, int *accept_windows_inuse) 699 { 700 struct pack_window *w, *this_mru_w; 701 int has_windows_inuse = 0; 702 703 /* 704 * Reject this pack if it has windows and the previously selected 705 * one does not. If this pack does not have windows, reject 706 * it if the pack file is newer than the previously selected one. 707 */ 708 if (*lru_p && !*mru_w && (p->windows || p->mtime > (*lru_p)->mtime)) 709 return; 710 711 for (w = this_mru_w = p->windows; w; w = w->next) { 712 /* 713 * Reject this pack if any of its windows are in use, 714 * but the previously selected pack did not have any 715 * inuse windows. Otherwise, record that this pack 716 * has windows in use. 717 */ 718 if (w->inuse_cnt) { 719 if (*accept_windows_inuse) 720 has_windows_inuse = 1; 721 else 722 return; 723 } 724 725 if (w->last_used > this_mru_w->last_used) 726 this_mru_w = w; 727 728 /* 729 * Reject this pack if it has windows that have been 730 * used more recently than the previously selected pack. 731 * If the previously selected pack had windows inuse and 732 * we have not encountered a window in this pack that is 733 * inuse, skip this check since we prefer a pack with no 734 * inuse windows to one that has inuse windows. 735 */ 736 if (*mru_w && *accept_windows_inuse == has_windows_inuse && 737 this_mru_w->last_used > (*mru_w)->last_used) 738 return; 739 } 740 741 /* 742 * Select this pack. 743 */ 744 *mru_w = this_mru_w; 745 *lru_p = p; 746 *accept_windows_inuse = has_windows_inuse; 747 } 748 749 static int close_one_pack(void) 750 { 751 struct packed_git *p, *lru_p = NULL; 752 struct pack_window *mru_w = NULL; 753 int accept_windows_inuse = 1; 754 755 for (p = packed_git; p; p = p->next) { 756 if (p->pack_fd == -1) 757 continue; 758 find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse); 759 } 760 761 if (lru_p) { 762 close(lru_p->pack_fd); 763 pack_open_fds--; 764 lru_p->pack_fd = -1; 765 return 1; 766 } 767 768 return 0; 769 } 770 682 771 void unuse_pack(struct pack_window **w_cursor) 683 772 { … … 702 791 * the resulting file might be different even if its name would be the 703 792 * same. It is best to close any reference to the old pack before it is 704 * replaced on disk. Of course no index pointers nor windows for given pack793 * replaced on disk. Of course no index pointers or windows for given pack 705 794 * must subsist at this point. If ever objects from this pack are requested 706 795 * again, the new version of the pack will be reinitialized through … … 732 821 } 733 822 823 static unsigned int get_max_fd_limit(void) 824 { 825 #ifdef RLIMIT_NOFILE 826 { 827 struct rlimit lim; 828 829 if (!getrlimit(RLIMIT_NOFILE, &lim)) 830 return lim.rlim_cur; 831 } 832 #endif 833 834 #ifdef _SC_OPEN_MAX 835 { 836 long open_max = sysconf(_SC_OPEN_MAX); 837 if (0 < open_max) 838 return open_max; 839 /* 840 * Otherwise, we got -1 for one of the two 841 * reasons: 842 * 843 * (1) sysconf() did not understand _SC_OPEN_MAX 844 * and signaled an error with -1; or 845 * (2) sysconf() said there is no limit. 846 * 847 * We _could_ clear errno before calling sysconf() to 848 * tell these two cases apart and return a huge number 849 * in the latter case to let the caller cap it to a 850 * value that is not so selfish, but letting the 851 * fallback OPEN_MAX codepath take care of these cases 852 * is a lot simpler. 853 */ 854 } 855 #endif 856 857 #ifdef OPEN_MAX 858 return OPEN_MAX; 859 #else 860 return 1; /* see the caller ;-) */ 861 #endif 862 } 863 734 864 /* 735 865 * Do not call this directly as this leaks p->pack_fd on error return; … … 748 878 749 879 if (!pack_max_fds) { 750 struct rlimit lim; 751 unsigned int max_fds; 752 753 if (getrlimit(RLIMIT_NOFILE, &lim)) 754 die_errno("cannot get RLIMIT_NOFILE"); 755 756 max_fds = lim.rlim_cur; 880 unsigned int max_fds = get_max_fd_limit(); 757 881 758 882 /* Save 3 for stdin/stdout/stderr, 22 for work */ … … 763 887 } 764 888 765 while (pack_max_fds <= pack_open_fds && unuse_one_window(NULL, -1))889 while (pack_max_fds <= pack_open_fds && close_one_pack()) 766 890 ; /* nothing */ 767 891 … … 879 1003 pack_mapped += win->len; 880 1004 while (packed_git_limit < pack_mapped 881 && unuse_one_window(p , p->pack_fd))1005 && unuse_one_window(p)) 882 1006 ; /* nothing */ 883 1007 win->base = xmmap(NULL, win->len, … … 925 1049 static void try_to_free_pack_memory(size_t size) 926 1050 { 927 release_pack_memory(size , -1);1051 release_pack_memory(size); 928 1052 } 929 1053 … … 995 1119 } 996 1120 1121 void (*report_garbage)(const char *desc, const char *path); 1122 1123 static void report_helper(const struct string_list *list, 1124 int seen_bits, int first, int last) 1125 { 1126 const char *msg; 1127 switch (seen_bits) { 1128 case 0: 1129 msg = "no corresponding .idx or .pack"; 1130 break; 1131 case 1: 1132 msg = "no corresponding .idx"; 1133 break; 1134 case 2: 1135 msg = "no corresponding .pack"; 1136 break; 1137 default: 1138 return; 1139 } 1140 for (; first < last; first++) 1141 report_garbage(msg, list->items[first].string); 1142 } 1143 1144 static void report_pack_garbage(struct string_list *list) 1145 { 1146 int i, baselen = -1, first = 0, seen_bits = 0; 1147 1148 if (!report_garbage) 1149 return; 1150 1151 sort_string_list(list); 1152 1153 for (i = 0; i < list->nr; i++) { 1154 const char *path = list->items[i].string; 1155 if (baselen != -1 && 1156 strncmp(path, list->items[first].string, baselen)) { 1157 report_helper(list, seen_bits, first, i); 1158 baselen = -1; 1159 seen_bits = 0; 1160 } 1161 if (baselen == -1) { 1162 const char *dot = strrchr(path, '.'); 1163 if (!dot) { 1164 report_garbage("garbage found", path); 1165 continue; 1166 } 1167 baselen = dot - path + 1; 1168 first = i; 1169 } 1170 if (!strcmp(path + baselen, "pack")) 1171 seen_bits |= 1; 1172 else if (!strcmp(path + baselen, "idx")) 1173 seen_bits |= 2; 1174 } 1175 report_helper(list, seen_bits, first, list->nr); 1176 } 1177 997 1178 static void prepare_packed_git_one(char *objdir, int local) 998 1179 { … … 1004 1185 DIR *dir; 1005 1186 struct dirent *de; 1187 struct string_list garbage = STRING_LIST_INIT_DUP; 1006 1188 1007 1189 sprintf(path, "%s/pack", objdir); … … 1019 1201 struct packed_git *p; 1020 1202 1021 if (!has_extension(de->d_name, ".idx")) 1203 if (len + namelen + 1 > sizeof(path)) { 1204 if (report_garbage) { 1205 struct strbuf sb = STRBUF_INIT; 1206 strbuf_addf(&sb, "%.*s/%s", len - 1, path, de->d_name); 1207 report_garbage("path too long", sb.buf); 1208 strbuf_release(&sb); 1209 } 1022 1210 continue; 1023 1024 if (len + namelen + 1 > sizeof(path)) 1211 } 1212 1213 if (is_dot_or_dotdot(de->d_name)) 1025 1214 continue; 1026 1215 1027 /* Don't reopen a pack we already have. */1028 1216 strcpy(path + len, de->d_name); 1029 for (p = packed_git; p; p = p->next) { 1030 if (!memcmp(path, p->pack_name, len + namelen - 4)) 1031 break; 1032 } 1033 if (p) 1217 1218 if (has_extension(de->d_name, ".idx")) { 1219 /* Don't reopen a pack we already have. */ 1220 for (p = packed_git; p; p = p->next) { 1221 if (!memcmp(path, p->pack_name, len + namelen - 4)) 1222 break; 1223 } 1224 if (p == NULL && 1225 /* 1226 * See if it really is a valid .idx file with 1227 * corresponding .pack file that we can map. 1228 */ 1229 (p = add_packed_git(path, len + namelen, local)) != NULL) 1230 install_packed_git(p); 1231 } 1232 1233 if (!report_garbage) 1034 1234 continue; 1035 /* See if it really is a valid .idx file with corresponding 1036 * .pack file that we can map. 1037 */ 1038 p = add_packed_git(path, len + namelen, local); 1039 if (!p) 1040 continue; 1041 install_packed_git(p); 1235 1236 if (has_extension(de->d_name, ".idx") || 1237 has_extension(de->d_name, ".pack") || 1238 has_extension(de->d_name, ".bitmap") || 1239 has_extension(de->d_name, ".keep")) 1240 string_list_append(&garbage, path); 1241 else 1242 report_garbage("garbage found", path); 1042 1243 } 1043 1244 closedir(dir); 1245 report_pack_garbage(&garbage); 1246 string_list_clear(&garbage, 0); 1044 1247 } 1045 1248 … … 1118 1321 void reprepare_packed_git(void) 1119 1322 { 1120 discard_revindex();1121 1323 prepare_packed_git_run_once = 0; 1122 1324 prepare_packed_git(); … … 1147 1349 } 1148 1350 1149 int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type) 1351 /* 1352 * With an in-core object data in "map", rehash it to make sure the 1353 * object name actually matches "sha1" to detect object corruption. 1354 * With "map" == NULL, try reading the object named with "sha1" using 1355 * the streaming interface and rehash it to do the same. 1356 */ 1357 int check_sha1_signature(const unsigned char *sha1, void *map, 1358 unsigned long size, const char *type) 1150 1359 { 1151 1360 unsigned char real_sha1[20]; 1152 hash_sha1_file(map, size, type, real_sha1); 1361 enum object_type obj_type; 1362 struct git_istream *st; 1363 git_SHA_CTX c; 1364 char hdr[32]; 1365 int hdrlen; 1366 1367 if (map) { 1368 hash_sha1_file(map, size, type, real_sha1); 1369 return hashcmp(sha1, real_sha1) ? -1 : 0; 1370 } 1371 1372 st = open_istream(sha1, &obj_type, &size, NULL); 1373 if (!st) 1374 return -1; 1375 1376 /* Generate the header */ 1377 hdrlen = sprintf(hdr, "%s %lu", typename(obj_type), size) + 1; 1378 1379 /* Sha1.. */ 1380 git_SHA1_Init(&c); 1381 git_SHA1_Update(&c, hdr, hdrlen); 1382 for (;;) { 1383 char buf[1024 * 16]; 1384 ssize_t readlen = read_istream(st, buf, sizeof(buf)); 1385 1386 if (readlen < 0) { 1387 close_istream(st); 1388 return -1; 1389 } 1390 if (!readlen) 1391 break; 1392 git_SHA1_Update(&c, buf, readlen); 1393 } 1394 git_SHA1_Final(real_sha1, &c); 1395 close_istream(st); 1153 1396 return hashcmp(sha1, real_sha1) ? -1 : 0; 1154 1397 } 1155 1398 1156 staticint git_open_noatime(const char *name)1399 int git_open_noatime(const char *name) 1157 1400 { 1158 1401 static int sha1_file_open_flag = O_NOATIME; … … 1173 1416 } 1174 1417 1175 static int open_sha1_file(const unsigned char *sha1) 1176 { 1177 int fd; 1178 char *name = sha1_file_name(sha1); 1418 static int stat_sha1_file(const unsigned char *sha1, struct stat *st) 1419 { 1179 1420 struct alternate_object_database *alt; 1180 1421 1181 fd = git_open_noatime(name); 1182 if (fd >= 0) 1183 return fd; 1422 if (!lstat(sha1_file_name(sha1), st)) 1423 return 0; 1184 1424 1185 1425 prepare_alt_odb(); 1186 1426 errno = ENOENT; 1187 1427 for (alt = alt_odb_list; alt; alt = alt->next) { 1188 name = alt->name; 1189 fill_sha1_path(name, sha1); 1428 fill_sha1_path(alt->name, sha1); 1429 if (!lstat(alt->base, st)) 1430 return 0; 1431 } 1432 1433 return -1; 1434 } 1435 1436 static int open_sha1_file(const unsigned char *sha1) 1437 { 1438 int fd; 1439 struct alternate_object_database *alt; 1440 1441 fd = git_open_noatime(sha1_file_name(sha1)); 1442 if (fd >= 0) 1443 return fd; 1444 1445 prepare_alt_odb(); 1446 errno = ENOENT; 1447 for (alt = alt_odb_list; alt; alt = alt->next) { 1448 fill_sha1_path(alt->name, sha1); 1190 1449 fd = git_open_noatime(alt->base); 1191 1450 if (fd >= 0) … … 1217 1476 } 1218 1477 return map; 1219 }1220 1221 /*1222 * There used to be a second loose object header format which1223 * was meant to mimic the in-pack format, allowing for direct1224 * copy of the object data. This format turned up not to be1225 * really worth it and we no longer write loose objects in that1226 * format.1227 */1228 static int experimental_loose_object(unsigned char *map)1229 {1230 unsigned int word;1231 1232 /*1233 * We must determine if the buffer contains the standard1234 * zlib-deflated stream or the experimental format based1235 * on the in-pack object format. Compare the header byte1236 * for each format:1237 *1238 * RFC1950 zlib w/ deflate : 0www1000 : 0 <= www <= 71239 * Experimental pack-based : Stttssss : ttt = 1,2,3,41240 *1241 * If bit 7 is clear and bits 0-3 equal 8, the buffer MUST be1242 * in standard loose-object format, UNLESS it is a Git-pack1243 * format object *exactly* 8 bytes in size when inflated.1244 *1245 * However, RFC1950 also specifies that the 1st 16-bit word1246 * must be divisible by 31 - this checksum tells us our buffer1247 * is in the standard format, giving a false positive only if1248 * the 1st word of the Git-pack format object happens to be1249 * divisible by 31, ie:1250 * ((byte0 * 256) + byte1) % 31 = 01251 * => 0ttt10000www1000 % 31 = 01252 *1253 * As it happens, this case can only arise for www=3 & ttt=11254 * - ie, a Commit object, which would have to be 8 bytes in1255 * size. As no Commit can be that small, we find that the1256 * combination of these two criteria (bitmask & checksum)1257 * can always correctly determine the buffer format.1258 */1259 word = (map[0] << 8) + map[1];1260 if ((map[0] & 0x8F) == 0x08 && !(word % 31))1261 return 0;1262 else1263 return 1;1264 1478 } 1265 1479 … … 1291 1505 int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz) 1292 1506 { 1293 unsigned long size, used;1294 static const char valid_loose_object_type[8] = {1295 0, /* OBJ_EXT */1296 1, 1, 1, 1, /* "commit", "tree", "blob", "tag" */1297 0, /* "delta" and others are invalid in a loose object */1298 };1299 enum object_type type;1300 1301 1507 /* Get the data stream */ 1302 1508 memset(stream, 0, sizeof(*stream)); … … 1306 1512 stream->avail_out = bufsiz; 1307 1513 1308 if (experimental_loose_object(map)) {1309 /*1310 * The old experimental format we no longer produce;1311 * we can still read it.1312 */1313 used = unpack_object_header_buffer(map, mapsize, &type, &size);1314 if (!used || !valid_loose_object_type[type])1315 return -1;1316 map += used;1317 mapsize -= used;1318 1319 /* Set up the stream for the rest.. */1320 stream->next_in = map;1321 stream->avail_in = mapsize;1322 git_inflate_init(stream);1323 1324 /* And generate the fake traditional header */1325 stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",1326 typename(type), size);1327 return 0;1328 }1329 1514 git_inflate_init(stream); 1330 1515 return git_inflate(stream, 0); … … 1518 1703 } 1519 1704 1520 /* forward declaration for a mutually recursive function */ 1521 static int packed_object_info(struct packed_git *p, off_t offset, 1522 unsigned long *sizep, int *rtype); 1523 1524 static int packed_delta_info(struct packed_git *p, 1525 struct pack_window **w_curs, 1526 off_t curpos, 1527 enum object_type type, 1528 off_t obj_offset, 1529 unsigned long *sizep) 1530 { 1531 off_t base_offset; 1532 1533 base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset); 1534 if (!base_offset) 1535 return OBJ_BAD; 1536 type = packed_object_info(p, base_offset, NULL, NULL); 1537 if (type <= OBJ_NONE) { 1705 /* 1706 * Like get_delta_base above, but we return the sha1 instead of the pack 1707 * offset. This means it is cheaper for REF deltas (we do not have to do 1708 * the final object lookup), but more expensive for OFS deltas (we 1709 * have to load the revidx to convert the offset back into a sha1). 1710 */ 1711 static const unsigned char *get_delta_base_sha1(struct packed_git *p, 1712 struct pack_window **w_curs, 1713 off_t curpos, 1714 enum object_type type, 1715 off_t delta_obj_offset) 1716 { 1717 if (type == OBJ_REF_DELTA) { 1718 unsigned char *base = use_pack(p, w_curs, curpos, NULL); 1719 return base; 1720 } else if (type == OBJ_OFS_DELTA) { 1538 1721 struct revindex_entry *revidx; 1539 const unsigned char *base_sha1; 1722 off_t base_offset = get_delta_base(p, w_curs, &curpos, 1723 type, delta_obj_offset); 1724 1725 if (!base_offset) 1726 return NULL; 1727 1540 1728 revidx = find_pack_revindex(p, base_offset); 1541 1729 if (!revidx) 1542 return OBJ_BAD; 1543 base_sha1 = nth_packed_object_sha1(p, revidx->nr); 1544 mark_bad_packed_object(p, base_sha1); 1545 type = sha1_object_info(base_sha1, NULL); 1546 if (type <= OBJ_NONE) 1547 return OBJ_BAD; 1548 } 1549 1550 /* We choose to only get the type of the base object and 1551 * ignore potentially corrupt pack file that expects the delta 1552 * based on a base with a wrong size. This saves tons of 1553 * inflate() calls. 1554 */ 1555 if (sizep) { 1556 *sizep = get_size_from_delta(p, w_curs, curpos); 1557 if (*sizep == 0) 1558 type = OBJ_BAD; 1559 } 1560 1561 return type; 1730 return NULL; 1731 1732 return nth_packed_object_sha1(p, revidx->nr); 1733 } else 1734 return NULL; 1562 1735 } 1563 1736 … … 1588 1761 } 1589 1762 1590 static int packed_object_info(struct packed_git *p, off_t obj_offset, 1591 unsigned long *sizep, int *rtype) 1592 { 1593 struct pack_window *w_curs = NULL; 1594 unsigned long size; 1595 off_t curpos = obj_offset; 1596 enum object_type type; 1597 1598 type = unpack_object_header(p, &w_curs, &curpos, &size); 1599 if (rtype) 1600 *rtype = type; /* representation type */ 1763 static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset) 1764 { 1765 int type; 1766 struct revindex_entry *revidx; 1767 const unsigned char *sha1; 1768 revidx = find_pack_revindex(p, obj_offset); 1769 if (!revidx) 1770 return OBJ_BAD; 1771 sha1 = nth_packed_object_sha1(p, revidx->nr); 1772 mark_bad_packed_object(p, sha1); 1773 type = sha1_object_info(sha1, NULL); 1774 if (type <= OBJ_NONE) 1775 return OBJ_BAD; 1776 return type; 1777 } 1778 1779 #define POI_STACK_PREALLOC 64 1780 1781 static enum object_type packed_to_object_type(struct packed_git *p, 1782 off_t obj_offset, 1783 enum object_type type, 1784 struct pack_window **w_curs, 1785 off_t curpos) 1786 { 1787 off_t small_poi_stack[POI_STACK_PREALLOC]; 1788 off_t *poi_stack = small_poi_stack; 1789 int poi_stack_nr = 0, poi_stack_alloc = POI_STACK_PREALLOC; 1790 1791 while (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) { 1792 off_t base_offset; 1793 unsigned long size; 1794 /* Push the object we're going to leave behind */ 1795 if (poi_stack_nr >= poi_stack_alloc && poi_stack == small_poi_stack) { 1796 poi_stack_alloc = alloc_nr(poi_stack_nr); 1797 poi_stack = xmalloc(sizeof(off_t)*poi_stack_alloc); 1798 memcpy(poi_stack, small_poi_stack, sizeof(off_t)*poi_stack_nr); 1799 } else { 1800 ALLOC_GROW(poi_stack, poi_stack_nr+1, poi_stack_alloc); 1801 } 1802 poi_stack[poi_stack_nr++] = obj_offset; 1803 /* If parsing the base offset fails, just unwind */ 1804 base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset); 1805 if (!base_offset) 1806 goto unwind; 1807 curpos = obj_offset = base_offset; 1808 type = unpack_object_header(p, w_curs, &curpos, &size); 1809 if (type <= OBJ_NONE) { 1810 /* If getting the base itself fails, we first 1811 * retry the base, otherwise unwind */ 1812 type = retry_bad_packed_offset(p, base_offset); 1813 if (type > OBJ_NONE) 1814 goto out; 1815 goto unwind; 1816 } 1817 } 1601 1818 1602 1819 switch (type) { 1603 case OBJ_OFS_DELTA: 1604 case OBJ_REF_DELTA: 1605 type = packed_delta_info(p, &w_curs, curpos, 1606 type, obj_offset, sizep); 1607 break; 1820 case OBJ_BAD: 1608 1821 case OBJ_COMMIT: 1609 1822 case OBJ_TREE: 1610 1823 case OBJ_BLOB: 1611 1824 case OBJ_TAG: 1612 if (sizep)1613 *sizep = size;1614 1825 break; 1615 1826 default: … … 1618 1829 type = OBJ_BAD; 1619 1830 } 1831 1832 out: 1833 if (poi_stack != small_poi_stack) 1834 free(poi_stack); 1835 return type; 1836 1837 unwind: 1838 while (poi_stack_nr) { 1839 obj_offset = poi_stack[--poi_stack_nr]; 1840 type = retry_bad_packed_offset(p, obj_offset); 1841 if (type > OBJ_NONE) 1842 goto out; 1843 } 1844 type = OBJ_BAD; 1845 goto out; 1846 } 1847 1848 static int packed_object_info(struct packed_git *p, off_t obj_offset, 1849 struct object_info *oi) 1850 { 1851 struct pack_window *w_curs = NULL; 1852 unsigned long size; 1853 off_t curpos = obj_offset; 1854 enum object_type type; 1855 1856 /* 1857 * We always get the representation type, but only convert it to 1858 * a "real" type later if the caller is interested. 1859 */ 1860 type = unpack_object_header(p, &w_curs, &curpos, &size); 1861 1862 if (oi->sizep) { 1863 if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) { 1864 off_t tmp_pos = curpos; 1865 off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos, 1866 type, obj_offset); 1867 if (!base_offset) { 1868 type = OBJ_BAD; 1869 goto out; 1870 } 1871 *oi->sizep = get_size_from_delta(p, &w_curs, tmp_pos); 1872 if (*oi->sizep == 0) { 1873 type = OBJ_BAD; 1874 goto out; 1875 } 1876 } else { 1877 *oi->sizep = size; 1878 } 1879 } 1880 1881 if (oi->disk_sizep) { 1882 struct revindex_entry *revidx = find_pack_revindex(p, obj_offset); 1883 *oi->disk_sizep = revidx[1].offset - obj_offset; 1884 } 1885 1886 if (oi->typep) { 1887 *oi->typep = packed_to_object_type(p, obj_offset, type, &w_curs, curpos); 1888 if (*oi->typep < 0) { 1889 type = OBJ_BAD; 1890 goto out; 1891 } 1892 } 1893 1894 if (oi->delta_base_sha1) { 1895 if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) { 1896 const unsigned char *base; 1897 1898 base = get_delta_base_sha1(p, &w_curs, curpos, 1899 type, obj_offset); 1900 if (!base) { 1901 type = OBJ_BAD; 1902 goto out; 1903 } 1904 1905 hashcpy(oi->delta_base_sha1, base); 1906 } else 1907 hashclr(oi->delta_base_sha1); 1908 } 1909 1910 out: 1620 1911 unuse_pack(&w_curs); 1621 1912 return type; … … 1681 1972 } 1682 1973 1974 static struct delta_base_cache_entry * 1975 get_delta_base_cache_entry(struct packed_git *p, off_t base_offset) 1976 { 1977 unsigned long hash = pack_entry_hash(p, base_offset); 1978 return delta_base_cache + hash; 1979 } 1980 1981 static int eq_delta_base_cache_entry(struct delta_base_cache_entry *ent, 1982 struct packed_git *p, off_t base_offset) 1983 { 1984 return (ent->data && ent->p == p && ent->base_offset == base_offset); 1985 } 1986 1683 1987 static int in_delta_base_cache(struct packed_git *p, off_t base_offset) 1684 1988 { 1685 unsigned long hash = pack_entry_hash(p, base_offset); 1686 struct delta_base_cache_entry *ent = delta_base_cache + hash; 1687 return (ent->data && ent->p == p && ent->base_offset == base_offset); 1989 struct delta_base_cache_entry *ent; 1990 ent = get_delta_base_cache_entry(p, base_offset); 1991 return eq_delta_base_cache_entry(ent, p, base_offset); 1992 } 1993 1994 static void clear_delta_base_cache_entry(struct delta_base_cache_entry *ent) 1995 { 1996 ent->data = NULL; 1997 ent->lru.next->prev = ent->lru.prev; 1998 ent->lru.prev->next = ent->lru.next; 1999 delta_base_cached -= ent->size; 1688 2000 } 1689 2001 … … 1691 2003 unsigned long *base_size, enum object_type *type, int keep_cache) 1692 2004 { 2005 struct delta_base_cache_entry *ent; 1693 2006 void *ret; 1694 unsigned long hash = pack_entry_hash(p, base_offset); 1695 struct delta_base_cache_entry *ent = delta_base_cache + hash; 2007 2008 ent = get_delta_base_cache_entry(p, base_offset); 2009 2010 if (!eq_delta_base_cache_entry(ent, p, base_offset)) 2011 return unpack_entry(p, base_offset, type, base_size); 1696 2012 1697 2013 ret = ent->data; 1698 if (!ret || ent->p != p || ent->base_offset != base_offset) 1699 return unpack_entry(p, base_offset, type, base_size); 1700 1701 if (!keep_cache) { 1702 ent->data = NULL; 1703 ent->lru.next->prev = ent->lru.prev; 1704 ent->lru.prev->next = ent->lru.next; 1705 delta_base_cached -= ent->size; 1706 } else { 2014 2015 if (!keep_cache) 2016 clear_delta_base_cache_entry(ent); 2017 else 1707 2018 ret = xmemdupz(ent->data, ent->size); 1708 }1709 2019 *type = ent->type; 1710 2020 *base_size = ent->size; … … 1770 2080 unsigned long *size); 1771 2081 1772 static void *unpack_delta_entry(struct packed_git *p,1773 struct pack_window **w_curs,1774 off_t curpos,1775 unsigned long delta_size,1776 off_t obj_offset,1777 enum object_type *type,1778 unsigned long *sizep)1779 {1780 void *delta_data, *result, *base;1781 unsigned long base_size;1782 off_t base_offset;1783 1784 base_offset = get_delta_base(p, w_curs, &curpos, *type, obj_offset);1785 if (!base_offset) {1786 error("failed to validate delta base reference "1787 "at offset %"PRIuMAX" from %s",1788 (uintmax_t)curpos, p->pack_name);1789 return NULL;1790 }1791 unuse_pack(w_curs);1792 base = cache_or_unpack_entry(p, base_offset, &base_size, type, 0);1793 if (!base) {1794 /*1795 * We're probably in deep shit, but let's try to fetch1796 * the required base anyway from another pack or loose.1797 * This is costly but should happen only in the presence1798 * of a corrupted pack, and is better than failing outright.1799 */1800 struct revindex_entry *revidx;1801 const unsigned char *base_sha1;1802 revidx = find_pack_revindex(p, base_offset);1803 if (!revidx)1804 return NULL;1805 base_sha1 = nth_packed_object_sha1(p, revidx->nr);1806 error("failed to read delta base object %s"1807 " at offset %"PRIuMAX" from %s",1808 sha1_to_hex(base_sha1), (uintmax_t)base_offset,1809 p->pack_name);1810 mark_bad_packed_object(p, base_sha1);1811 base = read_object(base_sha1, type, &base_size);1812 if (!base)1813 return NULL;1814 }1815 1816 delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size);1817 if (!delta_data) {1818 error("failed to unpack compressed delta "1819 "at offset %"PRIuMAX" from %s",1820 (uintmax_t)curpos, p->pack_name);1821 free(base);1822 return NULL;1823 }1824 result = patch_delta(base, base_size,1825 delta_data, delta_size,1826 sizep);1827 if (!result)1828 die("failed to apply delta");1829 free(delta_data);1830 add_delta_base_cache(p, base_offset, base, base_size, *type);1831 return result;1832 }1833 1834 2082 static void write_pack_access_log(struct packed_git *p, off_t obj_offset) 1835 2083 { 1836 2084 static FILE *log_file; 2085 2086 if (!log_pack_access) 2087 log_pack_access = getenv("GIT_TRACE_PACK_ACCESS"); 2088 if (!log_pack_access) 2089 log_pack_access = no_log_pack_access; 2090 if (log_pack_access == no_log_pack_access) 2091 return; 1837 2092 1838 2093 if (!log_file) { … … 1841 2096 error("cannot open pack access log '%s' for writing: %s", 1842 2097 log_pack_access, strerror(errno)); 1843 log_pack_access = NULL;2098 log_pack_access = no_log_pack_access; 1844 2099 return; 1845 2100 } … … 1852 2107 int do_check_packed_object_crc; 1853 2108 2109 #define UNPACK_ENTRY_STACK_PREALLOC 64 2110 struct unpack_entry_stack_ent { 2111 off_t obj_offset; 2112 off_t curpos; 2113 unsigned long size; 2114 }; 2115 1854 2116 void *unpack_entry(struct packed_git *p, off_t obj_offset, 1855 enum object_type * type, unsigned long *sizep)2117 enum object_type *final_type, unsigned long *final_size) 1856 2118 { 1857 2119 struct pack_window *w_curs = NULL; 1858 2120 off_t curpos = obj_offset; 1859 void *data; 1860 1861 if (log_pack_access) 2121 void *data = NULL; 2122 unsigned long size; 2123 enum object_type type; 2124 struct unpack_entry_stack_ent small_delta_stack[UNPACK_ENTRY_STACK_PREALLOC]; 2125 struct unpack_entry_stack_ent *delta_stack = small_delta_stack; 2126 int delta_stack_nr = 0, delta_stack_alloc = UNPACK_ENTRY_STACK_PREALLOC; 2127 int base_from_cache = 0; 2128 2129 if (log_pack_access != no_log_pack_access) 1862 2130 write_pack_access_log(p, obj_offset); 1863 2131 1864 if (do_check_packed_object_crc && p->index_version > 1) { 1865 struct revindex_entry *revidx = find_pack_revindex(p, obj_offset); 1866 unsigned long len = revidx[1].offset - obj_offset; 1867 if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) { 1868 const unsigned char *sha1 = 1869 nth_packed_object_sha1(p, revidx->nr); 1870 error("bad packed object CRC for %s", 1871 sha1_to_hex(sha1)); 1872 mark_bad_packed_object(p, sha1); 1873 unuse_pack(&w_curs); 1874 return NULL; 1875 } 1876 } 1877 1878 *type = unpack_object_header(p, &w_curs, &curpos, sizep); 1879 switch (*type) { 2132 /* PHASE 1: drill down to the innermost base object */ 2133 for (;;) { 2134 off_t base_offset; 2135 int i; 2136 struct delta_base_cache_entry *ent; 2137 2138 ent = get_delta_base_cache_entry(p, curpos); 2139 if (eq_delta_base_cache_entry(ent, p, curpos)) { 2140 type = ent->type; 2141 data = ent->data; 2142 size = ent->size; 2143 clear_delta_base_cache_entry(ent); 2144 base_from_cache = 1; 2145 break; 2146 } 2147 2148 if (do_check_packed_object_crc && p->index_version > 1) { 2149 struct revindex_entry *revidx = find_pack_revindex(p, obj_offset); 2150 unsigned long len = revidx[1].offset - obj_offset; 2151 if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) { 2152 const unsigned char *sha1 = 2153 nth_packed_object_sha1(p, revidx->nr); 2154 error("bad packed object CRC for %s", 2155 sha1_to_hex(sha1)); 2156 mark_bad_packed_object(p, sha1); 2157 unuse_pack(&w_curs); 2158 return NULL; 2159 } 2160 } 2161 2162 type = unpack_object_header(p, &w_curs, &curpos, &size); 2163 if (type != OBJ_OFS_DELTA && type != OBJ_REF_DELTA) 2164 break; 2165 2166 base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset); 2167 if (!base_offset) { 2168 error("failed to validate delta base reference " 2169 "at offset %"PRIuMAX" from %s", 2170 (uintmax_t)curpos, p->pack_name); 2171 /* bail to phase 2, in hopes of recovery */ 2172 data = NULL; 2173 break; 2174 } 2175 2176 /* push object, proceed to base */ 2177 if (delta_stack_nr >= delta_stack_alloc 2178 && delta_stack == small_delta_stack) { 2179 delta_stack_alloc = alloc_nr(delta_stack_nr); 2180 delta_stack = xmalloc(sizeof(*delta_stack)*delta_stack_alloc); 2181 memcpy(delta_stack, small_delta_stack, 2182 sizeof(*delta_stack)*delta_stack_nr); 2183 } else { 2184 ALLOC_GROW(delta_stack, delta_stack_nr+1, delta_stack_alloc); 2185 } 2186 i = delta_stack_nr++; 2187 delta_stack[i].obj_offset = obj_offset; 2188 delta_stack[i].curpos = curpos; 2189 delta_stack[i].size = size; 2190 2191 curpos = obj_offset = base_offset; 2192 } 2193 2194 /* PHASE 2: handle the base */ 2195 switch (type) { 1880 2196 case OBJ_OFS_DELTA: 1881 2197 case OBJ_REF_DELTA: 1882 data = unpack_delta_entry(p, &w_curs, curpos, *sizep,1883 obj_offset, type, sizep);2198 if (data) 2199 die("BUG in unpack_entry: left loop at a valid delta"); 1884 2200 break; 1885 2201 case OBJ_COMMIT: … … 1887 2203 case OBJ_BLOB: 1888 2204 case OBJ_TAG: 1889 data = unpack_compressed_entry(p, &w_curs, curpos, *sizep); 2205 if (!base_from_cache) 2206 data = unpack_compressed_entry(p, &w_curs, curpos, size); 1890 2207 break; 1891 2208 default: 1892 2209 data = NULL; 1893 2210 error("unknown object type %i at offset %"PRIuMAX" in %s", 1894 *type, (uintmax_t)obj_offset, p->pack_name); 1895 } 2211 type, (uintmax_t)obj_offset, p->pack_name); 2212 } 2213 2214 /* PHASE 3: apply deltas in order */ 2215 2216 /* invariants: 2217 * 'data' holds the base data, or NULL if there was corruption 2218 */ 2219 while (delta_stack_nr) { 2220 void *delta_data; 2221 void *base = data; 2222 unsigned long delta_size, base_size = size; 2223 int i; 2224 2225 data = NULL; 2226 2227 if (base) 2228 add_delta_base_cache(p, obj_offset, base, base_size, type); 2229 2230 if (!base) { 2231 /* 2232 * We're probably in deep shit, but let's try to fetch 2233 * the required base anyway from another pack or loose. 2234 * This is costly but should happen only in the presence 2235 * of a corrupted pack, and is better than failing outright. 2236 */ 2237 struct revindex_entry *revidx; 2238 const unsigned char *base_sha1; 2239 revidx = find_pack_revindex(p, obj_offset); 2240 if (revidx) { 2241 base_sha1 = nth_packed_object_sha1(p, revidx->nr); 2242 error("failed to read delta base object %s" 2243 " at offset %"PRIuMAX" from %s", 2244 sha1_to_hex(base_sha1), (uintmax_t)obj_offset, 2245 p->pack_name); 2246 mark_bad_packed_object(p, base_sha1); 2247 base = read_object(base_sha1, &type, &base_size); 2248 } 2249 } 2250 2251 i = --delta_stack_nr; 2252 obj_offset = delta_stack[i].obj_offset; 2253 curpos = delta_stack[i].curpos; 2254 delta_size = delta_stack[i].size; 2255 2256 if (!base) 2257 continue; 2258 2259 delta_data = unpack_compressed_entry(p, &w_curs, curpos, delta_size); 2260 2261 if (!delta_data) { 2262 error("failed to unpack compressed delta " 2263 "at offset %"PRIuMAX" from %s", 2264 (uintmax_t)curpos, p->pack_name); 2265 data = NULL; 2266 continue; 2267 } 2268 2269 data = patch_delta(base, base_size, 2270 delta_data, delta_size, 2271 &size); 2272 2273 /* 2274 * We could not apply the delta; warn the user, but keep going. 2275 * Our failure will be noticed either in the next iteration of 2276 * the loop, or if this is the final delta, in the caller when 2277 * we return NULL. Those code paths will take care of making 2278 * a more explicit warning and retrying with another copy of 2279 * the object. 2280 */ 2281 if (!data) 2282 error("failed to apply delta"); 2283 2284 free(delta_data); 2285 } 2286 2287 *final_type = type; 2288 *final_size = size; 2289 1896 2290 unuse_pack(&w_curs); 2291 2292 if (delta_stack != small_delta_stack) 2293 free(delta_stack); 2294 1897 2295 return data; 1898 2296 } … … 2054 2452 } 2055 2453 2454 /* 2455 * Iff a pack file contains the object named by sha1, return true and 2456 * store its location to e. 2457 */ 2056 2458 static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e) 2057 2459 { … … 2066 2468 2067 2469 for (p = packed_git; p; p = p->next) { 2068 if (p == last_found_pack || !fill_pack_entry(sha1, e, p)) 2069 continue; 2070 2071 last_found_pack = p; 2072 return 1; 2470 if (p == last_found_pack) 2471 continue; /* we already checked this one */ 2472 2473 if (fill_pack_entry(sha1, e, p)) { 2474 last_found_pack = p; 2475 return 1; 2476 } 2073 2477 } 2074 2478 return 0; … … 2088 2492 } 2089 2493 2090 static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *sizep) 2494 static int sha1_loose_object_info(const unsigned char *sha1, 2495 struct object_info *oi) 2091 2496 { 2092 2497 int status; … … 2096 2501 char hdr[32]; 2097 2502 2503 if (oi->delta_base_sha1) 2504 hashclr(oi->delta_base_sha1); 2505 2506 /* 2507 * If we don't care about type or size, then we don't 2508 * need to look inside the object at all. Note that we 2509 * do not optimize out the stat call, even if the 2510 * caller doesn't care about the disk-size, since our 2511 * return value implicitly indicates whether the 2512 * object even exists. 2513 */ 2514 if (!oi->typep && !oi->sizep) { 2515 struct stat st; 2516 if (stat_sha1_file(sha1, &st) < 0) 2517 return -1; 2518 if (oi->disk_sizep) 2519 *oi->disk_sizep = st.st_size; 2520 return 0; 2521 } 2522 2098 2523 map = map_sha1_file(sha1, &mapsize); 2099 2524 if (!map) 2100 return error("unable to find %s", sha1_to_hex(sha1)); 2525 return -1; 2526 if (oi->disk_sizep) 2527 *oi->disk_sizep = mapsize; 2101 2528 if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0) 2102 2529 status = error("unable to unpack %s header", … … 2104 2531 else if ((status = parse_sha1_header(hdr, &size)) < 0) 2105 2532 status = error("unable to parse %s header", sha1_to_hex(sha1)); 2106 else if ( sizep)2107 * sizep = size;2533 else if (oi->sizep) 2534 *oi->sizep = size; 2108 2535 git_inflate_end(&stream); 2109 2536 munmap(map, mapsize); 2110 return status; 2111 } 2112 2113 /* returns enum object_type or negative */ 2114 int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi) 2537 if (oi->typep) 2538 *oi->typep = status; 2539 return 0; 2540 } 2541 2542 int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, unsigned flags) 2115 2543 { 2116 2544 struct cached_object *co; 2117 2545 struct pack_entry e; 2118 int status, rtype; 2119 2120 co = find_cached_object(sha1); 2546 int rtype; 2547 const unsigned char *real = lookup_replace_object_extended(sha1, flags); 2548 2549 co = find_cached_object(real); 2121 2550 if (co) { 2551 if (oi->typep) 2552 *(oi->typep) = co->type; 2122 2553 if (oi->sizep) 2123 2554 *(oi->sizep) = co->size; 2555 if (oi->disk_sizep) 2556 *(oi->disk_sizep) = 0; 2557 if (oi->delta_base_sha1) 2558 hashclr(oi->delta_base_sha1); 2124 2559 oi->whence = OI_CACHED; 2125 return co->type;2126 } 2127 2128 if (!find_pack_entry( sha1, &e)) {2560 return 0; 2561 } 2562 2563 if (!find_pack_entry(real, &e)) { 2129 2564 /* Most likely it's a loose object. */ 2130 status = sha1_loose_object_info(sha1, oi->sizep); 2131 if (status >= 0) { 2565 if (!sha1_loose_object_info(real, oi)) { 2132 2566 oi->whence = OI_LOOSE; 2133 return status;2567 return 0; 2134 2568 } 2135 2569 2136 2570 /* Not a loose object; someone else may have just packed it. */ 2137 2571 reprepare_packed_git(); 2138 if (!find_pack_entry( sha1, &e))2139 return status;2140 } 2141 2142 status = packed_object_info(e.p, e.offset, oi->sizep, &rtype);2143 if ( status< 0) {2144 mark_bad_packed_object(e.p, sha1);2145 status = sha1_object_info_extended(sha1, oi);2572 if (!find_pack_entry(real, &e)) 2573 return -1; 2574 } 2575 2576 rtype = packed_object_info(e.p, e.offset, oi); 2577 if (rtype < 0) { 2578 mark_bad_packed_object(e.p, real); 2579 return sha1_object_info_extended(real, oi, 0); 2146 2580 } else if (in_delta_base_cache(e.p, e.offset)) { 2147 2581 oi->whence = OI_DBCACHED; … … 2154 2588 } 2155 2589 2156 return status; 2157 } 2158 2590 return 0; 2591 } 2592 2593 /* returns enum object_type or negative */ 2159 2594 int sha1_object_info(const unsigned char *sha1, unsigned long *sizep) 2160 2595 { 2161 struct object_info oi; 2162 2596 enum object_type type; 2597 struct object_info oi = {NULL}; 2598 2599 oi.typep = &type; 2163 2600 oi.sizep = sizep; 2164 return sha1_object_info_extended(sha1, &oi); 2601 if (sha1_object_info_extended(sha1, &oi, LOOKUP_REPLACE_OBJECT) < 0) 2602 return -1; 2603 return type; 2165 2604 } 2166 2605 … … 2197 2636 if (has_sha1_file(sha1) || find_cached_object(sha1)) 2198 2637 return 0; 2199 if (cached_object_alloc <= cached_object_nr) { 2200 cached_object_alloc = alloc_nr(cached_object_alloc); 2201 cached_objects = xrealloc(cached_objects, 2202 sizeof(*cached_objects) * 2203 cached_object_alloc); 2204 } 2638 ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc); 2205 2639 co = &cached_objects[cached_object_nr++]; 2206 2640 co->size = len; … … 2250 2684 { 2251 2685 void *data; 2252 char *path;2253 2686 const struct packed_git *p; 2254 const unsigned char *repl = (flag & READ_SHA1_FILE_REPLACE) 2255 ? lookup_replace_object(sha1) : sha1; 2687 const unsigned char *repl = lookup_replace_object_extended(sha1, flag); 2256 2688 2257 2689 errno = 0; … … 2269 2701 2270 2702 if (has_loose_object(repl)) { 2271 path = sha1_file_name(sha1); 2703 const char *path = sha1_file_name(sha1); 2704 2272 2705 die("loose object %s (stored in %s) is corrupt", 2273 2706 sha1_to_hex(repl), path); … … 2380 2813 if (ret) { 2381 2814 if (ret != EEXIST) { 2382 return error("unable to write sha1 filename %s: %s \n", filename, strerror(ret));2815 return error("unable to write sha1 filename %s: %s", filename, strerror(ret)); 2383 2816 } 2384 2817 /* FIXME!!! Collision check here ? */ … … 2447 2880 memcpy(buffer, filename, dirlen); 2448 2881 buffer[dirlen-1] = 0; 2449 if (mkdir(buffer, 0777) || adjust_shared_perm(buffer)) 2882 if (mkdir(buffer, 0777) && errno != EEXIST) 2883 return -1; 2884 if (adjust_shared_perm(buffer)) 2450 2885 return -1; 2451 2886 … … 2465 2900 git_SHA_CTX c; 2466 2901 unsigned char parano_sha1[20]; 2467 char *filename;2468 2902 static char tmp_file[PATH_MAX]; 2469 2470 filename = sha1_file_name(sha1); 2903 const char *filename = sha1_file_name(sha1); 2904 2471 2905 fd = create_tmpfile(tmp_file, sizeof(tmp_file), filename); 2472 2906 if (fd < 0) { 2473 2907 if (errno == EACCES) 2474 return error("insufficient permission for adding an object to repository database %s \n", get_object_directory());2908 return error("insufficient permission for adding an object to repository database %s", get_object_directory()); 2475 2909 else 2476 return error("unable to create temporary sha1 filename %s: %s\n", tmp_file, strerror(errno));2910 return error("unable to create temporary file: %s", strerror(errno)); 2477 2911 } 2478 2912 … … 2585 3019 if (find_pack_entry(sha1, &e)) 2586 3020 return 1; 2587 return has_loose_object(sha1); 3021 if (has_loose_object(sha1)) 3022 return 1; 3023 reprepare_packed_git(); 3024 return find_pack_entry(sha1, &e); 2588 3025 } 2589 3026
Note:
See TracChangeset
for help on using the changeset viewer.