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

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