diff --git a/blockjob.c b/blockjob.c index 2159df776b..0e9ed0336d 100644 --- a/blockjob.c +++ b/blockjob.c @@ -250,16 +250,28 @@ static bool block_job_started(BlockJob *job) return job->co; } +/** + * All jobs must allow a pause point before entering their job proper. This + * ensures that jobs can be paused prior to being started, then resumed later. + */ +static void coroutine_fn block_job_co_entry(void *opaque) +{ + BlockJob *job = opaque; + + assert(job && job->driver && job->driver->start); + block_job_pause_point(job); + job->driver->start(job); +} + void block_job_start(BlockJob *job) { assert(job && !block_job_started(job) && job->paused && - !job->busy && job->driver->start); - job->co = qemu_coroutine_create(job->driver->start, job); - if (--job->pause_count == 0) { - job->paused = false; - job->busy = true; - qemu_coroutine_enter(job->co); - } + job->driver && job->driver->start); + job->co = qemu_coroutine_create(block_job_co_entry, job); + job->pause_count--; + job->busy = true; + job->paused = false; + qemu_coroutine_enter(job->co); } void block_job_ref(BlockJob *job)