X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=blockjob.c;h=b7a29052b94fcb1a8a2ffb33ac8ac23962bd5c7d;hb=c2118e9e1ab34edb1b5d1b0b4092cb12271a593d;hp=25fe8e625d29e551a59b6789512caab5ec9b2920;hpb=22dd9405446f5301f32be4f9e88db6d9b582fd03;p=qmiga%2Fqemu.git diff --git a/blockjob.c b/blockjob.c index 25fe8e625d..b7a29052b9 100644 --- a/blockjob.c +++ b/blockjob.c @@ -198,6 +198,9 @@ void block_job_remove_all_bdrv(BlockJob *job) * 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); while (job->nodes) { GSList *l = job->nodes; BdrvChild *c = l->data; @@ -209,6 +212,7 @@ void block_job_remove_all_bdrv(BlockJob *job) g_slist_free_1(l); } + bdrv_graph_wrunlock_ctx(job->job.aio_context); } bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs) @@ -326,6 +330,26 @@ static bool block_job_set_speed(BlockJob *job, int64_t speed, Error **errp) 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(); @@ -354,6 +378,7 @@ BlockJobInfo *block_job_query_locked(BlockJob *job, Error **errp) { BlockJobInfo *info; uint64_t progress_current, progress_total; + const BlockJobDriver *drv = block_job_driver(job); GLOBAL_STATE_CODE(); @@ -366,7 +391,7 @@ BlockJobInfo *block_job_query_locked(BlockJob *job, Error **errp) &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; @@ -383,6 +408,11 @@ BlockJobInfo *block_job_query_locked(BlockJob *job, Error **errp) 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; } @@ -484,6 +514,8 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, int ret; GLOBAL_STATE_CODE(); + bdrv_graph_wrlock(bs); + if (job_id == NULL && !(flags & JOB_INTERNAL)) { job_id = bdrv_get_device_name(bs); } @@ -491,6 +523,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, job = job_create(job_id, &driver->job_driver, txn, bdrv_get_aio_context(bs), flags, cb, opaque, errp); if (job == NULL) { + bdrv_graph_wrunlock(bs); return NULL; } @@ -530,9 +563,11 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, goto fail; } + bdrv_graph_wrunlock(bs); return job; fail: + bdrv_graph_wrunlock(bs); job_early_fail(&job->job); return NULL; }