All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, mreitz@redhat.com, berto@igalia.com,
	jcody@redhat.com, jsnow@redhat.com, qemu-devel@nongnu.org,
	eblake@redhat.com
Subject: [Qemu-devel] [PATCH v3 03/15] block: Cancel jobs first in bdrv_close_all()
Date: Wed, 25 May 2016 14:29:11 +0200	[thread overview]
Message-ID: <1464179363-19821-4-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1464179363-19821-1-git-send-email-kwolf@redhat.com>

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 <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
---
 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

  parent reply	other threads:[~2016-05-25 12:29 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-25 12:29 [Qemu-devel] [PATCH v3 00/15] block jobs: Convert I/O to BlockBackend Kevin Wolf
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 01/15] block: Rename blk_write_zeroes() Kevin Wolf
2016-05-25 14:40   ` Max Reitz
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 02/15] block: keep a list of block jobs Kevin Wolf
2016-05-25 12:29 ` Kevin Wolf [this message]
2016-05-25 14:44   ` [Qemu-devel] [PATCH v3 03/15] block: Cancel jobs first in bdrv_close_all() Max Reitz
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 04/15] block: Default to enabled write cache in blk_new() Kevin Wolf
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 05/15] block: Convert block job core to BlockBackend Kevin Wolf
2016-05-25 14:51   ` Max Reitz
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 06/15] block: Make blk_co_preadv/pwritev() public Kevin Wolf
2016-05-25 13:41   ` Alberto Garcia
2016-05-25 14:08   ` Eric Blake
2016-05-25 14:54   ` Max Reitz
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 07/15] stream: Use BlockBackend for I/O Kevin Wolf
2016-05-25 14:56   ` Max Reitz
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 08/15] mirror: Allow target that already has a BlockBackend Kevin Wolf
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 09/15] mirror: Use BlockBackend for I/O Kevin Wolf
2016-05-25 15:02   ` Max Reitz
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 10/15] backup: Don't leak BackupBlockJob in error path Kevin Wolf
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 11/15] backup: Pack Notifier within BackupBlockJob Kevin Wolf
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 12/15] backup: Remove bs parameter from backup_do_cow() Kevin Wolf
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 13/15] backup: Use BlockBackend for I/O Kevin Wolf
2016-05-25 15:17   ` Max Reitz
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 14/15] commit: " Kevin Wolf
2016-05-25 15:19   ` Max Reitz
2016-05-25 12:29 ` [Qemu-devel] [PATCH v3 15/15] blockjob: Remove BlockJob.bs Kevin Wolf
2016-05-25 15:21   ` Max Reitz
2016-05-25 15:48   ` Eric Blake

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1464179363-19821-4-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=berto@igalia.com \
    --cc=eblake@redhat.com \
    --cc=jcody@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.