[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH RFC for-2.6 3/3] block: Support meta dirty bitmap
From: |
Fam Zheng |
Subject: |
[Qemu-devel] [PATCH RFC for-2.6 3/3] block: Support meta dirty bitmap |
Date: |
Mon, 7 Dec 2015 13:59:55 +0800 |
The added group of operations enables tracking of the changed bits in
the dirty bitmap.
Signed-off-by: Fam Zheng <address@hidden>
---
block.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
block/mirror.c | 3 ++-
blockdev.c | 3 ++-
include/block/block.h | 11 +++++++++++
migration/block.c | 2 +-
5 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/block.c b/block.c
index 3a7324b..a9beb04 100644
--- a/block.c
+++ b/block.c
@@ -64,6 +64,7 @@
*/
struct BdrvDirtyBitmap {
HBitmap *bitmap; /* Dirty sector bitmap implementation */
+ HBitmap *meta; /* Meta dirty bitmap */
BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
char *name; /* Optional non-empty unique ID */
int64_t size; /* Size of the bitmap (Number of sectors) */
@@ -3153,6 +3154,7 @@ void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
uint32_t granularity,
const char *name,
+ bool create_meta,
Error **errp)
{
int64_t bitmap_size;
@@ -3178,10 +3180,52 @@ BdrvDirtyBitmap
*bdrv_create_dirty_bitmap(BlockDriverState *bs,
bitmap->size = bitmap_size;
bitmap->name = g_strdup(name);
bitmap->disabled = false;
+ if (create_meta) {
+ bitmap->meta = hbitmap_create_meta(bitmap->bitmap);
+ }
QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
return bitmap;
}
+void bdrv_create_meta_dirty_bitmap(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap)
+{
+ assert(!bitmap->meta);
+ bitmap->meta = hbitmap_create_meta(bitmap->bitmap);
+}
+
+void bdrv_release_meta_dirty_bitmap(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap)
+{
+ assert(bitmap->meta);
+ hbitmap_free(bitmap->meta);
+ bitmap->meta = NULL;
+}
+
+int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap, int64_t sector,
+ int nb_sectors)
+{
+ uint64_t i;
+ int gran = bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
+
+ /* To optimize: we can make hbitmap to internally check the range in a
+ * coarse level, or at least do it word by word. */
+ for (i = sector; i < nb_sectors; i += gran) {
+ if (hbitmap_get(bitmap->meta, i)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap, int64_t sector,
+ int nb_sectors)
+{
+ hbitmap_reset(bitmap->meta, sector, nb_sectors);
+}
+
bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
{
return bitmap->successor;
@@ -3222,7 +3266,7 @@ int bdrv_dirty_bitmap_create_successor(BlockDriverState
*bs,
/* Create an anonymous successor */
granularity = bdrv_dirty_bitmap_granularity(bitmap);
- child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
+ child = bdrv_create_dirty_bitmap(bs, granularity, NULL, false, errp);
if (!child) {
return -1;
}
diff --git a/block/mirror.c b/block/mirror.c
index 0e8f556..e381b9d 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -743,7 +743,8 @@ static void mirror_start_job(BlockDriverState *bs,
BlockDriverState *target,
s->buf_size = ROUND_UP(buf_size, granularity);
s->unmap = unmap;
- s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
+ s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, false,
+ errp);
if (!s->dirty_bitmap) {
g_free(s->replaces);
block_job_unref(&s->common);
diff --git a/blockdev.c b/blockdev.c
index 313841b..2507d96 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2671,7 +2671,8 @@ void qmp_block_dirty_bitmap_add(const char *node, const
char *name,
granularity = bdrv_get_default_bitmap_granularity(bs);
}
- bdrv_create_dirty_bitmap(bs, granularity, name, errp);
+ bdrv_create_dirty_bitmap(bs, granularity, name, false,
+ errp);
out:
aio_context_release(aio_context);
diff --git a/include/block/block.h b/include/block/block.h
index 3477328..e749461 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -475,7 +475,12 @@ typedef struct BdrvDirtyBitmap BdrvDirtyBitmap;
BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
uint32_t granularity,
const char *name,
+ bool create_meta,
Error **errp);
+void bdrv_create_meta_dirty_bitmap(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap);
+void bdrv_release_meta_dirty_bitmap(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap);
int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
BdrvDirtyBitmap *bitmap,
Error **errp);
@@ -504,6 +509,12 @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
int64_t cur_sector, int nr_sectors);
void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi);
void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset);
+int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap, int64_t sector,
+ int nb_sectors);
+void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap, int64_t sector,
+ int nb_sectors);
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
void bdrv_enable_copy_on_read(BlockDriverState *bs);
diff --git a/migration/block.c b/migration/block.c
index 656f38f..43b64a5 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -322,7 +322,7 @@ static int set_dirty_tracking(void)
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
bmds->dirty_bitmap = bdrv_create_dirty_bitmap(bmds->bs, BLOCK_SIZE,
- NULL, NULL);
+ NULL, false, NULL);
if (!bmds->dirty_bitmap) {
ret = -errno;
goto fail;
--
2.4.3