Skip to content

Commit 60980ae

Browse files
ttaylorrgitster
authored andcommitted
midx.c: write MIDX filenames to strbuf
To ask for the name of a MIDX and its corresponding .rev file, callers invoke get_midx_filename() and get_midx_rev_filename(), respectively. These both invoke xstrfmt(), allocating a chunk of memory which must be freed later on. This makes callers in pack-bitmap.c somewhat awkward. Specifically, midx_bitmap_filename(), which is implemented like: return xstrfmt("%s-%s.bitmap", get_midx_filename(midx->object_dir), hash_to_hex(get_midx_checksum(midx))); this leaks the second argument to xstrfmt(), which itself was allocated with xstrfmt(). This caller could assign both the result of get_midx_filename() and the outer xstrfmt() to a temporary variable, remembering to free() the former before returning. But that involves a wasteful copy. Instead, get_midx_filename() and get_midx_rev_filename() take a strbuf as an output parameter. This way midx_bitmap_filename() can manipulate and pass around a temporary buffer which it detaches back to its caller. That allows us to implement the function without copying or open-coding get_midx_filename() in a way that doesn't leak. Update the other callers of get_midx_filename() and get_midx_rev_filename() accordingly. Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ee4a1d6 commit 60980ae

File tree

4 files changed

+49
-37
lines changed

4 files changed

+49
-37
lines changed

midx.c

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ const unsigned char *get_midx_checksum(struct multi_pack_index *m)
5757
return m->data + m->data_len - the_hash_algo->rawsz;
5858
}
5959

60-
char *get_midx_filename(const char *object_dir)
60+
void get_midx_filename(struct strbuf *out, const char *object_dir)
6161
{
62-
return xstrfmt("%s/pack/multi-pack-index", object_dir);
62+
strbuf_addf(out, "%s/pack/multi-pack-index", object_dir);
6363
}
6464

65-
char *get_midx_rev_filename(struct multi_pack_index *m)
65+
void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m)
6666
{
67-
return xstrfmt("%s/pack/multi-pack-index-%s.rev",
68-
m->object_dir, hash_to_hex(get_midx_checksum(m)));
67+
get_midx_filename(out, m->object_dir);
68+
strbuf_addf(out, "-%s.rev", hash_to_hex(get_midx_checksum(m)));
6969
}
7070

7171
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
8989
size_t midx_size;
9090
void *midx_map = NULL;
9191
uint32_t hash_version;
92-
char *midx_name = get_midx_filename(object_dir);
92+
struct strbuf midx_name = STRBUF_INIT;
9393
uint32_t i;
9494
const char *cur_pack_name;
9595
struct chunkfile *cf = NULL;
9696

97-
fd = git_open(midx_name);
97+
get_midx_filename(&midx_name, object_dir);
98+
99+
fd = git_open(midx_name.buf);
98100

99101
if (fd < 0)
100102
goto cleanup_fail;
101103
if (fstat(fd, &st)) {
102-
error_errno(_("failed to read %s"), midx_name);
104+
error_errno(_("failed to read %s"), midx_name.buf);
103105
goto cleanup_fail;
104106
}
105107

106108
midx_size = xsize_t(st.st_size);
107109

108110
if (midx_size < MIDX_MIN_SIZE) {
109-
error(_("multi-pack-index file %s is too small"), midx_name);
111+
error(_("multi-pack-index file %s is too small"), midx_name.buf);
110112
goto cleanup_fail;
111113
}
112114

113-
FREE_AND_NULL(midx_name);
115+
strbuf_release(&midx_name);
114116

115117
midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0);
116118
close(fd);
@@ -184,7 +186,7 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
184186

185187
cleanup_fail:
186188
free(m);
187-
free(midx_name);
189+
strbuf_release(&midx_name);
188190
free_chunkfile(cf);
189191
if (midx_map)
190192
munmap(midx_map, midx_size);
@@ -1115,7 +1117,7 @@ static int write_midx_internal(const char *object_dir,
11151117
const char *refs_snapshot,
11161118
unsigned flags)
11171119
{
1118-
char *midx_name;
1120+
struct strbuf midx_name = STRBUF_INIT;
11191121
unsigned char midx_hash[GIT_MAX_RAWSZ];
11201122
uint32_t i;
11211123
struct hashfile *f = NULL;
@@ -1130,10 +1132,10 @@ static int write_midx_internal(const char *object_dir,
11301132
/* Ensure the given object_dir is local, or a known alternate. */
11311133
find_odb(the_repository, object_dir);
11321134

1133-
midx_name = get_midx_filename(object_dir);
1134-
if (safe_create_leading_directories(midx_name))
1135+
get_midx_filename(&midx_name, object_dir);
1136+
if (safe_create_leading_directories(midx_name.buf))
11351137
die_errno(_("unable to create leading directories of %s"),
1136-
midx_name);
1138+
midx_name.buf);
11371139

11381140
if (!packs_to_include) {
11391141
/*
@@ -1367,7 +1369,7 @@ static int write_midx_internal(const char *object_dir,
13671369
pack_name_concat_len += MIDX_CHUNK_ALIGNMENT -
13681370
(pack_name_concat_len % MIDX_CHUNK_ALIGNMENT);
13691371

1370-
hold_lock_file_for_update(&lk, midx_name, LOCK_DIE_ON_ERROR);
1372+
hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR);
13711373
f = hashfd(get_lock_file_fd(&lk), get_lock_file_path(&lk));
13721374

13731375
if (ctx.nr - dropped_packs == 0) {
@@ -1404,9 +1406,9 @@ static int write_midx_internal(const char *object_dir,
14041406
ctx.pack_order = midx_pack_order(&ctx);
14051407

14061408
if (flags & MIDX_WRITE_REV_INDEX)
1407-
write_midx_reverse_index(midx_name, midx_hash, &ctx);
1409+
write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
14081410
if (flags & MIDX_WRITE_BITMAP) {
1409-
if (write_midx_bitmap(midx_name, midx_hash, &ctx,
1411+
if (write_midx_bitmap(midx_name.buf, midx_hash, &ctx,
14101412
refs_snapshot, flags) < 0) {
14111413
error(_("could not write multi-pack bitmap"));
14121414
result = 1;
@@ -1435,7 +1437,7 @@ static int write_midx_internal(const char *object_dir,
14351437
free(ctx.entries);
14361438
free(ctx.pack_perm);
14371439
free(ctx.pack_order);
1438-
free(midx_name);
1440+
strbuf_release(&midx_name);
14391441

14401442
return result;
14411443
}
@@ -1499,20 +1501,22 @@ static void clear_midx_files_ext(const char *object_dir, const char *ext,
14991501

15001502
void clear_midx_file(struct repository *r)
15011503
{
1502-
char *midx = get_midx_filename(r->objects->odb->path);
1504+
struct strbuf midx = STRBUF_INIT;
1505+
1506+
get_midx_filename(&midx, r->objects->odb->path);
15031507

15041508
if (r->objects && r->objects->multi_pack_index) {
15051509
close_midx(r->objects->multi_pack_index);
15061510
r->objects->multi_pack_index = NULL;
15071511
}
15081512

1509-
if (remove_path(midx))
1510-
die(_("failed to clear multi-pack-index at %s"), midx);
1513+
if (remove_path(midx.buf))
1514+
die(_("failed to clear multi-pack-index at %s"), midx.buf);
15111515

15121516
clear_midx_files_ext(r->objects->odb->path, ".bitmap", NULL);
15131517
clear_midx_files_ext(r->objects->odb->path, ".rev", NULL);
15141518

1515-
free(midx);
1519+
strbuf_release(&midx);
15161520
}
15171521

15181522
static int verify_midx_error;
@@ -1565,12 +1569,15 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
15651569
if (!m) {
15661570
int result = 0;
15671571
struct stat sb;
1568-
char *filename = get_midx_filename(object_dir);
1569-
if (!stat(filename, &sb)) {
1572+
struct strbuf filename = STRBUF_INIT;
1573+
1574+
get_midx_filename(&filename, object_dir);
1575+
1576+
if (!stat(filename.buf, &sb)) {
15701577
error(_("multi-pack-index file exists, but failed to parse"));
15711578
result = 1;
15721579
}
1573-
free(filename);
1580+
strbuf_release(&filename);
15741581
return result;
15751582
}
15761583

midx.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ struct multi_pack_index {
4848
#define MIDX_WRITE_BITMAP_HASH_CACHE (1 << 3)
4949

5050
const unsigned char *get_midx_checksum(struct multi_pack_index *m);
51-
char *get_midx_filename(const char *object_dir);
52-
char *get_midx_rev_filename(struct multi_pack_index *m);
51+
void get_midx_filename(struct strbuf *out, const char *object_dir);
52+
void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m);
5353

5454
struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local);
5555
int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id);

pack-bitmap.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,12 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
292292

293293
char *midx_bitmap_filename(struct multi_pack_index *midx)
294294
{
295-
return xstrfmt("%s-%s.bitmap",
296-
get_midx_filename(midx->object_dir),
297-
hash_to_hex(get_midx_checksum(midx)));
295+
struct strbuf buf = STRBUF_INIT;
296+
297+
get_midx_filename(&buf, midx->object_dir);
298+
strbuf_addf(&buf, "-%s.bitmap", hash_to_hex(get_midx_checksum(midx)));
299+
300+
return strbuf_detach(&buf, NULL);
298301
}
299302

300303
char *pack_bitmap_filename(struct packed_git *p)
@@ -324,10 +327,12 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
324327
}
325328

326329
if (bitmap_git->pack || bitmap_git->midx) {
330+
struct strbuf buf = STRBUF_INIT;
331+
get_midx_filename(&buf, midx->object_dir);
327332
/* ignore extra bitmap file; we can only handle one */
328-
warning("ignoring extra bitmap file: %s",
329-
get_midx_filename(midx->object_dir));
333+
warning("ignoring extra bitmap file: %s", buf.buf);
330334
close(fd);
335+
strbuf_release(&buf);
331336
return -1;
332337
}
333338

pack-revindex.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,14 +296,14 @@ int load_pack_revindex(struct packed_git *p)
296296

297297
int load_midx_revindex(struct multi_pack_index *m)
298298
{
299-
char *revindex_name;
299+
struct strbuf revindex_name = STRBUF_INIT;
300300
int ret;
301301
if (m->revindex_data)
302302
return 0;
303303

304-
revindex_name = get_midx_rev_filename(m);
304+
get_midx_rev_filename(&revindex_name, m);
305305

306-
ret = load_revindex_from_disk(revindex_name,
306+
ret = load_revindex_from_disk(revindex_name.buf,
307307
m->num_objects,
308308
&m->revindex_map,
309309
&m->revindex_len);
@@ -313,7 +313,7 @@ int load_midx_revindex(struct multi_pack_index *m)
313313
m->revindex_data = (const uint32_t *)((const char *)m->revindex_map + RIDX_HEADER_SIZE);
314314

315315
cleanup:
316-
free(revindex_name);
316+
strbuf_release(&revindex_name);
317317
return ret;
318318
}
319319

0 commit comments

Comments
 (0)