Blame SOURCES/kvm-blockjob-Wrappers-for-progress-counter-access.patch

383d26
From c8cf3cfff0a6fd9e059190a97d38b0d1a3223e8e Mon Sep 17 00:00:00 2001
383d26
From: Kevin Wolf <kwolf@redhat.com>
383d26
Date: Tue, 26 Jun 2018 09:47:52 +0200
383d26
Subject: [PATCH 23/89] blockjob: Wrappers for progress counter access
383d26
383d26
RH-Author: Kevin Wolf <kwolf@redhat.com>
383d26
Message-id: <20180626094856.6924-10-kwolf@redhat.com>
383d26
Patchwork-id: 81078
383d26
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH v2 09/73] blockjob: Wrappers for progress counter access
383d26
Bugzilla: 1513543
383d26
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
383d26
RH-Acked-by: Max Reitz <mreitz@redhat.com>
383d26
RH-Acked-by: Fam Zheng <famz@redhat.com>
383d26
383d26
Block job drivers are not expected to mess with the internals of the
383d26
BlockJob object, so provide wrapper functions for one of the cases where
383d26
they still do it: Updating the progress counter.
383d26
383d26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
383d26
Reviewed-by: Eric Blake <eblake@redhat.com>
383d26
Reviewed-by: Max Reitz <mreitz@redhat.com>
383d26
Reviewed-by: John Snow <jsnow@redhat.com>
383d26
(cherry picked from commit 05df8a6a2b4e36e8d69de2130e616d5ac28e8837)
383d26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
383d26
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
---
383d26
 block/backup.c           | 22 +++++++++++++---------
383d26
 block/commit.c           | 16 ++++++++--------
383d26
 block/mirror.c           | 11 +++++------
383d26
 block/stream.c           | 14 ++++++++------
383d26
 blockjob.c               | 10 ++++++++++
383d26
 include/block/blockjob.h | 19 +++++++++++++++++++
383d26
 6 files changed, 63 insertions(+), 29 deletions(-)
383d26
383d26
diff --git a/block/backup.c b/block/backup.c
383d26
index 453cd62..5d95805 100644
383d26
--- a/block/backup.c
383d26
+++ b/block/backup.c
383d26
@@ -39,6 +39,7 @@ typedef struct BackupBlockJob {
383d26
     BlockdevOnError on_source_error;
383d26
     BlockdevOnError on_target_error;
383d26
     CoRwlock flush_rwlock;
383d26
+    uint64_t len;
383d26
     uint64_t bytes_read;
383d26
     int64_t cluster_size;
383d26
     bool compress;
383d26
@@ -118,7 +119,7 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
383d26
 
383d26
         trace_backup_do_cow_process(job, start);
383d26
 
383d26
-        n = MIN(job->cluster_size, job->common.len - start);
383d26
+        n = MIN(job->cluster_size, job->len - start);
383d26
 
383d26
         if (!bounce_buffer) {
383d26
             bounce_buffer = blk_blockalign(blk, job->cluster_size);
383d26
@@ -159,7 +160,7 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
383d26
          * offset field is an opaque progress value, it is not a disk offset.
383d26
          */
383d26
         job->bytes_read += n;
383d26
-        job->common.offset += n;
383d26
+        block_job_progress_update(&job->common, n);
383d26
     }
383d26
 
383d26
 out:
383d26
@@ -261,7 +262,7 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
383d26
         return;
383d26
     }
383d26
 
383d26
-    len = DIV_ROUND_UP(backup_job->common.len, backup_job->cluster_size);
383d26
+    len = DIV_ROUND_UP(backup_job->len, backup_job->cluster_size);
383d26
     hbitmap_set(backup_job->copy_bitmap, 0, len);
383d26
 }
383d26
 
383d26
@@ -420,8 +421,9 @@ static void backup_incremental_init_copy_bitmap(BackupBlockJob *job)
383d26
         bdrv_set_dirty_iter(dbi, next_cluster * job->cluster_size);
383d26
     }
383d26
 
383d26
-    job->common.offset = job->common.len -
383d26
-                         hbitmap_count(job->copy_bitmap) * job->cluster_size;
383d26
+    /* TODO block_job_progress_set_remaining() would make more sense */
383d26
+    block_job_progress_update(&job->common,
383d26
+        job->len - hbitmap_count(job->copy_bitmap) * job->cluster_size);
383d26
 
383d26
     bdrv_dirty_iter_free(dbi);
383d26
 }
383d26
@@ -437,7 +439,9 @@ static void coroutine_fn backup_run(void *opaque)
383d26
     QLIST_INIT(&job->inflight_reqs);
383d26
     qemu_co_rwlock_init(&job->flush_rwlock);
383d26
 
383d26
-    nb_clusters = DIV_ROUND_UP(job->common.len, job->cluster_size);
383d26
+    nb_clusters = DIV_ROUND_UP(job->len, job->cluster_size);
383d26
+    block_job_progress_set_remaining(&job->common, job->len);
383d26
+
383d26
     job->copy_bitmap = hbitmap_alloc(nb_clusters, 0);
383d26
     if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
383d26
         backup_incremental_init_copy_bitmap(job);
383d26
@@ -461,7 +465,7 @@ static void coroutine_fn backup_run(void *opaque)
383d26
         ret = backup_run_incremental(job);
383d26
     } else {
383d26
         /* Both FULL and TOP SYNC_MODE's require copying.. */
383d26
-        for (offset = 0; offset < job->common.len;
383d26
+        for (offset = 0; offset < job->len;
383d26
              offset += job->cluster_size) {
383d26
             bool error_is_read;
383d26
             int alloced = 0;
383d26
@@ -620,7 +624,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
383d26
         goto error;
383d26
     }
383d26
 
383d26
-    /* job->common.len is fixed, so we can't allow resize */
383d26
+    /* job->len is fixed, so we can't allow resize */
383d26
     job = block_job_create(job_id, &backup_job_driver, txn, bs,
383d26
                            BLK_PERM_CONSISTENT_READ,
383d26
                            BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
383d26
@@ -676,7 +680,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
383d26
     /* Required permissions are already taken with target's blk_new() */
383d26
     block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
383d26
                        &error_abort);
383d26
-    job->common.len = len;
383d26
+    job->len = len;
383d26
 
383d26
     return &job->common;
383d26
 
383d26
diff --git a/block/commit.c b/block/commit.c
383d26
index 1432bae..50b191c 100644
383d26
--- a/block/commit.c
383d26
+++ b/block/commit.c
383d26
@@ -146,21 +146,21 @@ static void coroutine_fn commit_run(void *opaque)
383d26
     int64_t n = 0; /* bytes */
383d26
     void *buf = NULL;
383d26
     int bytes_written = 0;
383d26
-    int64_t base_len;
383d26
+    int64_t len, base_len;
383d26
 
383d26
-    ret = s->common.len = blk_getlength(s->top);
383d26
-
383d26
-    if (s->common.len < 0) {
383d26
+    ret = len = blk_getlength(s->top);
383d26
+    if (len < 0) {
383d26
         goto out;
383d26
     }
383d26
+    block_job_progress_set_remaining(&s->common, len);
383d26
 
383d26
     ret = base_len = blk_getlength(s->base);
383d26
     if (base_len < 0) {
383d26
         goto out;
383d26
     }
383d26
 
383d26
-    if (base_len < s->common.len) {
383d26
-        ret = blk_truncate(s->base, s->common.len, PREALLOC_MODE_OFF, NULL);
383d26
+    if (base_len < len) {
383d26
+        ret = blk_truncate(s->base, len, PREALLOC_MODE_OFF, NULL);
383d26
         if (ret) {
383d26
             goto out;
383d26
         }
383d26
@@ -168,7 +168,7 @@ static void coroutine_fn commit_run(void *opaque)
383d26
 
383d26
     buf = blk_blockalign(s->top, COMMIT_BUFFER_SIZE);
383d26
 
383d26
-    for (offset = 0; offset < s->common.len; offset += n) {
383d26
+    for (offset = 0; offset < len; offset += n) {
383d26
         bool copy;
383d26
 
383d26
         /* Note that even when no rate limit is applied we need to yield
383d26
@@ -198,7 +198,7 @@ static void coroutine_fn commit_run(void *opaque)
383d26
             }
383d26
         }
383d26
         /* Publish progress */
383d26
-        s->common.offset += n;
383d26
+        block_job_progress_update(&s->common, n);
383d26
 
383d26
         if (copy && s->common.speed) {
383d26
             delay_ns = ratelimit_calculate_delay(&s->limit, n);
383d26
diff --git a/block/mirror.c b/block/mirror.c
383d26
index 003f957..ed711b5 100644
383d26
--- a/block/mirror.c
383d26
+++ b/block/mirror.c
383d26
@@ -121,7 +121,7 @@ static void mirror_iteration_done(MirrorOp *op, int ret)
383d26
             bitmap_set(s->cow_bitmap, chunk_num, nb_chunks);
383d26
         }
383d26
         if (!s->initial_zeroing_ongoing) {
383d26
-            s->common.offset += op->bytes;
383d26
+            block_job_progress_update(&s->common, op->bytes);
383d26
         }
383d26
     }
383d26
     qemu_iovec_destroy(&op->qiov);
383d26
@@ -792,11 +792,10 @@ static void coroutine_fn mirror_run(void *opaque)
383d26
         block_job_pause_point(&s->common);
383d26
 
383d26
         cnt = bdrv_get_dirty_count(s->dirty_bitmap);
383d26
-        /* s->common.offset contains the number of bytes already processed so
383d26
-         * far, cnt is the number of dirty bytes remaining and
383d26
-         * s->bytes_in_flight is the number of bytes currently being
383d26
-         * processed; together those are the current total operation length */
383d26
-        s->common.len = s->common.offset + s->bytes_in_flight + cnt;
383d26
+        /* cnt is the number of dirty bytes remaining and s->bytes_in_flight is
383d26
+         * the number of bytes currently being processed; together those are
383d26
+         * the current remaining operation length */
383d26
+        block_job_progress_set_remaining(&s->common, s->bytes_in_flight + cnt);
383d26
 
383d26
         /* Note that even when no rate limit is applied we need to yield
383d26
          * periodically with no pending I/O so that bdrv_drain_all() returns.
383d26
diff --git a/block/stream.c b/block/stream.c
383d26
index 1a85708..8369852 100644
383d26
--- a/block/stream.c
383d26
+++ b/block/stream.c
383d26
@@ -107,6 +107,7 @@ static void coroutine_fn stream_run(void *opaque)
383d26
     BlockBackend *blk = s->common.blk;
383d26
     BlockDriverState *bs = blk_bs(blk);
383d26
     BlockDriverState *base = s->base;
383d26
+    int64_t len;
383d26
     int64_t offset = 0;
383d26
     uint64_t delay_ns = 0;
383d26
     int error = 0;
383d26
@@ -118,11 +119,12 @@ static void coroutine_fn stream_run(void *opaque)
383d26
         goto out;
383d26
     }
383d26
 
383d26
-    s->common.len = bdrv_getlength(bs);
383d26
-    if (s->common.len < 0) {
383d26
-        ret = s->common.len;
383d26
+    len = bdrv_getlength(bs);
383d26
+    if (len < 0) {
383d26
+        ret = len;
383d26
         goto out;
383d26
     }
383d26
+    block_job_progress_set_remaining(&s->common, len);
383d26
 
383d26
     buf = qemu_blockalign(bs, STREAM_BUFFER_SIZE);
383d26
 
383d26
@@ -135,7 +137,7 @@ static void coroutine_fn stream_run(void *opaque)
383d26
         bdrv_enable_copy_on_read(bs);
383d26
     }
383d26
 
383d26
-    for ( ; offset < s->common.len; offset += n) {
383d26
+    for ( ; offset < len; offset += n) {
383d26
         bool copy;
383d26
 
383d26
         /* Note that even when no rate limit is applied we need to yield
383d26
@@ -159,7 +161,7 @@ static void coroutine_fn stream_run(void *opaque)
383d26
 
383d26
             /* Finish early if end of backing file has been reached */
383d26
             if (ret == 0 && n == 0) {
383d26
-                n = s->common.len - offset;
383d26
+                n = len - offset;
383d26
             }
383d26
 
383d26
             copy = (ret == 1);
383d26
@@ -185,7 +187,7 @@ static void coroutine_fn stream_run(void *opaque)
383d26
         ret = 0;
383d26
 
383d26
         /* Publish progress */
383d26
-        s->common.offset += n;
383d26
+        block_job_progress_update(&s->common, n);
383d26
         if (copy && s->common.speed) {
383d26
             delay_ns = ratelimit_calculate_delay(&s->limit, n);
383d26
         } else {
383d26
diff --git a/blockjob.c b/blockjob.c
383d26
index 0033b96..d0a2ac5 100644
383d26
--- a/blockjob.c
383d26
+++ b/blockjob.c
383d26
@@ -818,6 +818,16 @@ int block_job_complete_sync(BlockJob *job, Error **errp)
383d26
     return block_job_finish_sync(job, &block_job_complete, errp);
383d26
 }
383d26
 
383d26
+void block_job_progress_update(BlockJob *job, uint64_t done)
383d26
+{
383d26
+    job->offset += done;
383d26
+}
383d26
+
383d26
+void block_job_progress_set_remaining(BlockJob *job, uint64_t remaining)
383d26
+{
383d26
+    job->len = job->offset + remaining;
383d26
+}
383d26
+
383d26
 BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
383d26
 {
383d26
     BlockJobInfo *info;
383d26
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
383d26
index fc645da..a2cc522 100644
383d26
--- a/include/block/blockjob.h
383d26
+++ b/include/block/blockjob.h
383d26
@@ -278,6 +278,25 @@ void block_job_finalize(BlockJob *job, Error **errp);
383d26
 void block_job_dismiss(BlockJob **job, Error **errp);
383d26
 
383d26
 /**
383d26
+ * block_job_progress_update:
383d26
+ * @job: The job that has made progress
383d26
+ * @done: How much progress the job made
383d26
+ *
383d26
+ * Updates the progress counter of the job.
383d26
+ */
383d26
+void block_job_progress_update(BlockJob *job, uint64_t done);
383d26
+
383d26
+/**
383d26
+ * block_job_progress_set_remaining:
383d26
+ * @job: The job whose expected progress end value is set
383d26
+ * @remaining: Expected end value of the progress counter of the job
383d26
+ *
383d26
+ * Sets the expected end value of the progress counter of a job so that a
383d26
+ * completion percentage can be calculated when the progress is updated.
383d26
+ */
383d26
+void block_job_progress_set_remaining(BlockJob *job, uint64_t remaining);
383d26
+
383d26
+/**
383d26
  * block_job_query:
383d26
  * @job: The job to get information about.
383d26
  *
383d26
-- 
383d26
1.8.3.1
383d26