Blame SOURCES/kvm-dirty-bitmap-make-it-possible-to-restore-bitmap-afte.patch

ae23c9
From 4122c0993f5b6de8db0227f5751e1f49e0b4354c Mon Sep 17 00:00:00 2001
ae23c9
From: John Snow <jsnow@redhat.com>
ae23c9
Date: Tue, 20 Nov 2018 18:18:13 +0000
ae23c9
Subject: [PATCH 19/35] dirty-bitmap: make it possible to restore bitmap after
ae23c9
 merge
ae23c9
ae23c9
RH-Author: John Snow <jsnow@redhat.com>
ae23c9
Message-id: <20181120181828.15132-10-jsnow@redhat.com>
ae23c9
Patchwork-id: 83057
ae23c9
O-Subject: [RHEL8/rhel qemu-kvm PATCH 09/24] dirty-bitmap: make it possible to restore bitmap after merge
ae23c9
Bugzilla: 1518989
ae23c9
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
ae23c9
RH-Acked-by: Max Reitz <mreitz@redhat.com>
ae23c9
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
ae23c9
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
ae23c9
ae23c9
Add backup parameter to bdrv_merge_dirty_bitmap() to be used then with
ae23c9
bdrv_restore_dirty_bitmap() if it needed to restore the bitmap after
ae23c9
merge operation.
ae23c9
ae23c9
This is needed to implement bitmap merge transaction action in further
ae23c9
commit.
ae23c9
ae23c9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
ae23c9
Reviewed-by: John Snow <jsnow@redhat.com>
ae23c9
(cherry picked from commit fa000f2f9fd96a75a0a33d50ead247fce11da92a)
ae23c9
Signed-off-by: John Snow <jsnow@redhat.com>
ae23c9
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ae23c9
---
ae23c9
 block/dirty-bitmap.c         | 17 ++++++++++++++---
ae23c9
 blockdev.c                   |  2 +-
ae23c9
 include/block/dirty-bitmap.h |  2 +-
ae23c9
 include/qemu/hbitmap.h       | 25 ++++++++++++++++---------
ae23c9
 util/hbitmap.c               | 11 ++++++++---
ae23c9
 5 files changed, 40 insertions(+), 17 deletions(-)
ae23c9
ae23c9
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
ae23c9
index 017ee9d..8ac933c 100644
ae23c9
--- a/block/dirty-bitmap.c
ae23c9
+++ b/block/dirty-bitmap.c
ae23c9
@@ -314,7 +314,7 @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
ae23c9
         return NULL;
ae23c9
     }
ae23c9
 
ae23c9
-    if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
ae23c9
+    if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
ae23c9
         error_setg(errp, "Merging of parent and successor bitmap failed");
ae23c9
         return NULL;
ae23c9
     }
ae23c9
@@ -791,8 +791,10 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset)
ae23c9
 }
ae23c9
 
ae23c9
 void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
ae23c9
-                             Error **errp)
ae23c9
+                             HBitmap **backup, Error **errp)
ae23c9
 {
ae23c9
+    bool ret;
ae23c9
+
ae23c9
     /* only bitmaps from one bds are supported */
ae23c9
     assert(dest->mutex == src->mutex);
ae23c9
 
ae23c9
@@ -810,11 +812,20 @@ void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
ae23c9
         goto out;
ae23c9
     }
ae23c9
 
ae23c9
-    if (!hbitmap_merge(dest->bitmap, src->bitmap)) {
ae23c9
+    if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
ae23c9
         error_setg(errp, "Bitmaps are incompatible and can't be merged");
ae23c9
         goto out;
ae23c9
     }
ae23c9
 
ae23c9
+    if (backup) {
ae23c9
+        *backup = dest->bitmap;
ae23c9
+        dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
ae23c9
+        ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
ae23c9
+    } else {
ae23c9
+        ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
ae23c9
+    }
ae23c9
+    assert(ret);
ae23c9
+
ae23c9
 out:
ae23c9
     qemu_mutex_unlock(dest->mutex);
ae23c9
 }
ae23c9
diff --git a/blockdev.c b/blockdev.c
ae23c9
index 2d86465..a10fbbd 100644
ae23c9
--- a/blockdev.c
ae23c9
+++ b/blockdev.c
ae23c9
@@ -3077,7 +3077,7 @@ void qmp_x_block_dirty_bitmap_merge(const char *node, const char *dst_name,
ae23c9
         return;
ae23c9
     }
ae23c9
 
ae23c9
-    bdrv_merge_dirty_bitmap(dst, src, errp);
ae23c9
+    bdrv_merge_dirty_bitmap(dst, src, NULL, errp);
ae23c9
 }
ae23c9
 
ae23c9
 BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
ae23c9
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
ae23c9
index 259bd27..201ff7f 100644
ae23c9
--- a/include/block/dirty-bitmap.h
ae23c9
+++ b/include/block/dirty-bitmap.h
ae23c9
@@ -71,7 +71,7 @@ void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap,
ae23c9
                                        bool persistent);
ae23c9
 void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked);
ae23c9
 void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
ae23c9
-                             Error **errp);
ae23c9
+                             HBitmap **backup, Error **errp);
ae23c9
 
ae23c9
 /* Functions that require manual locking.  */
ae23c9
 void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap);
ae23c9
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
ae23c9
index ddca52c..a7cb780 100644
ae23c9
--- a/include/qemu/hbitmap.h
ae23c9
+++ b/include/qemu/hbitmap.h
ae23c9
@@ -73,16 +73,23 @@ void hbitmap_truncate(HBitmap *hb, uint64_t size);
ae23c9
 
ae23c9
 /**
ae23c9
  * hbitmap_merge:
ae23c9
- * @a: The bitmap to store the result in.
ae23c9
- * @b: The bitmap to merge into @a.
ae23c9
- * @return true if the merge was successful,
ae23c9
- *         false if it was not attempted.
ae23c9
- *
ae23c9
- * Merge two bitmaps together.
ae23c9
- * A := A (BITOR) B.
ae23c9
- * B is left unmodified.
ae23c9
+ *
ae23c9
+ * Store result of merging @a and @b into @result.
ae23c9
+ * @result is allowed to be equal to @a or @b.
ae23c9
+ *
ae23c9
+ * Return true if the merge was successful,
ae23c9
+ *        false if it was not attempted.
ae23c9
+ */
ae23c9
+bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result);
ae23c9
+
ae23c9
+/**
ae23c9
+ * hbitmap_can_merge:
ae23c9
+ *
ae23c9
+ * hbitmap_can_merge(a, b) && hbitmap_can_merge(a, result) is sufficient and
ae23c9
+ * necessary for hbitmap_merge will not fail.
ae23c9
+ *
ae23c9
  */
ae23c9
-bool hbitmap_merge(HBitmap *a, const HBitmap *b);
ae23c9
+bool hbitmap_can_merge(const HBitmap *a, const HBitmap *b);
ae23c9
 
ae23c9
 /**
ae23c9
  * hbitmap_empty:
ae23c9
diff --git a/util/hbitmap.c b/util/hbitmap.c
ae23c9
index bcd3040..d5aca51 100644
ae23c9
--- a/util/hbitmap.c
ae23c9
+++ b/util/hbitmap.c
ae23c9
@@ -723,6 +723,10 @@ void hbitmap_truncate(HBitmap *hb, uint64_t size)
ae23c9
     }
ae23c9
 }
ae23c9
 
ae23c9
+bool hbitmap_can_merge(const HBitmap *a, const HBitmap *b)
ae23c9
+{
ae23c9
+    return (a->size == b->size) && (a->granularity == b->granularity);
ae23c9
+}
ae23c9
 
ae23c9
 /**
ae23c9
  * Given HBitmaps A and B, let A := A (BITOR) B.
ae23c9
@@ -731,14 +735,15 @@ void hbitmap_truncate(HBitmap *hb, uint64_t size)
ae23c9
  * @return true if the merge was successful,
ae23c9
  *         false if it was not attempted.
ae23c9
  */
ae23c9
-bool hbitmap_merge(HBitmap *a, const HBitmap *b)
ae23c9
+bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result)
ae23c9
 {
ae23c9
     int i;
ae23c9
     uint64_t j;
ae23c9
 
ae23c9
-    if ((a->size != b->size) || (a->granularity != b->granularity)) {
ae23c9
+    if (!hbitmap_can_merge(a, b) || !hbitmap_can_merge(a, result)) {
ae23c9
         return false;
ae23c9
     }
ae23c9
+    assert(hbitmap_can_merge(b, result));
ae23c9
 
ae23c9
     if (hbitmap_count(b) == 0) {
ae23c9
         return true;
ae23c9
@@ -750,7 +755,7 @@ bool hbitmap_merge(HBitmap *a, const HBitmap *b)
ae23c9
      */
ae23c9
     for (i = HBITMAP_LEVELS - 1; i >= 0; i--) {
ae23c9
         for (j = 0; j < a->sizes[i]; j++) {
ae23c9
-            a->levels[i][j] |= b->levels[i][j];
ae23c9
+            result->levels[i][j] = a->levels[i][j] | b->levels[i][j];
ae23c9
         }
ae23c9
     }
ae23c9
 
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9