block: simplify handling of try to merge different sized bitmaps

We have too much logic to simply check that bitmaps are of the same
size. Let's just define that hbitmap_merge() and
bdrv_dirty_bitmap_merge_internal() require their argument bitmaps be of
same size, this simplifies things.

Let's look through the callers:

For backup_init_bcs_bitmap() we already assert that merge can't fail.

In bdrv_reclaim_dirty_bitmap_locked() we gracefully handle the error
that can't happen: successor always has same size as its parent, drop
this logic.

In bdrv_merge_dirty_bitmap() we already has assertion and separate
check. Make the check explicit and improve error message.

Signed-off-by: Vladimir Sementsov-Ogievskiy <v.sementsov-og@mail.ru>
Reviewed-by: Nikita Lapshin <nikita.lapshin@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20220517111206.23585-4-v.sementsov-og@mail.ru>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Vladimir Sementsov-Ogievskiy 2022-05-17 14:12:06 +03:00 committed by Kevin Wolf
parent 58cbfbdf73
commit 618af89e55
5 changed files with 23 additions and 51 deletions

View file

@ -873,11 +873,6 @@ void hbitmap_truncate(HBitmap *hb, uint64_t size)
}
}
bool hbitmap_can_merge(const HBitmap *a, const HBitmap *b)
{
return (a->orig_size == b->orig_size);
}
/**
* hbitmap_sparse_merge: performs dst = dst | src
* works with differing granularities.
@ -901,28 +896,24 @@ static void hbitmap_sparse_merge(HBitmap *dst, const HBitmap *src)
* Given HBitmaps A and B, let R := A (BITOR) B.
* Bitmaps A and B will not be modified,
* except when bitmap R is an alias of A or B.
*
* @return true if the merge was successful,
* false if it was not attempted.
* Bitmaps must have same size.
*/
bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result)
void hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result)
{
int i;
uint64_t j;
if (!hbitmap_can_merge(a, b) || !hbitmap_can_merge(a, result)) {
return false;
}
assert(hbitmap_can_merge(b, result));
assert(a->orig_size == result->orig_size);
assert(b->orig_size == result->orig_size);
if ((!hbitmap_count(a) && result == b) ||
(!hbitmap_count(b) && result == a)) {
return true;
return;
}
if (!hbitmap_count(a) && !hbitmap_count(b)) {
hbitmap_reset_all(result);
return true;
return;
}
if (a->granularity != b->granularity) {
@ -935,7 +926,7 @@ bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result)
if (b != result) {
hbitmap_sparse_merge(result, b);
}
return true;
return;
}
/* This merge is O(size), as BITS_PER_LONG and HBITMAP_LEVELS are constant.
@ -951,8 +942,6 @@ bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result)
/* Recompute the dirty count */
result->count = hb_count_between(result, 0, result->size - 1);
return true;
}
char *hbitmap_sha256(const HBitmap *bitmap, Error **errp)