summaryrefslogtreecommitdiffstats
path: root/blockdev.c
diff options
context:
space:
mode:
authorKevin Wolf2022-02-03 15:05:33 +0100
committerKevin Wolf2022-02-11 09:44:16 +0100
commitaba8205be0707b9d108e32254e186ba88107a869 (patch)
tree8bf1266a5df2ac9e32eb8facf5e98da779bd5bcc /blockdev.c
parentMerge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20220208'... (diff)
downloadqemu-aba8205be0707b9d108e32254e186ba88107a869.tar.gz
qemu-aba8205be0707b9d108e32254e186ba88107a869.tar.xz
qemu-aba8205be0707b9d108e32254e186ba88107a869.zip
block: Lock AioContext for drain_end in blockdev-reopen
bdrv_subtree_drained_end() requires the caller to hold the AioContext lock for the drained node. Not doing this for nodes outside of the main AioContext leads to crashes when AIO_WAIT_WHILE() needs to wait and tries to temporarily release the lock. Fixes: 3908b7a8994fa5ef7a89aa58cd5a02fc58141592 Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2046659 Reported-by: Qing Wang <qinwang@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20220203140534.36522-2-kwolf@redhat.com> Reviewed-by: Hanna Reitz <hreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'blockdev.c')
-rw-r--r--blockdev.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/blockdev.c b/blockdev.c
index 8197165bb5..42e098b458 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3530,6 +3530,7 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
{
BlockReopenQueue *queue = NULL;
GSList *drained = NULL;
+ GSList *p;
/* Add each one of the BDS that we want to reopen to the queue */
for (; reopen_list != NULL; reopen_list = reopen_list->next) {
@@ -3579,7 +3580,15 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
fail:
bdrv_reopen_queue_free(queue);
- g_slist_free_full(drained, (GDestroyNotify) bdrv_subtree_drained_end);
+ for (p = drained; p; p = p->next) {
+ BlockDriverState *bs = p->data;
+ AioContext *ctx = bdrv_get_aio_context(bs);
+
+ aio_context_acquire(ctx);
+ bdrv_subtree_drained_end(bs);
+ aio_context_release(ctx);
+ }
+ g_slist_free(drained);
}
void qmp_blockdev_del(const char *node_name, Error **errp)