@@ -771,7 +771,14 @@ void block_job_resume_all(void)
void block_job_enter(BlockJob *job)
{
- if (job->co && !job->busy) {
+ if (!block_job_started(job)) {
+ return;
+ }
+ if (job->deferred_to_main_loop) {
+ return;
+ }
+
+ if (!job->busy) {
bdrv_coroutine_enter(blk_bs(job->blk), job->co);
}
}
@@ -899,7 +906,6 @@ static void block_job_defer_to_main_loop_bh(void *opaque)
aio_context_acquire(aio_context);
}
- data->job->deferred_to_main_loop = false;
data->fn(data->job, data->opaque);
if (aio_context != data->aio_context) {
@@ -241,7 +241,8 @@ typedef void BlockJobDeferToMainLoopFn(BlockJob *job, void *opaque);
* @fn: The function to run in the main loop
* @opaque: The opaque value that is passed to @fn
*
- * Execute a given function in the main loop with the BlockDriverState
+ * This function must be called by the main job coroutine just before it
+ * returns. @fn is executed in the main loop with the BlockDriverState
* AioContext acquired. Block jobs must call bdrv_unref(), bdrv_close(), and
* anything that uses bdrv_drain_all() in the main loop.
*