|
|
7711c0 |
From 8767d53aa1dd2df28d3093bb1c6d99e54916eb4a Mon Sep 17 00:00:00 2001
|
|
|
7711c0 |
From: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Date: Wed, 6 Feb 2019 22:12:28 +0100
|
|
|
7711c0 |
Subject: [PATCH 18/33] dirty-bitmap: make it possible to restore bitmap after
|
|
|
7711c0 |
merge
|
|
|
7711c0 |
|
|
|
7711c0 |
RH-Author: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Message-id: <20190206221243.7407-9-jsnow@redhat.com>
|
|
|
7711c0 |
Patchwork-id: 84267
|
|
|
7711c0 |
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH v2 08/23] dirty-bitmap: make it possible to restore bitmap after merge
|
|
|
7711c0 |
Bugzilla: 1658343
|
|
|
7711c0 |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
7711c0 |
|
|
|
7711c0 |
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
7711c0 |
|
|
|
7711c0 |
Add backup parameter to bdrv_merge_dirty_bitmap() to be used then with
|
|
|
7711c0 |
bdrv_restore_dirty_bitmap() if it needed to restore the bitmap after
|
|
|
7711c0 |
merge operation.
|
|
|
7711c0 |
|
|
|
7711c0 |
This is needed to implement bitmap merge transaction action in further
|
|
|
7711c0 |
commit.
|
|
|
7711c0 |
|
|
|
7711c0 |
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
7711c0 |
Reviewed-by: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
(cherry picked from commit fa000f2f9fd96a75a0a33d50ead247fce11da92a)
|
|
|
7711c0 |
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
7711c0 |
---
|
|
|
7711c0 |
block/dirty-bitmap.c | 17 ++++++++++++++---
|
|
|
7711c0 |
blockdev.c | 2 +-
|
|
|
7711c0 |
include/block/dirty-bitmap.h | 2 +-
|
|
|
7711c0 |
include/qemu/hbitmap.h | 25 ++++++++++++++++---------
|
|
|
7711c0 |
util/hbitmap.c | 11 ++++++++---
|
|
|
7711c0 |
5 files changed, 40 insertions(+), 17 deletions(-)
|
|
|
7711c0 |
|
|
|
7711c0 |
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
|
|
|
7711c0 |
index cadde5c..a9421cd 100644
|
|
|
7711c0 |
--- a/block/dirty-bitmap.c
|
|
|
7711c0 |
+++ b/block/dirty-bitmap.c
|
|
|
7711c0 |
@@ -314,7 +314,7 @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
|
|
|
7711c0 |
return NULL;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
- if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
|
|
|
7711c0 |
+ if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
|
|
|
7711c0 |
error_setg(errp, "Merging of parent and successor bitmap failed");
|
|
|
7711c0 |
return NULL;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
@@ -790,8 +790,10 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset)
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
|
|
7711c0 |
- Error **errp)
|
|
|
7711c0 |
+ HBitmap **backup, Error **errp)
|
|
|
7711c0 |
{
|
|
|
7711c0 |
+ bool ret;
|
|
|
7711c0 |
+
|
|
|
7711c0 |
/* only bitmaps from one bds are supported */
|
|
|
7711c0 |
assert(dest->mutex == src->mutex);
|
|
|
7711c0 |
|
|
|
7711c0 |
@@ -809,11 +811,20 @@ void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
|
|
7711c0 |
goto out;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
- if (!hbitmap_merge(dest->bitmap, src->bitmap)) {
|
|
|
7711c0 |
+ if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
|
|
|
7711c0 |
error_setg(errp, "Bitmaps are incompatible and can't be merged");
|
|
|
7711c0 |
goto out;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
+ if (backup) {
|
|
|
7711c0 |
+ *backup = dest->bitmap;
|
|
|
7711c0 |
+ dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
|
|
|
7711c0 |
+ ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
|
|
|
7711c0 |
+ } else {
|
|
|
7711c0 |
+ ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+ assert(ret);
|
|
|
7711c0 |
+
|
|
|
7711c0 |
out:
|
|
|
7711c0 |
qemu_mutex_unlock(dest->mutex);
|
|
|
7711c0 |
}
|
|
|
7711c0 |
diff --git a/blockdev.c b/blockdev.c
|
|
|
7711c0 |
index 5d9508c..823a97f 100644
|
|
|
7711c0 |
--- a/blockdev.c
|
|
|
7711c0 |
+++ b/blockdev.c
|
|
|
7711c0 |
@@ -3119,7 +3119,7 @@ void qmp_x_block_dirty_bitmap_merge(const char *node, const char *dst_name,
|
|
|
7711c0 |
return;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
- bdrv_merge_dirty_bitmap(dst, src, errp);
|
|
|
7711c0 |
+ bdrv_merge_dirty_bitmap(dst, src, NULL, errp);
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
|
|
|
7711c0 |
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
|
|
|
7711c0 |
index 259bd27..201ff7f 100644
|
|
|
7711c0 |
--- a/include/block/dirty-bitmap.h
|
|
|
7711c0 |
+++ b/include/block/dirty-bitmap.h
|
|
|
7711c0 |
@@ -71,7 +71,7 @@ void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap,
|
|
|
7711c0 |
bool persistent);
|
|
|
7711c0 |
void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked);
|
|
|
7711c0 |
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
|
|
7711c0 |
- Error **errp);
|
|
|
7711c0 |
+ HBitmap **backup, Error **errp);
|
|
|
7711c0 |
|
|
|
7711c0 |
/* Functions that require manual locking. */
|
|
|
7711c0 |
void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap);
|
|
|
7711c0 |
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
|
|
|
7711c0 |
index ddca52c..a7cb780 100644
|
|
|
7711c0 |
--- a/include/qemu/hbitmap.h
|
|
|
7711c0 |
+++ b/include/qemu/hbitmap.h
|
|
|
7711c0 |
@@ -73,16 +73,23 @@ void hbitmap_truncate(HBitmap *hb, uint64_t size);
|
|
|
7711c0 |
|
|
|
7711c0 |
/**
|
|
|
7711c0 |
* hbitmap_merge:
|
|
|
7711c0 |
- * @a: The bitmap to store the result in.
|
|
|
7711c0 |
- * @b: The bitmap to merge into @a.
|
|
|
7711c0 |
- * @return true if the merge was successful,
|
|
|
7711c0 |
- * false if it was not attempted.
|
|
|
7711c0 |
- *
|
|
|
7711c0 |
- * Merge two bitmaps together.
|
|
|
7711c0 |
- * A := A (BITOR) B.
|
|
|
7711c0 |
- * B is left unmodified.
|
|
|
7711c0 |
+ *
|
|
|
7711c0 |
+ * Store result of merging @a and @b into @result.
|
|
|
7711c0 |
+ * @result is allowed to be equal to @a or @b.
|
|
|
7711c0 |
+ *
|
|
|
7711c0 |
+ * Return true if the merge was successful,
|
|
|
7711c0 |
+ * false if it was not attempted.
|
|
|
7711c0 |
+ */
|
|
|
7711c0 |
+bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result);
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+/**
|
|
|
7711c0 |
+ * hbitmap_can_merge:
|
|
|
7711c0 |
+ *
|
|
|
7711c0 |
+ * hbitmap_can_merge(a, b) && hbitmap_can_merge(a, result) is sufficient and
|
|
|
7711c0 |
+ * necessary for hbitmap_merge will not fail.
|
|
|
7711c0 |
+ *
|
|
|
7711c0 |
*/
|
|
|
7711c0 |
-bool hbitmap_merge(HBitmap *a, const HBitmap *b);
|
|
|
7711c0 |
+bool hbitmap_can_merge(const HBitmap *a, const HBitmap *b);
|
|
|
7711c0 |
|
|
|
7711c0 |
/**
|
|
|
7711c0 |
* hbitmap_empty:
|
|
|
7711c0 |
diff --git a/util/hbitmap.c b/util/hbitmap.c
|
|
|
7711c0 |
index bcd3040..d5aca51 100644
|
|
|
7711c0 |
--- a/util/hbitmap.c
|
|
|
7711c0 |
+++ b/util/hbitmap.c
|
|
|
7711c0 |
@@ -723,6 +723,10 @@ void hbitmap_truncate(HBitmap *hb, uint64_t size)
|
|
|
7711c0 |
}
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
+bool hbitmap_can_merge(const HBitmap *a, const HBitmap *b)
|
|
|
7711c0 |
+{
|
|
|
7711c0 |
+ return (a->size == b->size) && (a->granularity == b->granularity);
|
|
|
7711c0 |
+}
|
|
|
7711c0 |
|
|
|
7711c0 |
/**
|
|
|
7711c0 |
* Given HBitmaps A and B, let A := A (BITOR) B.
|
|
|
7711c0 |
@@ -731,14 +735,15 @@ void hbitmap_truncate(HBitmap *hb, uint64_t size)
|
|
|
7711c0 |
* @return true if the merge was successful,
|
|
|
7711c0 |
* false if it was not attempted.
|
|
|
7711c0 |
*/
|
|
|
7711c0 |
-bool hbitmap_merge(HBitmap *a, const HBitmap *b)
|
|
|
7711c0 |
+bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result)
|
|
|
7711c0 |
{
|
|
|
7711c0 |
int i;
|
|
|
7711c0 |
uint64_t j;
|
|
|
7711c0 |
|
|
|
7711c0 |
- if ((a->size != b->size) || (a->granularity != b->granularity)) {
|
|
|
7711c0 |
+ if (!hbitmap_can_merge(a, b) || !hbitmap_can_merge(a, result)) {
|
|
|
7711c0 |
return false;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
+ assert(hbitmap_can_merge(b, result));
|
|
|
7711c0 |
|
|
|
7711c0 |
if (hbitmap_count(b) == 0) {
|
|
|
7711c0 |
return true;
|
|
|
7711c0 |
@@ -750,7 +755,7 @@ bool hbitmap_merge(HBitmap *a, const HBitmap *b)
|
|
|
7711c0 |
*/
|
|
|
7711c0 |
for (i = HBITMAP_LEVELS - 1; i >= 0; i--) {
|
|
|
7711c0 |
for (j = 0; j < a->sizes[i]; j++) {
|
|
|
7711c0 |
- a->levels[i][j] |= b->levels[i][j];
|
|
|
7711c0 |
+ result->levels[i][j] = a->levels[i][j] | b->levels[i][j];
|
|
|
7711c0 |
}
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
--
|
|
|
7711c0 |
1.8.3.1
|
|
|
7711c0 |
|