yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-block-dirty-bitmap-Add-bdrv_dirty_iter_next_area.patch

ae23c9
From 36323c9384909d2213fafb77b1fcf0ddbfcaaffc Mon Sep 17 00:00:00 2001
ae23c9
From: John Snow <jsnow@redhat.com>
ae23c9
Date: Tue, 20 Nov 2018 18:18:09 +0000
ae23c9
Subject: [PATCH 15/35] block/dirty-bitmap: Add bdrv_dirty_iter_next_area
ae23c9
ae23c9
RH-Author: John Snow <jsnow@redhat.com>
ae23c9
Message-id: <20181120181828.15132-6-jsnow@redhat.com>
ae23c9
Patchwork-id: 83054
ae23c9
O-Subject: [RHEL8/rhel qemu-kvm PATCH 05/24] block/dirty-bitmap: Add bdrv_dirty_iter_next_area
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: Max Reitz <mreitz@redhat.com>
ae23c9
ae23c9
This new function allows to look for a consecutively dirty area in a
ae23c9
dirty bitmap.
ae23c9
ae23c9
Signed-off-by: Max Reitz <mreitz@redhat.com>
ae23c9
Reviewed-by: Fam Zheng <famz@redhat.com>
ae23c9
Reviewed-by: John Snow <jsnow@redhat.com>
ae23c9
Message-id: 20180613181823.13618-10-mreitz@redhat.com
ae23c9
Signed-off-by: Max Reitz <mreitz@redhat.com>
ae23c9
(cherry picked from commit 72d10a94213a954ad569095cb4491f2ae0853c40)
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         | 55 ++++++++++++++++++++++++++++++++++++++++++++
ae23c9
 include/block/dirty-bitmap.h |  2 ++
ae23c9
 2 files changed, 57 insertions(+)
ae23c9
ae23c9
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
ae23c9
index 236dce1..c9b8a6f 100644
ae23c9
--- a/block/dirty-bitmap.c
ae23c9
+++ b/block/dirty-bitmap.c
ae23c9
@@ -528,6 +528,61 @@ int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
ae23c9
     return hbitmap_iter_next(&iter->hbi, true);
ae23c9
 }
ae23c9
 
ae23c9
+/**
ae23c9
+ * Return the next consecutively dirty area in the dirty bitmap
ae23c9
+ * belonging to the given iterator @iter.
ae23c9
+ *
ae23c9
+ * @max_offset: Maximum value that may be returned for
ae23c9
+ *              *offset + *bytes
ae23c9
+ * @offset:     Will contain the start offset of the next dirty area
ae23c9
+ * @bytes:      Will contain the length of the next dirty area
ae23c9
+ *
ae23c9
+ * Returns: True if a dirty area could be found before max_offset
ae23c9
+ *          (which means that *offset and *bytes then contain valid
ae23c9
+ *          values), false otherwise.
ae23c9
+ *
ae23c9
+ * Note that @iter is never advanced if false is returned.  If an area
ae23c9
+ * is found (which means that true is returned), it will be advanced
ae23c9
+ * past that area.
ae23c9
+ */
ae23c9
+bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t max_offset,
ae23c9
+                               uint64_t *offset, int *bytes)
ae23c9
+{
ae23c9
+    uint32_t granularity = bdrv_dirty_bitmap_granularity(iter->bitmap);
ae23c9
+    uint64_t gran_max_offset;
ae23c9
+    int64_t ret;
ae23c9
+    int size;
ae23c9
+
ae23c9
+    if (max_offset == iter->bitmap->size) {
ae23c9
+        /* If max_offset points to the image end, round it up by the
ae23c9
+         * bitmap granularity */
ae23c9
+        gran_max_offset = ROUND_UP(max_offset, granularity);
ae23c9
+    } else {
ae23c9
+        gran_max_offset = max_offset;
ae23c9
+    }
ae23c9
+
ae23c9
+    ret = hbitmap_iter_next(&iter->hbi, false);
ae23c9
+    if (ret < 0 || ret + granularity > gran_max_offset) {
ae23c9
+        return false;
ae23c9
+    }
ae23c9
+
ae23c9
+    *offset = ret;
ae23c9
+    size = 0;
ae23c9
+
ae23c9
+    assert(granularity <= INT_MAX);
ae23c9
+
ae23c9
+    do {
ae23c9
+        /* Advance iterator */
ae23c9
+        ret = hbitmap_iter_next(&iter->hbi, true);
ae23c9
+        size += granularity;
ae23c9
+    } while (ret + granularity <= gran_max_offset &&
ae23c9
+             hbitmap_iter_next(&iter->hbi, false) == ret + granularity &&
ae23c9
+             size <= INT_MAX - granularity);
ae23c9
+
ae23c9
+    *bytes = MIN(size, max_offset - *offset);
ae23c9
+    return true;
ae23c9
+}
ae23c9
+
ae23c9
 /* Called within bdrv_dirty_bitmap_lock..unlock */
ae23c9
 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
ae23c9
                                   int64_t offset, int64_t bytes)
ae23c9
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
ae23c9
index bf68dd7..259bd27 100644
ae23c9
--- a/include/block/dirty-bitmap.h
ae23c9
+++ b/include/block/dirty-bitmap.h
ae23c9
@@ -83,6 +83,8 @@ void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
ae23c9
 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
ae23c9
                                     int64_t offset, int64_t bytes);
ae23c9
 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
ae23c9
+bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t max_offset,
ae23c9
+                               uint64_t *offset, int *bytes);
ae23c9
 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t offset);
ae23c9
 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
ae23c9
 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9