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

@ -309,10 +309,7 @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BdrvDirtyBitmap *parent,
return NULL;
}
if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
error_setg(errp, "Merging of parent and successor bitmap failed");
return NULL;
}
hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap);
parent->disabled = successor->disabled;
parent->busy = false;
@ -912,13 +909,15 @@ bool bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
goto out;
}
if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
error_setg(errp, "Bitmaps are incompatible and can't be merged");
if (bdrv_dirty_bitmap_size(src) != bdrv_dirty_bitmap_size(dest)) {
error_setg(errp, "Bitmaps are of different sizes (destination size is %"
PRId64 ", source size is %" PRId64 ") and can't be merged",
bdrv_dirty_bitmap_size(dest), bdrv_dirty_bitmap_size(src));
goto out;
}
ret = bdrv_dirty_bitmap_merge_internal(dest, src, backup, false);
assert(ret);
bdrv_dirty_bitmap_merge_internal(dest, src, backup, false);
ret = true;
out:
bdrv_dirty_bitmaps_unlock(dest->bs);
@ -932,17 +931,16 @@ out:
/**
* bdrv_dirty_bitmap_merge_internal: merge src into dest.
* Does NOT check bitmap permissions; not suitable for use as public API.
* @dest, @src and @backup (if not NULL) must have same size.
*
* @backup: If provided, make a copy of dest here prior to merge.
* @lock: If true, lock and unlock bitmaps on the way in/out.
* returns true if the merge succeeded; false if unattempted.
*/
bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
void bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
const BdrvDirtyBitmap *src,
HBitmap **backup,
bool lock)
{
bool ret;
IO_CODE();
assert(!bdrv_dirty_bitmap_readonly(dest));
@ -959,9 +957,9 @@ bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
if (backup) {
*backup = dest->bitmap;
dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
hbitmap_merge(*backup, src->bitmap, dest->bitmap);
} else {
ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
}
if (lock) {
@ -970,6 +968,4 @@ bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
bdrv_dirty_bitmaps_unlock(src->bs);
}
}
return ret;
}