block_job_remove_all_bdrv(bjob);
blk_unref(bjob->blk);
+ ratelimit_destroy(&bjob->limit);
error_free(bjob->blocker);
}
job->job.aio_context = ctx;
}
+static AioContext *child_job_get_parent_aio_context(BdrvChild *c)
+{
+ BlockJob *job = c->opaque;
+
+ return job->job.aio_context;
+}
+
static const BdrvChildClass child_job = {
.get_parent_desc = child_job_get_parent_desc,
.drained_begin = child_job_drained_begin,
.can_set_aio_ctx = child_job_can_set_aio_ctx,
.set_aio_ctx = child_job_set_aio_ctx,
.stay_at_node = true,
+ .get_parent_aio_context = child_job_get_parent_aio_context,
};
void block_job_remove_all_bdrv(BlockJob *job)
if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
aio_context_release(job->job.aio_context);
}
- c = bdrv_root_attach_child(bs, name, &child_job, 0,
- job->job.aio_context, perm, shared_perm, job,
+ c = bdrv_root_attach_child(bs, name, &child_job, 0, perm, shared_perm, job,
errp);
if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
aio_context_acquire(job->job.aio_context);
int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n)
{
- if (!job->speed) {
- return 0;
- }
-
return ratelimit_calculate_delay(&job->limit, n);
}
BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
{
BlockJobInfo *info;
+ uint64_t progress_current, progress_total;
if (block_job_is_internal(job)) {
error_setg(errp, "Cannot query QEMU internal jobs");
return NULL;
}
+
+ progress_get_snapshot(&job->job.progress, &progress_current,
+ &progress_total);
+
info = g_new0(BlockJobInfo, 1);
info->type = g_strdup(job_type_str(&job->job));
info->device = g_strdup(job->job.id);
info->busy = qatomic_read(&job->job.busy);
info->paused = job->job.pause_count > 0;
- info->offset = job->job.progress.current;
- info->len = job->job.progress.total;
+ info->offset = progress_current;
+ info->len = progress_total;
info->speed = job->speed;
info->io_status = job->iostatus;
info->ready = job_is_ready(&job->job),
static void block_job_event_cancelled(Notifier *n, void *opaque)
{
BlockJob *job = opaque;
+ uint64_t progress_current, progress_total;
if (block_job_is_internal(job)) {
return;
}
+ progress_get_snapshot(&job->job.progress, &progress_current,
+ &progress_total);
+
qapi_event_send_block_job_cancelled(job_type(&job->job),
job->job.id,
- job->job.progress.total,
- job->job.progress.current,
+ progress_total,
+ progress_current,
job->speed);
}
{
BlockJob *job = opaque;
const char *msg = NULL;
+ uint64_t progress_current, progress_total;
if (block_job_is_internal(job)) {
return;
msg = error_get_pretty(job->job.err);
}
+ progress_get_snapshot(&job->job.progress, &progress_current,
+ &progress_total);
+
qapi_event_send_block_job_completed(job_type(&job->job),
job->job.id,
- job->job.progress.total,
- job->job.progress.current,
+ progress_total,
+ progress_current,
job->speed,
!!msg,
msg);
static void block_job_event_ready(Notifier *n, void *opaque)
{
BlockJob *job = opaque;
+ uint64_t progress_current, progress_total;
if (block_job_is_internal(job)) {
return;
}
+ progress_get_snapshot(&job->job.progress, &progress_current,
+ &progress_total);
+
qapi_event_send_block_job_ready(job_type(&job->job),
job->job.id,
- job->job.progress.total,
- job->job.progress.current,
+ progress_total,
+ progress_current,
job->speed);
}
assert(job->job.driver->free == &block_job_free);
assert(job->job.driver->user_resume == &block_job_user_resume);
+ ratelimit_init(&job->limit);
+
job->blk = blk;
job->finalize_cancelled_notifier.notify = block_job_event_cancelled;
blk_set_disable_request_queuing(blk, true);
blk_set_allow_aio_context_change(blk, true);
- /* Only set speed when necessary to avoid NotSupported error */
- if (speed != 0) {
- if (!block_job_set_speed(job, speed, errp)) {
- job_early_fail(&job->job);
- return NULL;
- }
+ if (!block_job_set_speed(job, speed, errp)) {
+ job_early_fail(&job->job);
+ return NULL;
}
return job;