Skip to content
Snippets Groups Projects
Commit 58cbfbdf authored by Vladimir Sementsov-Ogievskiy's avatar Vladimir Sementsov-Ogievskiy Committed by Kevin Wolf
Browse files

block: improve block_dirty_bitmap_merge(): don't allocate extra bitmap


We don't need extra bitmap. All we need is to backup the original
bitmap when we do first merge. So, drop extra temporary bitmap and work
directly with target and backup.

Still to keep old semantics, that on failure target is unchanged and
user don't need to restore, we need a local_backup variable and do
restore ourselves on failure path.

Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <v.sementsov-og@mail.ru>
Message-Id: <20220517111206.23585-3-v.sementsov-og@mail.ru>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 775b30b3
No related branches found
No related tags found
No related merge requests found
......@@ -261,8 +261,9 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
HBitmap **backup, Error **errp)
{
BlockDriverState *bs;
BdrvDirtyBitmap *dst, *src, *anon;
BdrvDirtyBitmap *dst, *src;
BlockDirtyBitmapOrStrList *lst;
HBitmap *local_backup = NULL;
GLOBAL_STATE_CODE();
......@@ -271,12 +272,6 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
return NULL;
}
anon = bdrv_create_dirty_bitmap(bs, bdrv_dirty_bitmap_granularity(dst),
NULL, errp);
if (!anon) {
return NULL;
}
for (lst = bms; lst; lst = lst->next) {
switch (lst->value->type) {
const char *name, *node;
......@@ -285,8 +280,7 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
src = bdrv_find_dirty_bitmap(bs, name);
if (!src) {
error_setg(errp, "Dirty bitmap '%s' not found", name);
dst = NULL;
goto out;
goto fail;
}
break;
case QTYPE_QDICT:
......@@ -294,29 +288,36 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
name = lst->value->u.external.name;
src = block_dirty_bitmap_lookup(node, name, NULL, errp);
if (!src) {
dst = NULL;
goto out;
goto fail;
}
break;
default:
abort();
}
if (!bdrv_merge_dirty_bitmap(anon, src, NULL, errp)) {
dst = NULL;
goto out;
/* We do backup only for first merge operation */
if (!bdrv_merge_dirty_bitmap(dst, src,
local_backup ? NULL : &local_backup,
errp))
{
goto fail;
}
}
/* Merge into dst; dst is unchanged on failure. */
if (!bdrv_merge_dirty_bitmap(dst, anon, backup, errp)) {
dst = NULL;
goto out;
if (backup) {
*backup = local_backup;
} else {
hbitmap_free(local_backup);
}
out:
bdrv_release_dirty_bitmap(anon);
return dst;
fail:
if (local_backup) {
bdrv_restore_dirty_bitmap(dst, local_backup);
}
return NULL;
}
void qmp_block_dirty_bitmap_merge(const char *node, const char *target,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment