* one to make sure that such a concurrent access does not attempt
* to process an already freed BdrvChild.
*/
- aio_context_release(job->job.aio_context);
- bdrv_graph_wrlock(NULL);
- aio_context_acquire(job->job.aio_context);
+ bdrv_graph_wrlock();
while (job->nodes) {
GSList *l = job->nodes;
BdrvChild *c = l->data;
uint64_t perm, uint64_t shared_perm, Error **errp)
{
BdrvChild *c;
- AioContext *ctx = bdrv_get_aio_context(bs);
- bool need_context_ops;
GLOBAL_STATE_CODE();
bdrv_ref(bs);
- need_context_ops = ctx != job->job.aio_context;
-
- if (need_context_ops) {
- if (job->job.aio_context != qemu_get_aio_context()) {
- aio_context_release(job->job.aio_context);
- }
- aio_context_acquire(ctx);
- }
c = bdrv_root_attach_child(bs, name, &child_job, 0, perm, shared_perm, job,
errp);
- if (need_context_ops) {
- aio_context_release(ctx);
- if (job->job.aio_context != qemu_get_aio_context()) {
- aio_context_acquire(job->job.aio_context);
- }
- }
if (c == NULL) {
return -EPERM;
}
return block_job_set_speed_locked(job, speed, errp);
}
+void block_job_change_locked(BlockJob *job, BlockJobChangeOptions *opts,
+ Error **errp)
+{
+ const BlockJobDriver *drv = block_job_driver(job);
+
+ GLOBAL_STATE_CODE();
+
+ if (job_apply_verb_locked(&job->job, JOB_VERB_CHANGE, errp)) {
+ return;
+ }
+
+ if (drv->change) {
+ job_unlock();
+ drv->change(job, opts, errp);
+ job_lock();
+ } else {
+ error_setg(errp, "Job type does not support change");
+ }
+}
+
void block_job_ratelimit_processed_bytes(BlockJob *job, uint64_t n)
{
IO_CODE();
{
BlockJobInfo *info;
uint64_t progress_current, progress_total;
+ const BlockJobDriver *drv = block_job_driver(job);
GLOBAL_STATE_CODE();
&progress_total);
info = g_new0(BlockJobInfo, 1);
- info->type = g_strdup(job_type_str(&job->job));
+ info->type = job_type(&job->job);
info->device = g_strdup(job->job.id);
info->busy = job->job.busy;
info->paused = job->job.pause_count > 0;
g_strdup(error_get_pretty(job->job.err)) :
g_strdup(strerror(-job->job.ret));
}
+ if (drv->query) {
+ job_unlock();
+ drv->query(job, info);
+ job_lock();
+ }
return info;
}
BlockJob *job;
int ret;
GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ bdrv_graph_wrlock();
if (job_id == NULL && !(flags & JOB_INTERNAL)) {
job_id = bdrv_get_device_name(bs);
job = job_create(job_id, &driver->job_driver, txn, bdrv_get_aio_context(bs),
flags, cb, opaque, errp);
if (job == NULL) {
+ bdrv_graph_wrunlock();
return NULL;
}
goto fail;
}
+ bdrv_graph_wrunlock();
return job;
fail:
+ bdrv_graph_wrunlock();
job_early_fail(&job->job);
return NULL;
}