|
|
7711c0 |
From afaa0a6c9269fc840a8a48b2ca2693c1c09f78ed Mon Sep 17 00:00:00 2001
|
|
|
7711c0 |
From: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Date: Wed, 20 Mar 2019 21:48:31 +0100
|
|
|
7711c0 |
Subject: [PATCH 038/163] dirty-bitmap: add bdrv_dirty_bitmap_next_dirty_area
|
|
|
7711c0 |
|
|
|
7711c0 |
RH-Author: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Message-id: <20190320214838.22027-4-jsnow@redhat.com>
|
|
|
7711c0 |
Patchwork-id: 84998
|
|
|
7711c0 |
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 03/10] dirty-bitmap: add bdrv_dirty_bitmap_next_dirty_area
|
|
|
7711c0 |
Bugzilla: 1691048
|
|
|
7711c0 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
7711c0 |
|
|
|
7711c0 |
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
7711c0 |
|
|
|
7711c0 |
The function alters bdrv_dirty_iter_next_area(), which is wrong and
|
|
|
7711c0 |
less efficient (see further commit
|
|
|
7711c0 |
"block/mirror: fix and improve do_sync_target_write" for description).
|
|
|
7711c0 |
|
|
|
7711c0 |
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
7711c0 |
(cherry picked from commit a78a1a48cd1a2e86f23f113bb05e2d3dd8ae0bf6)
|
|
|
7711c0 |
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
7711c0 |
---
|
|
|
7711c0 |
block/dirty-bitmap.c | 6 ++++++
|
|
|
7711c0 |
include/block/dirty-bitmap.h | 2 ++
|
|
|
7711c0 |
include/qemu/hbitmap.h | 16 ++++++++++++++++
|
|
|
7711c0 |
util/hbitmap.c | 39 +++++++++++++++++++++++++++++++++++++++
|
|
|
7711c0 |
4 files changed, 63 insertions(+)
|
|
|
7711c0 |
|
|
|
7711c0 |
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
|
|
|
7711c0 |
index b162f4a..c151837 100644
|
|
|
7711c0 |
--- a/block/dirty-bitmap.c
|
|
|
7711c0 |
+++ b/block/dirty-bitmap.c
|
|
|
7711c0 |
@@ -787,6 +787,12 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset,
|
|
|
7711c0 |
return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
+bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
|
|
|
7711c0 |
+ uint64_t *offset, uint64_t *bytes)
|
|
|
7711c0 |
+{
|
|
|
7711c0 |
+ return hbitmap_next_dirty_area(bitmap->bitmap, offset, bytes);
|
|
|
7711c0 |
+}
|
|
|
7711c0 |
+
|
|
|
7711c0 |
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
|
|
7711c0 |
HBitmap **backup, Error **errp)
|
|
|
7711c0 |
{
|
|
|
7711c0 |
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
|
|
|
7711c0 |
index 102ccdd..4ef00ca 100644
|
|
|
7711c0 |
--- a/include/block/dirty-bitmap.h
|
|
|
7711c0 |
+++ b/include/block/dirty-bitmap.h
|
|
|
7711c0 |
@@ -101,6 +101,8 @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
|
|
|
7711c0 |
char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp);
|
|
|
7711c0 |
int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset,
|
|
|
7711c0 |
uint64_t bytes);
|
|
|
7711c0 |
+bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
|
|
|
7711c0 |
+ uint64_t *offset, uint64_t *bytes);
|
|
|
7711c0 |
BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
|
|
|
7711c0 |
BdrvDirtyBitmap *bitmap,
|
|
|
7711c0 |
Error **errp);
|
|
|
7711c0 |
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
|
|
|
7711c0 |
index 1359755..097dce3 100644
|
|
|
7711c0 |
--- a/include/qemu/hbitmap.h
|
|
|
7711c0 |
+++ b/include/qemu/hbitmap.h
|
|
|
7711c0 |
@@ -311,6 +311,22 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi);
|
|
|
7711c0 |
*/
|
|
|
7711c0 |
int64_t hbitmap_next_zero(const HBitmap *hb, uint64_t start, uint64_t count);
|
|
|
7711c0 |
|
|
|
7711c0 |
+/* hbitmap_next_dirty_area:
|
|
|
7711c0 |
+ * @hb: The HBitmap to operate on
|
|
|
7711c0 |
+ * @start: in-out parameter.
|
|
|
7711c0 |
+ * in: the offset to start from
|
|
|
7711c0 |
+ * out: (if area found) start of found area
|
|
|
7711c0 |
+ * @count: in-out parameter.
|
|
|
7711c0 |
+ * in: length of requested region
|
|
|
7711c0 |
+ * out: length of found area
|
|
|
7711c0 |
+ *
|
|
|
7711c0 |
+ * If dirty area found within [@start, @start + @count), returns true and sets
|
|
|
7711c0 |
+ * @offset and @bytes appropriately. Otherwise returns false and leaves @offset
|
|
|
7711c0 |
+ * and @bytes unchanged.
|
|
|
7711c0 |
+ */
|
|
|
7711c0 |
+bool hbitmap_next_dirty_area(const HBitmap *hb, uint64_t *start,
|
|
|
7711c0 |
+ uint64_t *count);
|
|
|
7711c0 |
+
|
|
|
7711c0 |
/* hbitmap_create_meta:
|
|
|
7711c0 |
* Create a "meta" hbitmap to track dirtiness of the bits in this HBitmap.
|
|
|
7711c0 |
* The caller owns the created bitmap and must call hbitmap_free_meta(hb) to
|
|
|
7711c0 |
diff --git a/util/hbitmap.c b/util/hbitmap.c
|
|
|
7711c0 |
index 09b3719..fa35652 100644
|
|
|
7711c0 |
--- a/util/hbitmap.c
|
|
|
7711c0 |
+++ b/util/hbitmap.c
|
|
|
7711c0 |
@@ -246,6 +246,45 @@ int64_t hbitmap_next_zero(const HBitmap *hb, uint64_t start, uint64_t count)
|
|
|
7711c0 |
return res;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
+bool hbitmap_next_dirty_area(const HBitmap *hb, uint64_t *start,
|
|
|
7711c0 |
+ uint64_t *count)
|
|
|
7711c0 |
+{
|
|
|
7711c0 |
+ HBitmapIter hbi;
|
|
|
7711c0 |
+ int64_t firt_dirty_off, area_end;
|
|
|
7711c0 |
+ uint32_t granularity = 1UL << hb->granularity;
|
|
|
7711c0 |
+ uint64_t end;
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ if (*start >= hb->orig_size || *count == 0) {
|
|
|
7711c0 |
+ return false;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ end = *count > hb->orig_size - *start ? hb->orig_size : *start + *count;
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ hbitmap_iter_init(&hbi, hb, *start);
|
|
|
7711c0 |
+ firt_dirty_off = hbitmap_iter_next(&hbi, false);
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ if (firt_dirty_off < 0 || firt_dirty_off >= end) {
|
|
|
7711c0 |
+ return false;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ if (firt_dirty_off + granularity >= end) {
|
|
|
7711c0 |
+ area_end = end;
|
|
|
7711c0 |
+ } else {
|
|
|
7711c0 |
+ area_end = hbitmap_next_zero(hb, firt_dirty_off + granularity,
|
|
|
7711c0 |
+ end - firt_dirty_off - granularity);
|
|
|
7711c0 |
+ if (area_end < 0) {
|
|
|
7711c0 |
+ area_end = end;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ if (firt_dirty_off > *start) {
|
|
|
7711c0 |
+ *start = firt_dirty_off;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+ *count = area_end - *start;
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ return true;
|
|
|
7711c0 |
+}
|
|
|
7711c0 |
+
|
|
|
7711c0 |
bool hbitmap_empty(const HBitmap *hb)
|
|
|
7711c0 |
{
|
|
|
7711c0 |
return hb->count == 0;
|
|
|
7711c0 |
--
|
|
|
7711c0 |
1.8.3.1
|
|
|
7711c0 |
|