Merge branch 'tb/plug-pack-bitmap-leaks'
Leakfix. * tb/plug-pack-bitmap-leaks: pack-bitmap.c: more aggressively free in free_bitmap_index() pack-bitmap.c: don't leak type-level bitmaps midx.c: write MIDX filenames to strbuf builtin/multi-pack-index.c: don't leak concatenated options builtin/repack.c: avoid leaking child arguments builtin/pack-objects.c: don't leak memory via arguments t/helper/test-read-midx.c: free MIDX within read_midx_file() midx.c: don't leak MIDX from verify_midx_file midx.c: clean up chunkfile after reading the MIDX
This commit is contained in:
commit
49767c3d9f
@ -167,6 +167,8 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv)
|
||||
usage_with_options(builtin_multi_pack_index_verify_usage,
|
||||
options);
|
||||
|
||||
FREE_AND_NULL(options);
|
||||
|
||||
return verify_midx_file(the_repository, opts.object_dir, opts.flags);
|
||||
}
|
||||
|
||||
@ -191,6 +193,8 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv)
|
||||
usage_with_options(builtin_multi_pack_index_expire_usage,
|
||||
options);
|
||||
|
||||
FREE_AND_NULL(options);
|
||||
|
||||
return expire_midx_packs(the_repository, opts.object_dir, opts.flags);
|
||||
}
|
||||
|
||||
|
@ -4148,11 +4148,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
read_packs_list_from_stdin();
|
||||
if (rev_list_unpacked)
|
||||
add_unreachable_loose_objects();
|
||||
} else if (!use_internal_rev_list)
|
||||
} else if (!use_internal_rev_list) {
|
||||
read_object_list_from_stdin();
|
||||
else {
|
||||
} else {
|
||||
get_object_list(rp.nr, rp.v);
|
||||
strvec_clear(&rp);
|
||||
}
|
||||
cleanup_preferred_base();
|
||||
if (include_tag && nr_result)
|
||||
@ -4162,7 +4161,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
the_repository);
|
||||
|
||||
if (non_empty && !nr_result)
|
||||
return 0;
|
||||
goto cleanup;
|
||||
if (nr_result) {
|
||||
trace2_region_enter("pack-objects", "prepare-pack",
|
||||
the_repository);
|
||||
@ -4183,5 +4182,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
" pack-reused %"PRIu32),
|
||||
written, written_delta, reused, reused_delta,
|
||||
reuse_packfile_objects);
|
||||
|
||||
cleanup:
|
||||
strvec_clear(&rp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -258,9 +258,11 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
|
||||
for_each_packed_object(write_oid, &cmd,
|
||||
FOR_EACH_OBJECT_PROMISOR_ONLY);
|
||||
|
||||
if (cmd.in == -1)
|
||||
if (cmd.in == -1) {
|
||||
/* No packed objects; cmd was never started */
|
||||
child_process_clear(&cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
close(cmd.in);
|
||||
|
||||
|
66
midx.c
66
midx.c
@ -57,15 +57,15 @@ const unsigned char *get_midx_checksum(struct multi_pack_index *m)
|
||||
return m->data + m->data_len - the_hash_algo->rawsz;
|
||||
}
|
||||
|
||||
char *get_midx_filename(const char *object_dir)
|
||||
void get_midx_filename(struct strbuf *out, const char *object_dir)
|
||||
{
|
||||
return xstrfmt("%s/pack/multi-pack-index", object_dir);
|
||||
strbuf_addf(out, "%s/pack/multi-pack-index", object_dir);
|
||||
}
|
||||
|
||||
char *get_midx_rev_filename(struct multi_pack_index *m)
|
||||
void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m)
|
||||
{
|
||||
return xstrfmt("%s/pack/multi-pack-index-%s.rev",
|
||||
m->object_dir, hash_to_hex(get_midx_checksum(m)));
|
||||
get_midx_filename(out, m->object_dir);
|
||||
strbuf_addf(out, "-%s.rev", hash_to_hex(get_midx_checksum(m)));
|
||||
}
|
||||
|
||||
static int midx_read_oid_fanout(const unsigned char *chunk_start,
|
||||
@ -89,28 +89,30 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
|
||||
size_t midx_size;
|
||||
void *midx_map = NULL;
|
||||
uint32_t hash_version;
|
||||
char *midx_name = get_midx_filename(object_dir);
|
||||
struct strbuf midx_name = STRBUF_INIT;
|
||||
uint32_t i;
|
||||
const char *cur_pack_name;
|
||||
struct chunkfile *cf = NULL;
|
||||
|
||||
fd = git_open(midx_name);
|
||||
get_midx_filename(&midx_name, object_dir);
|
||||
|
||||
fd = git_open(midx_name.buf);
|
||||
|
||||
if (fd < 0)
|
||||
goto cleanup_fail;
|
||||
if (fstat(fd, &st)) {
|
||||
error_errno(_("failed to read %s"), midx_name);
|
||||
error_errno(_("failed to read %s"), midx_name.buf);
|
||||
goto cleanup_fail;
|
||||
}
|
||||
|
||||
midx_size = xsize_t(st.st_size);
|
||||
|
||||
if (midx_size < MIDX_MIN_SIZE) {
|
||||
error(_("multi-pack-index file %s is too small"), midx_name);
|
||||
error(_("multi-pack-index file %s is too small"), midx_name.buf);
|
||||
goto cleanup_fail;
|
||||
}
|
||||
|
||||
FREE_AND_NULL(midx_name);
|
||||
strbuf_release(&midx_name);
|
||||
|
||||
midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
close(fd);
|
||||
@ -179,12 +181,13 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
|
||||
trace2_data_intmax("midx", the_repository, "load/num_packs", m->num_packs);
|
||||
trace2_data_intmax("midx", the_repository, "load/num_objects", m->num_objects);
|
||||
|
||||
free_chunkfile(cf);
|
||||
return m;
|
||||
|
||||
cleanup_fail:
|
||||
free(m);
|
||||
free(midx_name);
|
||||
free(cf);
|
||||
strbuf_release(&midx_name);
|
||||
free_chunkfile(cf);
|
||||
if (midx_map)
|
||||
munmap(midx_map, midx_size);
|
||||
if (0 <= fd)
|
||||
@ -1130,7 +1133,7 @@ static int write_midx_internal(const char *object_dir,
|
||||
const char *refs_snapshot,
|
||||
unsigned flags)
|
||||
{
|
||||
char *midx_name;
|
||||
struct strbuf midx_name = STRBUF_INIT;
|
||||
unsigned char midx_hash[GIT_MAX_RAWSZ];
|
||||
uint32_t i;
|
||||
struct hashfile *f = NULL;
|
||||
@ -1141,10 +1144,10 @@ static int write_midx_internal(const char *object_dir,
|
||||
int result = 0;
|
||||
struct chunkfile *cf;
|
||||
|
||||
midx_name = get_midx_filename(object_dir);
|
||||
if (safe_create_leading_directories(midx_name))
|
||||
get_midx_filename(&midx_name, object_dir);
|
||||
if (safe_create_leading_directories(midx_name.buf))
|
||||
die_errno(_("unable to create leading directories of %s"),
|
||||
midx_name);
|
||||
midx_name.buf);
|
||||
|
||||
if (!packs_to_include) {
|
||||
/*
|
||||
@ -1373,7 +1376,7 @@ static int write_midx_internal(const char *object_dir,
|
||||
pack_name_concat_len += MIDX_CHUNK_ALIGNMENT -
|
||||
(pack_name_concat_len % MIDX_CHUNK_ALIGNMENT);
|
||||
|
||||
hold_lock_file_for_update(&lk, midx_name, LOCK_DIE_ON_ERROR);
|
||||
hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR);
|
||||
f = hashfd(get_lock_file_fd(&lk), get_lock_file_path(&lk));
|
||||
|
||||
if (ctx.nr - dropped_packs == 0) {
|
||||
@ -1410,9 +1413,9 @@ static int write_midx_internal(const char *object_dir,
|
||||
ctx.pack_order = midx_pack_order(&ctx);
|
||||
|
||||
if (flags & MIDX_WRITE_REV_INDEX)
|
||||
write_midx_reverse_index(midx_name, midx_hash, &ctx);
|
||||
write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
|
||||
if (flags & MIDX_WRITE_BITMAP) {
|
||||
if (write_midx_bitmap(midx_name, midx_hash, &ctx,
|
||||
if (write_midx_bitmap(midx_name.buf, midx_hash, &ctx,
|
||||
refs_snapshot, flags) < 0) {
|
||||
error(_("could not write multi-pack bitmap"));
|
||||
result = 1;
|
||||
@ -1442,7 +1445,7 @@ cleanup:
|
||||
free(ctx.entries);
|
||||
free(ctx.pack_perm);
|
||||
free(ctx.pack_order);
|
||||
free(midx_name);
|
||||
strbuf_release(&midx_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1506,20 +1509,22 @@ static void clear_midx_files_ext(const char *object_dir, const char *ext,
|
||||
|
||||
void clear_midx_file(struct repository *r)
|
||||
{
|
||||
char *midx = get_midx_filename(r->objects->odb->path);
|
||||
struct strbuf midx = STRBUF_INIT;
|
||||
|
||||
get_midx_filename(&midx, r->objects->odb->path);
|
||||
|
||||
if (r->objects && r->objects->multi_pack_index) {
|
||||
close_midx(r->objects->multi_pack_index);
|
||||
r->objects->multi_pack_index = NULL;
|
||||
}
|
||||
|
||||
if (remove_path(midx))
|
||||
die(_("failed to clear multi-pack-index at %s"), midx);
|
||||
if (remove_path(midx.buf))
|
||||
die(_("failed to clear multi-pack-index at %s"), midx.buf);
|
||||
|
||||
clear_midx_files_ext(r->objects->odb->path, ".bitmap", NULL);
|
||||
clear_midx_files_ext(r->objects->odb->path, ".rev", NULL);
|
||||
|
||||
free(midx);
|
||||
strbuf_release(&midx);
|
||||
}
|
||||
|
||||
static int verify_midx_error;
|
||||
@ -1572,12 +1577,15 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
|
||||
if (!m) {
|
||||
int result = 0;
|
||||
struct stat sb;
|
||||
char *filename = get_midx_filename(object_dir);
|
||||
if (!stat(filename, &sb)) {
|
||||
struct strbuf filename = STRBUF_INIT;
|
||||
|
||||
get_midx_filename(&filename, object_dir);
|
||||
|
||||
if (!stat(filename.buf, &sb)) {
|
||||
error(_("multi-pack-index file exists, but failed to parse"));
|
||||
result = 1;
|
||||
}
|
||||
free(filename);
|
||||
strbuf_release(&filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1610,7 +1618,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
|
||||
* Remaining tests assume that we have objects, so we can
|
||||
* return here.
|
||||
*/
|
||||
return verify_midx_error;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (flags & MIDX_PROGRESS)
|
||||
@ -1688,7 +1696,9 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
|
||||
}
|
||||
stop_progress(&progress);
|
||||
|
||||
cleanup:
|
||||
free(pairs);
|
||||
close_midx(m);
|
||||
|
||||
return verify_midx_error;
|
||||
}
|
||||
|
4
midx.h
4
midx.h
@ -48,8 +48,8 @@ struct multi_pack_index {
|
||||
#define MIDX_WRITE_BITMAP_HASH_CACHE (1 << 3)
|
||||
|
||||
const unsigned char *get_midx_checksum(struct multi_pack_index *m);
|
||||
char *get_midx_filename(const char *object_dir);
|
||||
char *get_midx_rev_filename(struct multi_pack_index *m);
|
||||
void get_midx_filename(struct strbuf *out, const char *object_dir);
|
||||
void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m);
|
||||
|
||||
struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local);
|
||||
int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id);
|
||||
|
@ -292,9 +292,12 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
|
||||
|
||||
char *midx_bitmap_filename(struct multi_pack_index *midx)
|
||||
{
|
||||
return xstrfmt("%s-%s.bitmap",
|
||||
get_midx_filename(midx->object_dir),
|
||||
hash_to_hex(get_midx_checksum(midx)));
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
get_midx_filename(&buf, midx->object_dir);
|
||||
strbuf_addf(&buf, "-%s.bitmap", hash_to_hex(get_midx_checksum(midx)));
|
||||
|
||||
return strbuf_detach(&buf, NULL);
|
||||
}
|
||||
|
||||
char *pack_bitmap_filename(struct packed_git *p)
|
||||
@ -324,10 +327,12 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
|
||||
}
|
||||
|
||||
if (bitmap_git->pack || bitmap_git->midx) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
get_midx_filename(&buf, midx->object_dir);
|
||||
/* ignore extra bitmap file; we can only handle one */
|
||||
warning("ignoring extra bitmap file: %s",
|
||||
get_midx_filename(midx->object_dir));
|
||||
warning("ignoring extra bitmap file: %s", buf.buf);
|
||||
close(fd);
|
||||
strbuf_release(&buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1721,6 +1726,12 @@ void test_bitmap_walk(struct rev_info *revs)
|
||||
else
|
||||
die("mismatch in bitmap results");
|
||||
|
||||
bitmap_free(result);
|
||||
bitmap_free(tdata.base);
|
||||
bitmap_free(tdata.commits);
|
||||
bitmap_free(tdata.trees);
|
||||
bitmap_free(tdata.blobs);
|
||||
bitmap_free(tdata.tags);
|
||||
free_bitmap_index(bitmap_git);
|
||||
}
|
||||
|
||||
@ -1848,9 +1859,17 @@ void free_bitmap_index(struct bitmap_index *b)
|
||||
ewah_pool_free(b->trees);
|
||||
ewah_pool_free(b->blobs);
|
||||
ewah_pool_free(b->tags);
|
||||
if (b->bitmaps) {
|
||||
struct stored_bitmap *sb;
|
||||
kh_foreach_value(b->bitmaps, sb, {
|
||||
ewah_pool_free(sb->root);
|
||||
free(sb);
|
||||
});
|
||||
}
|
||||
kh_destroy_oid_map(b->bitmaps);
|
||||
free(b->ext_index.objects);
|
||||
free(b->ext_index.hashes);
|
||||
kh_destroy_oid_pos(b->ext_index.positions);
|
||||
bitmap_free(b->result);
|
||||
bitmap_free(b->haves);
|
||||
if (bitmap_is_midx(b)) {
|
||||
|
@ -296,14 +296,14 @@ int load_pack_revindex(struct packed_git *p)
|
||||
|
||||
int load_midx_revindex(struct multi_pack_index *m)
|
||||
{
|
||||
char *revindex_name;
|
||||
struct strbuf revindex_name = STRBUF_INIT;
|
||||
int ret;
|
||||
if (m->revindex_data)
|
||||
return 0;
|
||||
|
||||
revindex_name = get_midx_rev_filename(m);
|
||||
get_midx_rev_filename(&revindex_name, m);
|
||||
|
||||
ret = load_revindex_from_disk(revindex_name,
|
||||
ret = load_revindex_from_disk(revindex_name.buf,
|
||||
m->num_objects,
|
||||
&m->revindex_map,
|
||||
&m->revindex_len);
|
||||
@ -313,7 +313,7 @@ int load_midx_revindex(struct multi_pack_index *m)
|
||||
m->revindex_data = (const uint32_t *)((const char *)m->revindex_map + RIDX_HEADER_SIZE);
|
||||
|
||||
cleanup:
|
||||
free(revindex_name);
|
||||
strbuf_release(&revindex_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -55,9 +55,10 @@ static int read_midx_file(const char *object_dir, int show_objects)
|
||||
printf("%s %"PRIu64"\t%s\n",
|
||||
oid_to_hex(&oid), e.offset, e.p->pack_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
close_midx(m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user