|
|
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 |
|