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

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