aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/backup.c18
-rw-r--r--block/commit.c4
-rw-r--r--block/mirror.c5
-rw-r--r--block/stream.c4
-rw-r--r--blockjob.c9
-rw-r--r--include/block/blockjob_int.h8
6 files changed, 29 insertions, 19 deletions
diff --git a/block/backup.c b/block/backup.c
index 8468fd9f94..cfdb6ecdf5 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -325,21 +325,17 @@ static void backup_complete(BlockJob *job, void *opaque)
static bool coroutine_fn yield_and_check(BackupBlockJob *job)
{
+ uint64_t delay_ns;
+
if (block_job_is_cancelled(&job->common)) {
return true;
}
- /* we need to yield so that bdrv_drain_all() returns.
- * (without, VM does not reboot)
- */
- if (job->common.speed) {
- uint64_t delay_ns = ratelimit_calculate_delay(&job->common.limit,
- job->bytes_read);
- job->bytes_read = 0;
- block_job_sleep_ns(&job->common, delay_ns);
- } else {
- block_job_sleep_ns(&job->common, 0);
- }
+ /* We need to yield even for delay_ns = 0 so that bdrv_drain_all() can
+ * return. Without a yield, the VM would not reboot. */
+ delay_ns = block_job_ratelimit_get_delay(&job->common, job->bytes_read);
+ job->bytes_read = 0;
+ block_job_sleep_ns(&job->common, delay_ns);
if (block_job_is_cancelled(&job->common)) {
return true;
diff --git a/block/commit.c b/block/commit.c
index 46cbeaec3e..ba5df6aa0a 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -197,8 +197,8 @@ static void coroutine_fn commit_run(void *opaque)
/* Publish progress */
block_job_progress_update(&s->common, n);
- if (copy && s->common.speed) {
- delay_ns = ratelimit_calculate_delay(&s->common.limit, n);
+ if (copy) {
+ delay_ns = block_job_ratelimit_get_delay(&s->common, n);
} else {
delay_ns = 0;
}
diff --git a/block/mirror.c b/block/mirror.c
index 6955d68804..6aa38db114 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -447,10 +447,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
assert(io_bytes);
offset += io_bytes;
nb_chunks -= DIV_ROUND_UP(io_bytes, s->granularity);
- if (s->common.speed) {
- delay_ns = ratelimit_calculate_delay(&s->common.limit,
- io_bytes_acct);
- }
+ delay_ns = block_job_ratelimit_get_delay(&s->common, io_bytes_acct);
}
return delay_ns;
}
diff --git a/block/stream.c b/block/stream.c
index 797d7c4f21..df9660d2fc 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -185,8 +185,8 @@ static void coroutine_fn stream_run(void *opaque)
/* Publish progress */
block_job_progress_update(&s->common, n);
- if (copy && s->common.speed) {
- delay_ns = ratelimit_calculate_delay(&s->common.limit, n);
+ if (copy) {
+ delay_ns = block_job_ratelimit_get_delay(&s->common, n);
} else {
delay_ns = 0;
}
diff --git a/blockjob.c b/blockjob.c
index 2f4b768338..04416f11cd 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -680,6 +680,15 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
block_job_enter_cond(job, block_job_timer_pending);
}
+int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n)
+{
+ if (!job->speed) {
+ return 0;
+ }
+
+ return ratelimit_calculate_delay(&job->limit, n);
+}
+
void block_job_complete(BlockJob *job, Error **errp)
{
/* Should not be reachable via external interface for internal jobs */
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index ad510d5a0c..62ec964d09 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -166,6 +166,14 @@ void block_job_sleep_ns(BlockJob *job, int64_t ns);
void block_job_yield(BlockJob *job);
/**
+ * block_job_ratelimit_get_delay:
+ *
+ * Calculate and return delay for the next request in ns. See the documentation
+ * of ratelimit_calculate_delay() for details.
+ */
+int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n);
+
+/**
* block_job_early_fail:
* @bs: The block device.
*