yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

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

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