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