diff options
author | Kevin Wolf <kwolf@redhat.com> | 2023-05-25 14:47:11 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2023-05-30 17:29:44 +0200 |
commit | 8823407c06a920eb2af217660094fdd8aff6c176 (patch) | |
tree | 67251c7c3e1d3d283f83af4de82db03a023c11ca /block.c | |
parent | 8dc8a60c9e52fa446a5135180592c0cd4213acfb (diff) | |
download | qemu-8823407c06a920eb2af217660094fdd8aff6c176.zip qemu-8823407c06a920eb2af217660094fdd8aff6c176.tar.gz qemu-8823407c06a920eb2af217660094fdd8aff6c176.tar.bz2 |
block: Fix AioContext locking in bdrv_insert_node()
While calling bdrv_new_open_driver_opts(), the main AioContext lock must
be held, not the lock of the AioContext of the block subtree it will be
added to afterwards.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20230525124713.401149-11-kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r-- | block.c | 11 |
1 files changed, 11 insertions, 0 deletions
@@ -5399,12 +5399,17 @@ static void bdrv_delete(BlockDriverState *bs) * empty set of options. The reference to the QDict belongs to the block layer * after the call (even on failure), so if the caller intends to reuse the * dictionary, it needs to use qobject_ref() before calling bdrv_open. + * + * The caller holds the AioContext lock for @bs. It must make sure that @bs + * stays in the same AioContext, i.e. @options must not refer to nodes in a + * different AioContext. */ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options, int flags, Error **errp) { ERRP_GUARD(); int ret; + AioContext *ctx = bdrv_get_aio_context(bs); BlockDriverState *new_node_bs = NULL; const char *drvname, *node_name; BlockDriver *drv; @@ -5425,8 +5430,14 @@ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options, GLOBAL_STATE_CODE(); + aio_context_release(ctx); + aio_context_acquire(qemu_get_aio_context()); new_node_bs = bdrv_new_open_driver_opts(drv, node_name, options, flags, errp); + aio_context_release(qemu_get_aio_context()); + aio_context_acquire(ctx); + assert(bdrv_get_aio_context(bs) == ctx); + options = NULL; /* bdrv_new_open_driver() eats options */ if (!new_node_bs) { error_prepend(errp, "Could not create node: "); |