qemu-block
[Top][All Lists]
Advanced

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

[Qemu-block] [PATCH 9/9] mirror: replace bdrv_dirty_bitmap with plain hb


From: Denis V. Lunev
Subject: [Qemu-block] [PATCH 9/9] mirror: replace bdrv_dirty_bitmap with plain hbitmap
Date: Tue, 14 Jun 2016 18:25:16 +0300

We have replaced the mechanics of syncing new writes in the previous patch
and thus do not need to track dirty changes anymore.

Signed-off-by: Denis V. Lunev <address@hidden>
Reviewed-by: Vladimir Sementsov-Ogievskiy<address@hidden>
CC: Stefan Hajnoczi <address@hidden>
CC: Fam Zheng <address@hidden>
CC: Kevin Wolf <address@hidden>
CC: Max Reitz <address@hidden>
CC: Jeff Cody <address@hidden>
CC: Eric Blake <address@hidden>
---
 block/mirror.c | 58 ++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 38 insertions(+), 20 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index 086256c..926fd13 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -52,7 +52,7 @@ typedef struct MirrorBlockJob {
     size_t buf_size;
     int64_t bdev_length;
     unsigned long *cow_bitmap;
-    BdrvDirtyBitmap *dirty_bitmap;
+    HBitmap *copy_bitmap;
     HBitmapIter hbi;
     uint8_t *buf;
     QSIMPLEQ_HEAD(, MirrorBuffer) buf_free;
@@ -141,7 +141,7 @@ static void mirror_write_complete(void *opaque, int ret)
     if (ret < 0) {
         BlockErrorAction action;
 
-        bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
+        hbitmap_set(s->copy_bitmap, op->sector_num, op->nb_sectors);
         action = mirror_error_action(s, false, -ret);
         if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
             s->ret = ret;
@@ -157,7 +157,7 @@ static void mirror_read_complete(void *opaque, int ret)
     if (ret < 0) {
         BlockErrorAction action;
 
-        bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
+        hbitmap_set(s->copy_bitmap, op->sector_num, op->nb_sectors);
         action = mirror_error_action(s, true, -ret);
         if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
             s->ret = ret;
@@ -328,9 +328,9 @@ static uint64_t coroutine_fn 
mirror_iteration(MirrorBlockJob *s)
 
     sector_num = hbitmap_iter_next(&s->hbi);
     if (sector_num < 0) {
-        bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
+        hbitmap_iter_init(&s->hbi, s->copy_bitmap, 0);
         sector_num = hbitmap_iter_next(&s->hbi);
-        trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap));
+        trace_mirror_restart_iter(s, hbitmap_count(s->copy_bitmap));
         assert(sector_num >= 0);
     }
 
@@ -347,7 +347,7 @@ static uint64_t coroutine_fn 
mirror_iteration(MirrorBlockJob *s)
         int64_t next_sector = sector_num + nb_chunks * sectors_per_chunk;
         int64_t next_chunk = next_sector / sectors_per_chunk;
         if (next_sector >= end ||
-            !bdrv_get_dirty(source, s->dirty_bitmap, next_sector)) {
+            !hbitmap_get(s->copy_bitmap, next_sector)) {
             break;
         }
         if (test_bit(next_chunk, s->in_flight_bitmap)) {
@@ -357,7 +357,7 @@ static uint64_t coroutine_fn 
mirror_iteration(MirrorBlockJob *s)
         hbitmap_next = hbitmap_iter_next(&s->hbi);
         if (hbitmap_next > next_sector || hbitmap_next < 0) {
             /* The bitmap iterator's cache is stale, refresh it */
-            bdrv_set_dirty_iter(&s->hbi, next_sector);
+            hbitmap_iter_init(&s->hbi, s->copy_bitmap, next_sector);
             hbitmap_next = hbitmap_iter_next(&s->hbi);
         }
         assert(hbitmap_next == next_sector);
@@ -368,8 +368,7 @@ static uint64_t coroutine_fn 
mirror_iteration(MirrorBlockJob *s)
      * calling bdrv_get_block_status_above could yield - if some blocks are
      * marked dirty in this window, we need to know.
      */
-    bdrv_reset_dirty_bitmap(s->dirty_bitmap, sector_num,
-                            nb_chunks * sectors_per_chunk);
+    hbitmap_reset(s->copy_bitmap, sector_num, nb_chunks * sectors_per_chunk);
     bitmap_set(s->in_flight_bitmap, sector_num / sectors_per_chunk, nb_chunks);
     while (nb_chunks > 0 && sector_num < end) {
         int ret;
@@ -553,8 +552,8 @@ static int coroutine_fn mirror_before_write_notify(
     aligned_start = QEMU_ALIGN_UP(sector_num, sectors_per_chunk);
     aligned_end = QEMU_ALIGN_DOWN(sector_num + nb_sectors, sectors_per_chunk);
     if (aligned_end > aligned_start) {
-        bdrv_reset_dirty_bitmap(s->dirty_bitmap, aligned_start,
-                                aligned_end - aligned_start);
+        hbitmap_reset(s->copy_bitmap, aligned_start,
+                      aligned_end - aligned_start);
     }
 
     if (req->type == BDRV_TRACKED_DISCARD) {
@@ -596,7 +595,7 @@ static int mirror_dirty_init(MirrorBlockJob *s)
 
     if (base == NULL && !bdrv_has_zero_init(target_bs) &&
             target_bs->drv->bdrv_co_write_zeroes == NULL) {
-        bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, end);
+        hbitmap_set(s->copy_bitmap, 0, end);
         return 0;
     }
 
@@ -625,7 +624,7 @@ static int mirror_dirty_init(MirrorBlockJob *s)
 
         assert(n > 0);
         if (ret == 1) {
-            bdrv_set_dirty_bitmap(s->dirty_bitmap, sector_num, n);
+            hbitmap_set(s->copy_bitmap, sector_num, n);
         }
         sector_num += n;
     }
@@ -729,7 +728,7 @@ static void coroutine_fn mirror_run(void *opaque)
     }
 
     last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-    bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi);
+    hbitmap_iter_init(&s->hbi, s->copy_bitmap, 0);
     for (;;) {
         uint64_t delay_ns = 0;
         int64_t cnt;
@@ -740,7 +739,7 @@ static void coroutine_fn mirror_run(void *opaque)
             goto immediate_exit;
         }
 
-        cnt = bdrv_get_dirty_count(s->dirty_bitmap);
+        cnt = hbitmap_count(s->copy_bitmap);
         /* s->common.offset contains the number of bytes already processed so
          * far, cnt is the number of dirty sectors remaining and
          * s->sectors_in_flight is the number of sectors currently being
@@ -787,7 +786,7 @@ static void coroutine_fn mirror_run(void *opaque)
 
                 should_complete = s->should_complete ||
                     block_job_is_cancelled(&s->common);
-                cnt = bdrv_get_dirty_count(s->dirty_bitmap);
+                cnt = hbitmap_count(s->copy_bitmap);
             }
         }
 
@@ -802,7 +801,7 @@ static void coroutine_fn mirror_run(void *opaque)
              */
             trace_mirror_before_drain(s, cnt);
             bdrv_co_drain(bs);
-            cnt = bdrv_get_dirty_count(s->dirty_bitmap);
+            cnt = hbitmap_count(s->copy_bitmap);
         }
 
         ret = 0;
@@ -842,7 +841,7 @@ immediate_exit:
     qemu_vfree(s->buf);
     g_free(s->cow_bitmap);
     g_free(s->in_flight_bitmap);
-    bdrv_release_dirty_bitmap(bs, s->dirty_bitmap);
+    hbitmap_free(s->copy_bitmap);
 
     data = g_malloc(sizeof(*data));
     data->ret = ret;
@@ -925,6 +924,25 @@ static const BlockJobDriver commit_active_job_driver = {
     .complete      = mirror_complete,
 };
 
+static HBitmap *mirror_create_bitmap(BlockDriverState *bs,
+                                     uint32_t granularity, Error **errp)
+{
+    int64_t bitmap_size;
+    uint32_t sector_granularity;
+
+    assert((granularity & (granularity - 1)) == 0);
+
+    sector_granularity = granularity >> BDRV_SECTOR_BITS;
+    assert(sector_granularity);
+    bitmap_size = bdrv_nb_sectors(bs);
+    if (bitmap_size < 0) {
+        error_setg_errno(errp, -bitmap_size, "could not get length of device");
+        errno = -bitmap_size;
+        return NULL;
+    }
+    return hbitmap_alloc(bitmap_size, ctz32(sector_granularity));
+}
+
 static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
                              const char *replaces,
                              int64_t speed, uint32_t granularity,
@@ -971,8 +989,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);
-    if (!s->dirty_bitmap) {
+    s->copy_bitmap = mirror_create_bitmap(bs, granularity, errp);
+    if (s->copy_bitmap == NULL) {
         g_free(s->replaces);
         blk_unref(s->target);
         block_job_unref(&s->common);
-- 
2.5.0




reply via email to

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