mirror of https://github.com/xemu-project/xemu.git
blockjob: Introduce block_job_complete_sync()
Implement block_job_complete_sync() by doing the exact same thing as block_job_cancel_sync() does, only with calling block_job_complete() instead of block_job_cancel(). Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-id: 1414159063-25977-5-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
94054183da
commit
345f9e1b04
39
blockjob.c
39
blockjob.c
|
@ -153,7 +153,7 @@ void block_job_iostatus_reset(BlockJob *job)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BlockCancelData {
|
struct BlockFinishData {
|
||||||
BlockJob *job;
|
BlockJob *job;
|
||||||
BlockCompletionFunc *cb;
|
BlockCompletionFunc *cb;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
|
@ -161,19 +161,22 @@ struct BlockCancelData {
|
||||||
int ret;
|
int ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void block_job_cancel_cb(void *opaque, int ret)
|
static void block_job_finish_cb(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
struct BlockCancelData *data = opaque;
|
struct BlockFinishData *data = opaque;
|
||||||
|
|
||||||
data->cancelled = block_job_is_cancelled(data->job);
|
data->cancelled = block_job_is_cancelled(data->job);
|
||||||
data->ret = ret;
|
data->ret = ret;
|
||||||
data->cb(data->opaque, ret);
|
data->cb(data->opaque, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int block_job_cancel_sync(BlockJob *job)
|
static int block_job_finish_sync(BlockJob *job,
|
||||||
|
void (*finish)(BlockJob *, Error **errp),
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
struct BlockCancelData data;
|
struct BlockFinishData data;
|
||||||
BlockDriverState *bs = job->bs;
|
BlockDriverState *bs = job->bs;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
assert(bs->job == job);
|
assert(bs->job == job);
|
||||||
|
|
||||||
|
@ -184,15 +187,37 @@ int block_job_cancel_sync(BlockJob *job)
|
||||||
data.cb = job->cb;
|
data.cb = job->cb;
|
||||||
data.opaque = job->opaque;
|
data.opaque = job->opaque;
|
||||||
data.ret = -EINPROGRESS;
|
data.ret = -EINPROGRESS;
|
||||||
job->cb = block_job_cancel_cb;
|
job->cb = block_job_finish_cb;
|
||||||
job->opaque = &data;
|
job->opaque = &data;
|
||||||
block_job_cancel(job);
|
finish(job, &local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
while (data.ret == -EINPROGRESS) {
|
while (data.ret == -EINPROGRESS) {
|
||||||
aio_poll(bdrv_get_aio_context(bs), true);
|
aio_poll(bdrv_get_aio_context(bs), true);
|
||||||
}
|
}
|
||||||
return (data.cancelled && data.ret == 0) ? -ECANCELED : data.ret;
|
return (data.cancelled && data.ret == 0) ? -ECANCELED : data.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A wrapper around block_job_cancel() taking an Error ** parameter so it may be
|
||||||
|
* used with block_job_finish_sync() without the need for (rather nasty)
|
||||||
|
* function pointer casts there. */
|
||||||
|
static void block_job_cancel_err(BlockJob *job, Error **errp)
|
||||||
|
{
|
||||||
|
block_job_cancel(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
int block_job_cancel_sync(BlockJob *job)
|
||||||
|
{
|
||||||
|
return block_job_finish_sync(job, &block_job_cancel_err, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int block_job_complete_sync(BlockJob *job, Error **errp)
|
||||||
|
{
|
||||||
|
return block_job_finish_sync(job, &block_job_complete, errp);
|
||||||
|
}
|
||||||
|
|
||||||
void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns)
|
void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns)
|
||||||
{
|
{
|
||||||
assert(job->busy);
|
assert(job->busy);
|
||||||
|
|
|
@ -272,6 +272,21 @@ bool block_job_is_paused(BlockJob *job);
|
||||||
*/
|
*/
|
||||||
int block_job_cancel_sync(BlockJob *job);
|
int block_job_cancel_sync(BlockJob *job);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* block_job_complete_sync:
|
||||||
|
* @job: The job to be completed.
|
||||||
|
* @errp: Error object which may be set by block_job_complete(); this is not
|
||||||
|
* necessarily set on every error, the job return value has to be
|
||||||
|
* checked as well.
|
||||||
|
*
|
||||||
|
* Synchronously complete the job. The completion callback is called before the
|
||||||
|
* function returns, unless it is NULL (which is permissible when using this
|
||||||
|
* function).
|
||||||
|
*
|
||||||
|
* Returns the return value from the job.
|
||||||
|
*/
|
||||||
|
int block_job_complete_sync(BlockJob *job, Error **errp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* block_job_iostatus_reset:
|
* block_job_iostatus_reset:
|
||||||
* @job: The job whose I/O status should be reset.
|
* @job: The job whose I/O status should be reset.
|
||||||
|
|
Loading…
Reference in New Issue