@@ -57,26 +57,31 @@ void add_chunk(struct chunkfile *cf,
cf->chunks_nr++;
}
-int write_chunkfile(struct chunkfile *cf, void *data)
+int write_chunkfile(struct chunkfile *cf,
+ enum chunkfile_flags flags,
+ void *data)
{
int i, result = 0;
- uint64_t cur_offset = hashfile_total(cf->f);
trace2_region_enter("chunkfile", "write", the_repository);
- /* Add the table of contents to the current offset */
- cur_offset += (cf->chunks_nr + 1) * CHUNK_TOC_ENTRY_SIZE;
+ if (!(flags & CHUNKFILE_TRAILING_TOC)) {
+ uint64_t cur_offset = hashfile_total(cf->f);
- for (i = 0; i < cf->chunks_nr; i++) {
- hashwrite_be32(cf->f, cf->chunks[i].id);
- hashwrite_be64(cf->f, cur_offset);
+ /* Add the table of contents to the current offset */
+ cur_offset += (cf->chunks_nr + 1) * CHUNK_TOC_ENTRY_SIZE;
- cur_offset += cf->chunks[i].size;
- }
+ for (i = 0; i < cf->chunks_nr; i++) {
+ hashwrite_be32(cf->f, cf->chunks[i].id);
+ hashwrite_be64(cf->f, cur_offset);
- /* Trailing entry marks the end of the chunks */
- hashwrite_be32(cf->f, 0);
- hashwrite_be64(cf->f, cur_offset);
+ cur_offset += cf->chunks[i].size;
+ }
+
+ /* Trailing entry marks the end of the chunks */
+ hashwrite_be32(cf->f, 0);
+ hashwrite_be64(cf->f, cur_offset);
+ }
for (i = 0; i < cf->chunks_nr; i++) {
cf->chunks[i].offset = hashfile_total(cf->f);
@@ -85,10 +90,26 @@ int write_chunkfile(struct chunkfile *cf, void *data)
if (result)
goto cleanup;
- if (hashfile_total(cf->f) - cf->chunks[i].offset != cf->chunks[i].size)
- BUG("expected to write %"PRId64" bytes to chunk %"PRIx32", but wrote %"PRId64" instead",
- cf->chunks[i].size, cf->chunks[i].id,
- hashfile_total(cf->f) - cf->chunks[i].offset);
+ if (!(flags & CHUNKFILE_TRAILING_TOC)) {
+ if (hashfile_total(cf->f) - cf->chunks[i].offset != cf->chunks[i].size)
+ BUG("expected to write %"PRId64" bytes to chunk %"PRIx32", but wrote %"PRId64" instead",
+ cf->chunks[i].size, cf->chunks[i].id,
+ hashfile_total(cf->f) - cf->chunks[i].offset);
+ }
+
+ cf->chunks[i].size = hashfile_total(cf->f) - cf->chunks[i].offset;
+ }
+
+ if (flags & CHUNKFILE_TRAILING_TOC) {
+ size_t last_chunk_tail = hashfile_total(cf->f);
+ /* First entry marks the end of the chunks */
+ hashwrite_be32(cf->f, 0);
+ hashwrite_be64(cf->f, last_chunk_tail);
+
+ for (i = cf->chunks_nr - 1; i >= 0; i--) {
+ hashwrite_be32(cf->f, cf->chunks[i].id);
+ hashwrite_be64(cf->f, cf->chunks[i].offset);
+ }
}
cleanup:
@@ -31,7 +31,14 @@ void add_chunk(struct chunkfile *cf,
uint32_t id,
size_t size,
chunk_write_fn fn);
-int write_chunkfile(struct chunkfile *cf, void *data);
+
+enum chunkfile_flags {
+ CHUNKFILE_TRAILING_TOC = (1 << 0),
+};
+
+int write_chunkfile(struct chunkfile *cf,
+ enum chunkfile_flags flags,
+ void *data);
int read_table_of_contents(struct chunkfile *cf,
const unsigned char *mfile,
@@ -1932,7 +1932,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
get_num_chunks(cf) * ctx->commits.nr);
}
- write_chunkfile(cf, ctx);
+ write_chunkfile(cf, 0, ctx);
stop_progress(&ctx->progress);
strbuf_release(&progress_title);
@@ -1510,7 +1510,7 @@ static int write_midx_internal(const char *object_dir,
}
write_midx_header(f, get_num_chunks(cf), ctx.nr - dropped_packs);
- write_chunkfile(cf, &ctx);
+ write_chunkfile(cf, 0, &ctx);
finalize_hashfile(f, midx_hash, FSYNC_COMPONENT_PACK_METADATA,
CSUM_FSYNC | CSUM_HASH_IN_STREAM);