[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 19/31] block: Cancel jobs first in bdrv_close_all()
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 19/31] block: Cancel jobs first in bdrv_close_all() |
Date: |
Wed, 25 May 2016 19:39:44 +0200 |
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 <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
Reviewed-by: Alberto Garcia <address@hidden>
Reviewed-by: Max Reitz <address@hidden>
---
block.c | 23 ++---------------------
blockjob.c | 13 +++++++++++++
include/block/blockjob.h | 7 +++++++
3 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/block.c b/block.c
index 45cddd6..736432f 100644
--- a/block.c
+++ b/block.c
@@ -2209,8 +2209,7 @@ static void bdrv_close(BlockDriverState *bs)
void bdrv_close_all(void)
{
- BlockDriverState *bs;
- AioContext *aio_context;
+ block_job_cancel_sync_all();
/* Drop references from requests still in flight, such as canceled block
* jobs whose AIO context has not been polled yet */
@@ -2219,25 +2218,7 @@ void bdrv_close_all(void)
blk_remove_all_bs();
blockdev_close_all_bdrv_states();
- /* Cancel all block jobs */
- while (!QTAILQ_EMPTY(&all_bdrv_states)) {
- QTAILQ_FOREACH(bs, &all_bdrv_states, bs_list) {
- aio_context = bdrv_get_aio_context(bs);
-
- aio_context_acquire(aio_context);
- if (bs->job) {
- block_job_cancel_sync(bs->job);
- aio_context_release(aio_context);
- break;
- }
- aio_context_release(aio_context);
- }
-
- /* All the remaining BlockDriverStates are referenced directly or
- * indirectly from block jobs, so there needs to be at least one BDS
- * directly used by a block job */
- assert(bs);
- }
+ assert(QTAILQ_EMPTY(&all_bdrv_states));
}
static void change_parent_backing_link(BlockDriverState *from,
diff --git a/blockjob.c b/blockjob.c
index 0f1bc77..e916b41 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);
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 30bb2c6..4ac6831 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -371,6 +371,13 @@ bool block_job_is_paused(BlockJob *job);
int block_job_cancel_sync(BlockJob *job);
/**
+ * block_job_cancel_sync_all:
+ *
+ * Synchronously cancels all jobs using block_job_cancel_sync().
+ */
+void block_job_cancel_sync_all(void);
+
+/**
* block_job_complete_sync:
* @job: The job to be completed.
* @errp: Error object which may be set by block_job_complete(); this is not
--
1.8.3.1
- [Qemu-block] [PULL 07/31] block: Make bdrv_open() return a BDS, (continued)
- [Qemu-block] [PULL 07/31] block: Make bdrv_open() return a BDS, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 04/31] tests: Drop BDS from test-throttle.c, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 10/31] block: Drop errp parameter from blk_new(), Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 13/31] block: Fix reconfiguring graph with drained nodes, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 11/31] block: Introduce bdrv_replace_child(), Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 12/31] block: Make bdrv_drain() use bdrv_drained_begin/end(), Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 16/31] dma-helpers: change BlockBackend to opaque value in DMAIOFunc, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 20/31] block: Default to enabled write cache in blk_new(), Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 14/31] block: Propagate .drained_begin/end callbacks, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 15/31] dma-helpers: change interface to byte-based, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 19/31] block: Cancel jobs first in bdrv_close_all(),
Kevin Wolf <=
- [Qemu-block] [PULL 18/31] block: keep a list of block jobs, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 22/31] block: Make blk_co_preadv/pwritev() public, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 17/31] block: Rename blk_write_zeroes(), Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 23/31] stream: Use BlockBackend for I/O, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 28/31] backup: Remove bs parameter from backup_do_cow(), Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 21/31] block: Convert block job core to BlockBackend, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 27/31] backup: Pack Notifier within BackupBlockJob, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 24/31] mirror: Allow target that already has a BlockBackend, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 26/31] backup: Don't leak BackupBlockJob in error path, Kevin Wolf, 2016/05/25
- [Qemu-block] [PULL 25/31] mirror: Use BlockBackend for I/O, Kevin Wolf, 2016/05/25