Re: [PATCH v4 2/2] pack-bitmap: add load corrupt bitmap test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> 2025年5月29日 23:45,Junio C Hamano <gitster@xxxxxxxxx> 写道:
> 
> "Lidong Yan via GitGitGadget" <gitgitgadget@xxxxxxxxx> writes:
> 
>> From: Lidong Yan <502024330056@xxxxxxxxxxxxxxxx>
>> 
>> This patch add test_bitmap_list_commits_offset() in patch-bitmap.c,
> 
> "pack-bitmap.c"?
> 
>> a new test helper command `test-tool bitmap list-commits-offset`,
>> and a `load corrupt bitmap` test case in t5310.
>> 
>> The `load corrupt bitmap` test case intentionally corrupt the
>> "xor_offset" field of the first entry. And the newly added helper
>> can help to find position of "xor_offset" in bitmap file.
> 
> [the structure of a log message]
> 
> The usual way to compose a log message of this project is to
> 
> - Give an observation on how the current system works in the
>   present tense (so no need to say "Currently X is Y", or
>   "Previously X was Y" to describe the state before your change;
>   just "X is Y" is enough), and discuss what you perceive as a
>   problem in it.
> 
> - Propose a solution (optional---often, problem description
>   trivially leads to an obvious solution in reader's minds).
> 
> - Give commands to somebody editing the codebase to "make it so".
> 
> in this order.
> 
> The proposed log message lacks the motivation and only talks about
> what the patch does.  We add a test-only code in a file, intermixed
> with production code.  Let's explain why it is the best arrangement.

I see. I am trying to validate these patch series and test further patch won’t leak
memory under the condition that bitmap is corrupted, Anyway I will pay attention
to motivation in my following log messages.

> 
>> Signed-off-by: Lidong Yan <502024330056@xxxxxxxxxxxxxxxx>
>> ---
>> pack-bitmap.c           | 73 +++++++++++++++++++++++++++++++++++++----
>> pack-bitmap.h           |  1 +
>> t/helper/test-bitmap.c  |  8 +++++
>> t/t5310-pack-bitmaps.sh | 27 +++++++++++++++
>> 4 files changed, 103 insertions(+), 6 deletions(-)
> 
> After the second round of the series, no review comments seem to
> have been sent to the list.  Is everybody happy with the latest
> iteration?
> 
> Thanks.
> 
>> diff --git a/pack-bitmap.c b/pack-bitmap.c
>> index fd19c2255163..39c1c1bc4ce1 100644
>> --- a/pack-bitmap.c
>> +++ b/pack-bitmap.c
>> @@ -34,6 +34,11 @@ struct stored_bitmap {
>> int flags;
>> };
>> 
>> +struct stored_bitmap_tag_pos {
>> + struct stored_bitmap stored;
>> + size_t map_pos;
>> +};
>> +
>> /*
>>  * The active bitmap index for a repository. By design, repositories only have
>>  * a single bitmap index available (the index for the biggest packfile in
>> @@ -148,6 +153,7 @@ static int existing_bitmaps_hits_nr;
>> static int existing_bitmaps_misses_nr;
>> static int roots_with_bitmaps_nr;
>> static int roots_without_bitmaps_nr;
>> +static int tag_pos_on_bitmap;
>> 
>> static struct ewah_bitmap *lookup_stored_bitmap(struct stored_bitmap *st)
>> {
>> @@ -314,13 +320,18 @@ static struct stored_bitmap *store_bitmap(struct bitmap_index *index,
>>  struct ewah_bitmap *root,
>>  const struct object_id *oid,
>>  struct stored_bitmap *xor_with,
>> -  int flags)
>> +  int flags, size_t map_pos)
>> {
>> struct stored_bitmap *stored;
>> + struct stored_bitmap_tag_pos *tagged;
>> khiter_t hash_pos;
>> int ret;
>> 
>> - stored = xmalloc(sizeof(struct stored_bitmap));
>> + tagged = xmalloc(tag_pos_on_bitmap ? sizeof(struct stored_bitmap_tag_pos) :
>> +     sizeof(struct stored_bitmap));
>> + stored = &tagged->stored;
>> + if (tag_pos_on_bitmap)
>> + tagged->map_pos = map_pos;
>> stored->root = root;
>> stored->xor = xor_with;
>> stored->flags = flags;
>> @@ -376,10 +387,12 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
>> struct stored_bitmap *xor_bitmap = NULL;
>> uint32_t commit_idx_pos;
>> struct object_id oid;
>> + size_t entry_map_pos;
>> 
>> if (index->map_size - index->map_pos < 6)
>> return error(_("corrupt ewah bitmap: truncated header for entry %d"), i);
>> 
>> + entry_map_pos = index->map_pos;
>> commit_idx_pos = read_be32(index->map, &index->map_pos);
>> xor_offset = read_u8(index->map, &index->map_pos);
>> flags = read_u8(index->map, &index->map_pos);
>> @@ -402,8 +415,9 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
>> if (!bitmap)
>> return -1;
>> 
>> - recent_bitmaps[i % MAX_XOR_OFFSET] = store_bitmap(
>> - index, bitmap, &oid, xor_bitmap, flags);
>> + recent_bitmaps[i % MAX_XOR_OFFSET] =
>> + store_bitmap(index, bitmap, &oid, xor_bitmap, flags,
>> +     entry_map_pos);
>> }
>> 
>> return 0;
>> @@ -869,6 +883,7 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
>> int xor_flags;
>> khiter_t hash_pos;
>> struct bitmap_lookup_table_xor_item *xor_item;
>> + size_t entry_map_pos;
>> 
>> if (is_corrupt)
>> return NULL;
>> @@ -928,6 +943,7 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
>> goto corrupt;
>> }
>> 
>> + entry_map_pos = bitmap_git->map_pos;
>> bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
>> xor_flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
>> bitmap = read_bitmap_1(bitmap_git);
>> @@ -935,7 +951,8 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
>> if (!bitmap)
>> goto corrupt;
>> 
>> - xor_bitmap = store_bitmap(bitmap_git, bitmap, &xor_item->oid, xor_bitmap, xor_flags);
>> + xor_bitmap = store_bitmap(bitmap_git, bitmap, &xor_item->oid,
>> +  xor_bitmap, xor_flags, entry_map_pos);
>> xor_items_nr--;
>> }
>> 
>> @@ -969,6 +986,7 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
>> * Instead, we can skip ahead and immediately read the flags and
>> * ewah bitmap.
>> */
>> + entry_map_pos = bitmap_git->map_pos;
>> bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
>> flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
>> bitmap = read_bitmap_1(bitmap_git);
>> @@ -976,7 +994,8 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
>> if (!bitmap)
>> goto corrupt;
>> 
>> - return store_bitmap(bitmap_git, bitmap, oid, xor_bitmap, flags);
>> + return store_bitmap(bitmap_git, bitmap, oid, xor_bitmap, flags,
>> +    entry_map_pos);
>> 
>> corrupt:
>> free(xor_items);
>> @@ -2856,6 +2875,48 @@ int test_bitmap_commits(struct repository *r)
>> return 0;
>> }
>> 
>> +int test_bitmap_commits_offset(struct repository *r)
>> +{
>> + struct object_id oid;
>> + struct stored_bitmap_tag_pos *tagged;
>> + struct bitmap_index *bitmap_git;
>> + size_t commit_idx_pos_map_pos, xor_offset_map_pos, flag_map_pos,
>> + ewah_bitmap_map_pos;
>> +
>> + tag_pos_on_bitmap = 1;
>> + bitmap_git = prepare_bitmap_git(r);
>> + if (!bitmap_git)
>> + die(_("failed to load bitmap indexes"));
>> +
>> + /*
>> + * As this function is only used to print bitmap selected
>> + * commits, we don't have to read the commit table.
>> + */
>> + if (bitmap_git->table_lookup) {
>> + if (load_bitmap_entries_v1(bitmap_git) < 0)
>> + die(_("failed to load bitmap indexes"));
>> + }
>> +
>> + kh_foreach (bitmap_git->bitmaps, oid, tagged, {
>> + commit_idx_pos_map_pos = tagged->map_pos;
>> + xor_offset_map_pos = tagged->map_pos + sizeof(uint32_t);
>> + flag_map_pos = xor_offset_map_pos + sizeof(uint8_t);
>> + ewah_bitmap_map_pos = flag_map_pos + sizeof(uint8_t);
>> +
>> + printf_ln("%s %"PRIuMAX" %"PRIuMAX" %"PRIuMAX" %"PRIuMAX,
>> +  oid_to_hex(&oid),
>> +  (uintmax_t)commit_idx_pos_map_pos,
>> +  (uintmax_t)xor_offset_map_pos,
>> +  (uintmax_t)flag_map_pos,
>> +  (uintmax_t)ewah_bitmap_map_pos);
>> + })
>> + ;
>> +
>> + free_bitmap_index(bitmap_git);
>> +
>> + return 0;
>> +}
>> +
>> int test_bitmap_hashes(struct repository *r)
>> {
>> struct bitmap_index *bitmap_git = prepare_bitmap_git(r);
>> diff --git a/pack-bitmap.h b/pack-bitmap.h
>> index 382d39499af2..96880ba3d72d 100644
>> --- a/pack-bitmap.h
>> +++ b/pack-bitmap.h
>> @@ -81,6 +81,7 @@ void traverse_bitmap_commit_list(struct bitmap_index *,
>> show_reachable_fn show_reachable);
>> void test_bitmap_walk(struct rev_info *revs);
>> int test_bitmap_commits(struct repository *r);
>> +int test_bitmap_commits_offset(struct repository *r);
>> int test_bitmap_hashes(struct repository *r);
>> int test_bitmap_pseudo_merges(struct repository *r);
>> int test_bitmap_pseudo_merge_commits(struct repository *r, uint32_t n);
>> diff --git a/t/helper/test-bitmap.c b/t/helper/test-bitmap.c
>> index 3f23f2107268..65a1ab29192b 100644
>> --- a/t/helper/test-bitmap.c
>> +++ b/t/helper/test-bitmap.c
>> @@ -10,6 +10,11 @@ static int bitmap_list_commits(void)
>> return test_bitmap_commits(the_repository);
>> }
>> 
>> +static int bitmap_list_commits_offset(void)
>> +{
>> + return test_bitmap_commits_offset(the_repository);
>> +}
>> +
>> static int bitmap_dump_hashes(void)
>> {
>> return test_bitmap_hashes(the_repository);
>> @@ -36,6 +41,8 @@ int cmd__bitmap(int argc, const char **argv)
>> 
>> if (argc == 2 && !strcmp(argv[1], "list-commits"))
>> return bitmap_list_commits();
>> + if (argc == 2 && !strcmp(argv[1], "list-commits-offset"))
>> + return bitmap_list_commits_offset();
>> if (argc == 2 && !strcmp(argv[1], "dump-hashes"))
>> return bitmap_dump_hashes();
>> if (argc == 2 && !strcmp(argv[1], "dump-pseudo-merges"))
>> @@ -46,6 +53,7 @@ int cmd__bitmap(int argc, const char **argv)
>> return bitmap_dump_pseudo_merge_objects(atoi(argv[2]));
>> 
>> usage("\ttest-tool bitmap list-commits\n"
>> +      "\ttest-tool bitmap list-commits-offset\n"
>>      "\ttest-tool bitmap dump-hashes\n"
>>      "\ttest-tool bitmap dump-pseudo-merges\n"
>>      "\ttest-tool bitmap dump-pseudo-merge-commits <n>\n"
>> diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
>> index a62b463eaf09..ef4c5fbaae83 100755
>> --- a/t/t5310-pack-bitmaps.sh
>> +++ b/t/t5310-pack-bitmaps.sh
>> @@ -486,6 +486,33 @@ test_bitmap_cases () {
>> grep "ignoring extra bitmap" trace2.txt
>> )
>> '
>> +
>> + test_expect_success 'load corrupt bitmap' '
>> + rm -fr repo &&
>> + git init repo &&
>> + test_when_finished "rm -fr repo" &&
>> + (
>> + cd repo &&
>> + git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
>> +
>> + test_commit base &&
>> +
>> + git repack -adb &&
>> + bitmap="$(ls .git/objects/pack/pack-*.bitmap)" &&
>> + chmod +w $bitmap &&
>> +
>> + read oid commit_off xor_off flag_off ewah_off <<-EOF &&
>> + $(test-tool bitmap list-commits-offset | head -n 1)
>> + EOF
>> + printf '\161' |
>> + dd of=$bitmap count=1 bs=1 conv=notrunc seek=$xor_off &&
>> +
>> +
>> + git rev-list --count HEAD > expect &&
>> + git rev-list --use-bitmap-index --count HEAD > actual &&
>> + test_cmp expect actual
>> + )
>> + '
>> }
>> 
>> test_bitmap_cases
> 






[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux