|
@@ -314,7 +314,7 @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
|
|
|
+ if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
|
|
|
error_setg(errp, "Merging of parent and successor bitmap failed");
|
|
|
return NULL;
|
|
|
}
|
|
@@ -791,8 +791,10 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset)
|
|
|
}
|
|
|
|
|
|
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
|
|
- Error **errp)
|
|
|
+ HBitmap **backup, Error **errp)
|
|
|
{
|
|
|
+ bool ret;
|
|
|
+
|
|
|
/* only bitmaps from one bds are supported */
|
|
|
assert(dest->mutex == src->mutex);
|
|
|
|
|
@@ -810,11 +812,20 @@ void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- if (!hbitmap_merge(dest->bitmap, src->bitmap)) {
|
|
|
+ if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
|
|
|
error_setg(errp, "Bitmaps are incompatible and can't be merged");
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
+ if (backup) {
|
|
|
+ *backup = dest->bitmap;
|
|
|
+ dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
|
|
|
+ ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
|
|
|
+ } else {
|
|
|
+ ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
|
|
|
+ }
|
|
|
+ assert(ret);
|
|
|
+
|
|
|
out:
|
|
|
qemu_mutex_unlock(dest->mutex);
|
|
|
}
|