qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-block] [PATCH RFC for-2.6 3/3] block: Support meta dirty bitmap


From: Fam Zheng
Subject: [Qemu-block] [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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]