From 004e95df98266da33e08c9f1731aca71b6d6d7c4 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 20 Apr 2018 14:56:08 +0200 Subject: job: Convert block_job_cancel_async() to Job block_job_cancel_async() did two things that were still block job specific: * Setting job->force. This field makes sense on the Job level, so we can just move it. While at it, rename it to job->force_cancel to make its purpose more obvious. * Resetting the I/O status. This can't be moved because generic Jobs don't have an I/O status. What the function really implements is a user resume, except without entering the coroutine. Consequently, it makes sense to call the .user_resume driver callback here which already resets the I/O status. The old block_job_cancel_async() has two separate if statements that check job->iostatus != BLOCK_DEVICE_IO_STATUS_OK and job->user_paused. However, the former condition always implies the latter (as is asserted in block_job_iostatus_reset()), so changing the explicit call of block_job_iostatus_reset() on the former condition with the .user_resume callback on the latter condition is equivalent and doesn't need to access any BlockJob specific state. Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz --- blockjob.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'blockjob.c') diff --git a/blockjob.c b/blockjob.c index 34c57da304..4cac3670ad 100644 --- a/blockjob.c +++ b/blockjob.c @@ -270,19 +270,20 @@ static int block_job_prepare(BlockJob *job) return job->job.ret; } -static void block_job_cancel_async(BlockJob *job, bool force) +static void job_cancel_async(Job *job, bool force) { - if (job->iostatus != BLOCK_DEVICE_IO_STATUS_OK) { - block_job_iostatus_reset(job); - } - if (job->job.user_paused) { - /* Do not call block_job_enter here, the caller will handle it. */ - job->job.user_paused = false; - job->job.pause_count--; + if (job->user_paused) { + /* Do not call job_enter here, the caller will handle it. */ + job->user_paused = false; + if (job->driver->user_resume) { + job->driver->user_resume(job); + } + assert(job->pause_count > 0); + job->pause_count--; } - job->job.cancelled = true; + job->cancelled = true; /* To prevent 'force == false' overriding a previous 'force == true' */ - job->force |= force; + job->force_cancel |= force; } static int block_job_txn_apply(BlockJobTxn *txn, int fn(BlockJob *), bool lock) @@ -367,7 +368,7 @@ static void block_job_completed_txn_abort(BlockJob *job) * on the caller, so leave it. */ QLIST_FOREACH(other_job, &txn->jobs, txn_list) { if (other_job != job) { - block_job_cancel_async(other_job, false); + job_cancel_async(&other_job->job, false); } } while (!QLIST_EMPTY(&txn->jobs)) { @@ -527,7 +528,7 @@ void block_job_cancel(BlockJob *job, bool force) job_do_dismiss(&job->job); return; } - block_job_cancel_async(job, force); + job_cancel_async(&job->job, force); if (!job_started(&job->job)) { block_job_completed(job, -ECANCELED); } else if (job->job.deferred_to_main_loop) { -- cgit v1.2.3