Git fork

csum-file: stop depending on `the_repository`

There are multiple sites in "csum-file.c" where we use the global
`the_repository` variable, either explicitly or implicitly by using
`the_hash_algo`.

Refactor the code to stop using `the_repository` by adapting functions
to receive required data as parameters. Adapt callsites accordingly by
either using `the_repository->hash_algo`, or by using a context-provided
hash algorithm in case the subsystem already got rid of its dependency
on `the_repository`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
228457c9 e969bc87

+56 -39
+1 -1
builtin/fast-import.c
··· 770 p->pack_fd = pack_fd; 771 p->do_not_close = 1; 772 p->repo = the_repository; 773 - pack_file = hashfd(pack_fd, p->pack_name); 774 775 pack_data = p; 776 pack_size = write_pack_header(pack_file, 0);
··· 770 p->pack_fd = pack_fd; 771 p->do_not_close = 1; 772 p->repo = the_repository; 773 + pack_file = hashfd(the_repository->hash_algo, pack_fd, p->pack_name); 774 775 pack_data = p; 776 pack_size = write_pack_header(pack_file, 0);
+1 -1
builtin/index-pack.c
··· 1381 REALLOC_ARRAY(objects, nr_objects + nr_unresolved + 1); 1382 memset(objects + nr_objects + 1, 0, 1383 nr_unresolved * sizeof(*objects)); 1384 - f = hashfd(output_fd, curr_pack); 1385 fix_unresolved_deltas(f); 1386 strbuf_addf(&msg, Q_("completed with %d local object", 1387 "completed with %d local objects",
··· 1381 REALLOC_ARRAY(objects, nr_objects + nr_unresolved + 1); 1382 memset(objects + nr_objects + 1, 0, 1383 nr_unresolved * sizeof(*objects)); 1384 + f = hashfd(the_repository->hash_algo, output_fd, curr_pack); 1385 fix_unresolved_deltas(f); 1386 strbuf_addf(&msg, Q_("completed with %d local object", 1387 "completed with %d local objects",
+2 -1
builtin/pack-objects.c
··· 1311 char *pack_tmp_name = NULL; 1312 1313 if (pack_to_stdout) 1314 - f = hashfd_throughput(1, "<stdout>", progress_state); 1315 else 1316 f = create_tmp_packfile(&pack_tmp_name); 1317
··· 1311 char *pack_tmp_name = NULL; 1312 1313 if (pack_to_stdout) 1314 + f = hashfd_throughput(the_repository->hash_algo, 1, 1315 + "<stdout>", progress_state); 1316 else 1317 f = create_tmp_packfile(&pack_tmp_name); 1318
+6 -3
commit-graph.c
··· 2090 return -1; 2091 } 2092 2093 - f = hashfd(get_tempfile_fd(graph_layer), get_tempfile_path(graph_layer)); 2094 } else { 2095 hold_lock_file_for_update_mode(&lk, ctx->graph_name, 2096 LOCK_DIE_ON_ERROR, 0444); 2097 - f = hashfd(get_lock_file_fd(&lk), get_lock_file_path(&lk)); 2098 } 2099 2100 cf = init_chunkfile(f); ··· 2716 2717 static int commit_graph_checksum_valid(struct commit_graph *g) 2718 { 2719 - return hashfile_checksum_valid(g->data, g->data_len); 2720 } 2721 2722 static int verify_one_commit_graph(struct repository *r,
··· 2090 return -1; 2091 } 2092 2093 + f = hashfd(the_repository->hash_algo, 2094 + get_tempfile_fd(graph_layer), get_tempfile_path(graph_layer)); 2095 } else { 2096 hold_lock_file_for_update_mode(&lk, ctx->graph_name, 2097 LOCK_DIE_ON_ERROR, 0444); 2098 + f = hashfd(the_repository->hash_algo, 2099 + get_lock_file_fd(&lk), get_lock_file_path(&lk)); 2100 } 2101 2102 cf = init_chunkfile(f); ··· 2718 2719 static int commit_graph_checksum_valid(struct commit_graph *g) 2720 { 2721 + return hashfile_checksum_valid(the_repository->hash_algo, 2722 + g->data, g->data_len); 2723 } 2724 2725 static int verify_one_commit_graph(struct repository *r,
+16 -12
csum-file.c
··· 8 * able to verify hasn't been messed with afterwards. 9 */ 10 11 - #define USE_THE_REPOSITORY_VARIABLE 12 - 13 #include "git-compat-util.h" 14 #include "csum-file.h" 15 #include "git-zlib.h" ··· 148 } 149 } 150 151 - struct hashfile *hashfd_check(const char *name) 152 { 153 int sink, check; 154 struct hashfile *f; 155 156 sink = xopen("/dev/null", O_WRONLY); 157 check = xopen(name, O_RDONLY); 158 - f = hashfd(sink, name); 159 f->check_fd = check; 160 f->check_buffer = xmalloc(f->buffer_len); 161 162 return f; 163 } 164 165 - static struct hashfile *hashfd_internal(int fd, const char *name, 166 struct progress *tp, 167 size_t buffer_len) 168 { ··· 176 f->do_crc = 0; 177 f->skip_hash = 0; 178 179 - f->algop = unsafe_hash_algo(the_hash_algo); 180 f->algop->init_fn(&f->ctx); 181 182 f->buffer_len = buffer_len; ··· 186 return f; 187 } 188 189 - struct hashfile *hashfd(int fd, const char *name) 190 { 191 /* 192 * Since we are not going to use a progress meter to 193 * measure the rate of data passing through this hashfile, 194 * use a larger buffer size to reduce fsync() calls. 195 */ 196 - return hashfd_internal(fd, name, NULL, 128 * 1024); 197 } 198 199 - struct hashfile *hashfd_throughput(int fd, const char *name, struct progress *tp) 200 { 201 /* 202 * Since we are expecting to report progress of the ··· 204 * size so the progress indicators arrive at a more 205 * frequent rate. 206 */ 207 - return hashfd_internal(fd, name, tp, 8 * 1024); 208 } 209 210 void hashfile_checkpoint_init(struct hashfile *f, ··· 246 return f->crc32; 247 } 248 249 - int hashfile_checksum_valid(const unsigned char *data, size_t total_len) 250 { 251 unsigned char got[GIT_MAX_RAWSZ]; 252 struct git_hash_ctx ctx; 253 - const struct git_hash_algo *algop = unsafe_hash_algo(the_hash_algo); 254 size_t data_len = total_len - algop->rawsz; 255 256 if (total_len < algop->rawsz) 257 return 0; /* say "too short"? */
··· 8 * able to verify hasn't been messed with afterwards. 9 */ 10 11 #include "git-compat-util.h" 12 #include "csum-file.h" 13 #include "git-zlib.h" ··· 146 } 147 } 148 149 + struct hashfile *hashfd_check(const struct git_hash_algo *algop, 150 + const char *name) 151 { 152 int sink, check; 153 struct hashfile *f; 154 155 sink = xopen("/dev/null", O_WRONLY); 156 check = xopen(name, O_RDONLY); 157 + f = hashfd(algop, sink, name); 158 f->check_fd = check; 159 f->check_buffer = xmalloc(f->buffer_len); 160 161 return f; 162 } 163 164 + static struct hashfile *hashfd_internal(const struct git_hash_algo *algop, 165 + int fd, const char *name, 166 struct progress *tp, 167 size_t buffer_len) 168 { ··· 176 f->do_crc = 0; 177 f->skip_hash = 0; 178 179 + f->algop = unsafe_hash_algo(algop); 180 f->algop->init_fn(&f->ctx); 181 182 f->buffer_len = buffer_len; ··· 186 return f; 187 } 188 189 + struct hashfile *hashfd(const struct git_hash_algo *algop, 190 + int fd, const char *name) 191 { 192 /* 193 * Since we are not going to use a progress meter to 194 * measure the rate of data passing through this hashfile, 195 * use a larger buffer size to reduce fsync() calls. 196 */ 197 + return hashfd_internal(algop, fd, name, NULL, 128 * 1024); 198 } 199 200 + struct hashfile *hashfd_throughput(const struct git_hash_algo *algop, 201 + int fd, const char *name, struct progress *tp) 202 { 203 /* 204 * Since we are expecting to report progress of the ··· 206 * size so the progress indicators arrive at a more 207 * frequent rate. 208 */ 209 + return hashfd_internal(algop, fd, name, tp, 8 * 1024); 210 } 211 212 void hashfile_checkpoint_init(struct hashfile *f, ··· 248 return f->crc32; 249 } 250 251 + int hashfile_checksum_valid(const struct git_hash_algo *algop, 252 + const unsigned char *data, size_t total_len) 253 { 254 unsigned char got[GIT_MAX_RAWSZ]; 255 struct git_hash_ctx ctx; 256 size_t data_len = total_len - algop->rawsz; 257 + 258 + algop = unsafe_hash_algo(algop); 259 260 if (total_len < algop->rawsz) 261 return 0; /* say "too short"? */
+8 -4
csum-file.h
··· 45 #define CSUM_FSYNC 2 46 #define CSUM_HASH_IN_STREAM 4 47 48 - struct hashfile *hashfd(int fd, const char *name); 49 - struct hashfile *hashfd_check(const char *name); 50 - struct hashfile *hashfd_throughput(int fd, const char *name, struct progress *tp); 51 52 /* 53 * Free the hashfile without flushing its contents to disk. This only ··· 66 uint32_t crc32_end(struct hashfile *); 67 68 /* Verify checksum validity while reading. Returns non-zero on success. */ 69 - int hashfile_checksum_valid(const unsigned char *data, size_t len); 70 71 /* 72 * Returns the total number of bytes fed to the hashfile so far (including ones
··· 45 #define CSUM_FSYNC 2 46 #define CSUM_HASH_IN_STREAM 4 47 48 + struct hashfile *hashfd(const struct git_hash_algo *algop, 49 + int fd, const char *name); 50 + struct hashfile *hashfd_check(const struct git_hash_algo *algop, 51 + const char *name); 52 + struct hashfile *hashfd_throughput(const struct git_hash_algo *algop, 53 + int fd, const char *name, struct progress *tp); 54 55 /* 56 * Free the hashfile without flushing its contents to disk. This only ··· 69 uint32_t crc32_end(struct hashfile *); 70 71 /* Verify checksum validity while reading. Returns non-zero on success. */ 72 + int hashfile_checksum_valid(const struct git_hash_algo *algop, 73 + const unsigned char *data, size_t len); 74 75 /* 76 * Returns the total number of bytes fed to the hashfile so far (including ones
+4 -2
midx-write.c
··· 1342 return -1; 1343 } 1344 1345 - f = hashfd(get_tempfile_fd(incr), get_tempfile_path(incr)); 1346 } else { 1347 hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR); 1348 - f = hashfd(get_lock_file_fd(&lk), get_lock_file_path(&lk)); 1349 } 1350 1351 cf = init_chunkfile(f);
··· 1342 return -1; 1343 } 1344 1345 + f = hashfd(r->hash_algo, get_tempfile_fd(incr), 1346 + get_tempfile_path(incr)); 1347 } else { 1348 hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR); 1349 + f = hashfd(r->hash_algo, get_lock_file_fd(&lk), 1350 + get_lock_file_path(&lk)); 1351 } 1352 1353 cf = init_chunkfile(f);
+2 -1
midx.c
··· 747 748 int midx_checksum_valid(struct multi_pack_index *m) 749 { 750 - return hashfile_checksum_valid(m->data, m->data_len); 751 } 752 753 struct clear_midx_data {
··· 747 748 int midx_checksum_valid(struct multi_pack_index *m) 749 { 750 + return hashfile_checksum_valid(m->repo->hash_algo, 751 + m->data, m->data_len); 752 } 753 754 struct clear_midx_data {
+1 -1
pack-bitmap-write.c
··· 1030 if (writer->pseudo_merges_nr) 1031 options |= BITMAP_OPT_PSEUDO_MERGES; 1032 1033 - f = hashfd(fd, tmp_file.buf); 1034 1035 memcpy(header.magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE)); 1036 header.version = htons(default_version);
··· 1030 if (writer->pseudo_merges_nr) 1031 options |= BITMAP_OPT_PSEUDO_MERGES; 1032 1033 + f = hashfd(the_repository->hash_algo, fd, tmp_file.buf); 1034 1035 memcpy(header.magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE)); 1036 header.version = htons(default_version);
+5 -4
pack-bitmap.c
··· 3024 return 0; 3025 } 3026 3027 - static int verify_bitmap_file(const char *name) 3028 { 3029 struct stat st; 3030 unsigned char *data; ··· 3040 3041 data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 3042 close(fd); 3043 - if (!hashfile_checksum_valid(data, st.st_size)) 3044 res = error(_("bitmap file '%s' has invalid checksum"), 3045 name); 3046 ··· 3055 for (struct multi_pack_index *m = get_multi_pack_index(r); 3056 m; m = m->next) { 3057 char *midx_bitmap_name = midx_bitmap_filename(m); 3058 - res |= verify_bitmap_file(midx_bitmap_name); 3059 free(midx_bitmap_name); 3060 } 3061 3062 for (struct packed_git *p = get_all_packs(r); 3063 p; p = p->next) { 3064 char *pack_bitmap_name = pack_bitmap_filename(p); 3065 - res |= verify_bitmap_file(pack_bitmap_name); 3066 free(pack_bitmap_name); 3067 } 3068
··· 3024 return 0; 3025 } 3026 3027 + static int verify_bitmap_file(const struct git_hash_algo *algop, 3028 + const char *name) 3029 { 3030 struct stat st; 3031 unsigned char *data; ··· 3041 3042 data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 3043 close(fd); 3044 + if (!hashfile_checksum_valid(algop, data, st.st_size)) 3045 res = error(_("bitmap file '%s' has invalid checksum"), 3046 name); 3047 ··· 3056 for (struct multi_pack_index *m = get_multi_pack_index(r); 3057 m; m = m->next) { 3058 char *midx_bitmap_name = midx_bitmap_filename(m); 3059 + res |= verify_bitmap_file(r->hash_algo, midx_bitmap_name); 3060 free(midx_bitmap_name); 3061 } 3062 3063 for (struct packed_git *p = get_all_packs(r); 3064 p; p = p->next) { 3065 char *pack_bitmap_name = pack_bitmap_filename(p); 3066 + res |= verify_bitmap_file(r->hash_algo, pack_bitmap_name); 3067 free(pack_bitmap_name); 3068 } 3069
+1 -1
pack-check.c
··· 180 return error("packfile %s index not opened", p->pack_name); 181 182 /* Verify SHA1 sum of the index file */ 183 - if (!hashfile_checksum_valid(p->index_data, p->index_size)) 184 err = error("Packfile index for %s hash mismatch", 185 p->pack_name); 186 return err;
··· 180 return error("packfile %s index not opened", p->pack_name); 181 182 /* Verify SHA1 sum of the index file */ 183 + if (!hashfile_checksum_valid(the_repository->hash_algo, p->index_data, p->index_size)) 184 err = error("Packfile index for %s hash mismatch", 185 p->pack_name); 186 return err;
+2 -1
pack-revindex.c
··· 322 if (!p->revindex_map || !p->revindex_data) 323 return res; 324 325 - if (!hashfile_checksum_valid((const unsigned char *)p->revindex_map, p->revindex_size)) { 326 error(_("invalid checksum")); 327 res = -1; 328 }
··· 322 if (!p->revindex_map || !p->revindex_data) 323 return res; 324 325 + if (!hashfile_checksum_valid(the_repository->hash_algo, 326 + (const unsigned char *)p->revindex_map, p->revindex_size)) { 327 error(_("invalid checksum")); 328 res = -1; 329 }
+6 -6
pack-write.c
··· 82 83 if (opts->flags & WRITE_IDX_VERIFY) { 84 assert(index_name); 85 - f = hashfd_check(index_name); 86 } else { 87 if (!index_name) { 88 struct strbuf tmp_file = STRBUF_INIT; ··· 92 unlink(index_name); 93 fd = xopen(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600); 94 } 95 - f = hashfd(fd, index_name); 96 } 97 98 /* if last object's offset is >= 2^31 we should use index V2 */ ··· 268 fd = xopen(rev_name, O_CREAT|O_EXCL|O_WRONLY, 0600); 269 path = xstrdup(rev_name); 270 } 271 - f = hashfd(fd, path); 272 } else if (flags & WRITE_REV_VERIFY) { 273 struct stat statbuf; 274 if (stat(rev_name, &statbuf)) { ··· 278 } else 279 die_errno(_("could not stat: %s"), rev_name); 280 } 281 - f = hashfd_check(rev_name); 282 path = xstrdup(rev_name); 283 } else { 284 return NULL; ··· 346 347 fd = odb_mkstemp(&tmp_file, "pack/tmp_mtimes_XXXXXX"); 348 mtimes_name = strbuf_detach(&tmp_file, NULL); 349 - f = hashfd(fd, mtimes_name); 350 351 write_mtimes_header(hash_algo, f); 352 write_mtimes_objects(f, to_pack, objects, nr_objects); ··· 534 535 fd = odb_mkstemp(&tmpname, "pack/tmp_pack_XXXXXX"); 536 *pack_tmp_name = strbuf_detach(&tmpname, NULL); 537 - return hashfd(fd, *pack_tmp_name); 538 } 539 540 static void rename_tmp_packfile(struct strbuf *name_prefix, const char *source,
··· 82 83 if (opts->flags & WRITE_IDX_VERIFY) { 84 assert(index_name); 85 + f = hashfd_check(the_repository->hash_algo, index_name); 86 } else { 87 if (!index_name) { 88 struct strbuf tmp_file = STRBUF_INIT; ··· 92 unlink(index_name); 93 fd = xopen(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600); 94 } 95 + f = hashfd(the_repository->hash_algo, fd, index_name); 96 } 97 98 /* if last object's offset is >= 2^31 we should use index V2 */ ··· 268 fd = xopen(rev_name, O_CREAT|O_EXCL|O_WRONLY, 0600); 269 path = xstrdup(rev_name); 270 } 271 + f = hashfd(the_repository->hash_algo, fd, path); 272 } else if (flags & WRITE_REV_VERIFY) { 273 struct stat statbuf; 274 if (stat(rev_name, &statbuf)) { ··· 278 } else 279 die_errno(_("could not stat: %s"), rev_name); 280 } 281 + f = hashfd_check(the_repository->hash_algo, rev_name); 282 path = xstrdup(rev_name); 283 } else { 284 return NULL; ··· 346 347 fd = odb_mkstemp(&tmp_file, "pack/tmp_mtimes_XXXXXX"); 348 mtimes_name = strbuf_detach(&tmp_file, NULL); 349 + f = hashfd(the_repository->hash_algo, fd, mtimes_name); 350 351 write_mtimes_header(hash_algo, f); 352 write_mtimes_objects(f, to_pack, objects, nr_objects); ··· 534 535 fd = odb_mkstemp(&tmpname, "pack/tmp_pack_XXXXXX"); 536 *pack_tmp_name = strbuf_detach(&tmpname, NULL); 537 + return hashfd(the_repository->hash_algo, fd, *pack_tmp_name); 538 } 539 540 static void rename_tmp_packfile(struct strbuf *name_prefix, const char *source,
+1 -1
read-cache.c
··· 2848 struct strbuf sb = STRBUF_INIT; 2849 int nr, nr_threads, ret; 2850 2851 - f = hashfd(tempfile->fd, tempfile->filename.buf); 2852 2853 prepare_repo_settings(r); 2854 f->skip_hash = r->settings.index_skip_hash;
··· 2848 struct strbuf sb = STRBUF_INIT; 2849 int nr, nr_threads, ret; 2850 2851 + f = hashfd(the_repository->hash_algo, tempfile->fd, tempfile->filename.buf); 2852 2853 prepare_repo_settings(r); 2854 f->skip_hash = r->settings.index_skip_hash;