diff options
Diffstat (limited to 'blockjob.c')
| -rw-r--r-- | blockjob.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/blockjob.c b/blockjob.c index dfffad921a..36c5fdeb2f 100644 --- a/blockjob.c +++ b/blockjob.c @@ -359,6 +359,11 @@ static bool block_job_started(BlockJob *job) return job->co; } +const BlockJobDriver *block_job_driver(BlockJob *job) +{ + return job->driver; +} + /** * All jobs must allow a pause point before entering their job proper. This * ensures that jobs can be paused prior to being started, then resumed later. @@ -659,22 +664,18 @@ static bool block_job_timer_pending(BlockJob *job) void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp) { - Error *local_err = NULL; int64_t old_speed = job->speed; - if (!job->driver->set_speed) { - error_setg(errp, QERR_UNSUPPORTED); - return; - } if (block_job_apply_verb(job, BLOCK_JOB_VERB_SET_SPEED, errp)) { return; } - job->driver->set_speed(job, speed, &local_err); - if (local_err) { - error_propagate(errp, local_err); + if (speed < 0) { + error_setg(errp, QERR_INVALID_PARAMETER, "speed"); return; } + ratelimit_set_speed(&job->limit, speed, BLOCK_JOB_SLICE_TIME); + job->speed = speed; if (speed && speed <= old_speed) { return; @@ -684,6 +685,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 */ @@ -702,7 +712,7 @@ void block_job_complete(BlockJob *job, Error **errp) void block_job_finalize(BlockJob *job, Error **errp) { - assert(job && job->id && job->txn); + assert(job && job->id); if (block_job_apply_verb(job, BLOCK_JOB_VERB_FINALIZE, errp)) { return; } @@ -810,6 +820,16 @@ int block_job_complete_sync(BlockJob *job, Error **errp) return block_job_finish_sync(job, &block_job_complete, errp); } +void block_job_progress_update(BlockJob *job, uint64_t done) +{ + job->offset += done; +} + +void block_job_progress_set_remaining(BlockJob *job, uint64_t remaining) +{ + job->len = job->offset + remaining; +} + BlockJobInfo *block_job_query(BlockJob *job, Error **errp) { BlockJobInfo *info; @@ -831,6 +851,8 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp) info->status = job->status; info->auto_finalize = job->auto_finalize; info->auto_dismiss = job->auto_dismiss; + info->has_error = job->ret != 0; + info->error = job->ret ? g_strdup(strerror(-job->ret)) : NULL; return info; } |