From a1a2af075647bb61e1435ce4c78d99e3f36d928b Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 8 Apr 2016 18:26:37 +0200 Subject: block: Cancel jobs first in bdrv_close_all() So far, bdrv_close_all() first removed all root BlockDriverStates of BlockBackends and monitor owned BDSes, and then assumed that the remaining BDSes must be related to jobs and cancelled these jobs. This order doesn't work that well any more when block jobs use BlockBackends internally because then they will lose their BDS before being cancelled. This patch changes bdrv_close_all() to first cancel all jobs and then remove all root BDSes from the remaining BBs. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Reviewed-by: Max Reitz --- blockjob.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'blockjob.c') diff --git a/blockjob.c b/blockjob.c index 0f1bc77b1d..e916b41030 100644 --- a/blockjob.c +++ b/blockjob.c @@ -331,6 +331,19 @@ int block_job_cancel_sync(BlockJob *job) return block_job_finish_sync(job, &block_job_cancel_err, NULL); } +void block_job_cancel_sync_all(void) +{ + BlockJob *job; + AioContext *aio_context; + + while ((job = QLIST_FIRST(&block_jobs))) { + aio_context = bdrv_get_aio_context(job->bs); + aio_context_acquire(aio_context); + block_job_cancel_sync(job); + aio_context_release(aio_context); + } +} + int block_job_complete_sync(BlockJob *job, Error **errp) { return block_job_finish_sync(job, &block_job_complete, errp); -- cgit v1.2.3