mirror of
https://github.com/qemu/qemu.git
synced 2024-11-27 05:43:47 +08:00
block: Add block_job_add_bdrv()
When a block job is created on a certain BlockDriverState, operations are blocked there while the job exists. However, some block jobs may involve additional BDSs, which must be blocked separately when the job is created and unblocked manually afterwards. This patch adds block_job_add_bdrv(), that simplifies this process by keeping a list of BDSs that are involved in the specified block job. Signed-off-by: Alberto Garcia <berto@igalia.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
40840e419b
commit
23d402d42b
17
blockjob.c
17
blockjob.c
@ -113,6 +113,13 @@ static void block_job_detach_aio_context(void *opaque)
|
||||
block_job_unref(job);
|
||||
}
|
||||
|
||||
void block_job_add_bdrv(BlockJob *job, BlockDriverState *bs)
|
||||
{
|
||||
job->nodes = g_slist_prepend(job->nodes, bs);
|
||||
bdrv_ref(bs);
|
||||
bdrv_op_block_all(bs, job->blocker);
|
||||
}
|
||||
|
||||
void *block_job_create(const char *job_id, const BlockJobDriver *driver,
|
||||
BlockDriverState *bs, int64_t speed,
|
||||
BlockCompletionFunc *cb, void *opaque, Error **errp)
|
||||
@ -150,7 +157,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
|
||||
job = g_malloc0(driver->instance_size);
|
||||
error_setg(&job->blocker, "block device is in use by block job: %s",
|
||||
BlockJobType_lookup[driver->job_type]);
|
||||
bdrv_op_block_all(bs, job->blocker);
|
||||
block_job_add_bdrv(job, bs);
|
||||
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
|
||||
|
||||
job->driver = driver;
|
||||
@ -189,9 +196,15 @@ void block_job_ref(BlockJob *job)
|
||||
void block_job_unref(BlockJob *job)
|
||||
{
|
||||
if (--job->refcnt == 0) {
|
||||
GSList *l;
|
||||
BlockDriverState *bs = blk_bs(job->blk);
|
||||
bs->job = NULL;
|
||||
bdrv_op_unblock_all(bs, job->blocker);
|
||||
for (l = job->nodes; l; l = l->next) {
|
||||
bs = l->data;
|
||||
bdrv_op_unblock_all(bs, job->blocker);
|
||||
bdrv_unref(bs);
|
||||
}
|
||||
g_slist_free(job->nodes);
|
||||
blk_remove_aio_context_notifier(job->blk,
|
||||
block_job_attached_aio_context,
|
||||
block_job_detach_aio_context, job);
|
||||
|
@ -188,6 +188,9 @@ struct BlockJob {
|
||||
/** Block other operations when block job is running */
|
||||
Error *blocker;
|
||||
|
||||
/** BlockDriverStates that are involved in this block job */
|
||||
GSList *nodes;
|
||||
|
||||
/** The opaque value that is passed to the completion function. */
|
||||
void *opaque;
|
||||
|
||||
@ -252,6 +255,17 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
|
||||
BlockDriverState *bs, int64_t speed,
|
||||
BlockCompletionFunc *cb, void *opaque, Error **errp);
|
||||
|
||||
/**
|
||||
* block_job_add_bdrv:
|
||||
* @job: A block job
|
||||
* @bs: A BlockDriverState that is involved in @job
|
||||
*
|
||||
* Add @bs to the list of BlockDriverState that are involved in
|
||||
* @job. This means that all operations will be blocked on @bs while
|
||||
* @job exists.
|
||||
*/
|
||||
void block_job_add_bdrv(BlockJob *job, BlockDriverState *bs);
|
||||
|
||||
/**
|
||||
* block_job_sleep_ns:
|
||||
* @job: The job that calls the function.
|
||||
|
Loading…
Reference in New Issue
Block a user