From: Kevin Wolf Date: Thu, 25 May 2023 12:47:04 +0000 (+0200) Subject: block: Take main AioContext lock when calling bdrv_open() X-Git-Tag: v8.1.0~134^2~29 X-Git-Url: https://git.proxmox.com/?p=mirror_qemu.git;a=commitdiff_plain;h=c6e0a6de62c5fa99ef06a9bb49c8072bcf93f431 block: Take main AioContext lock when calling bdrv_open() The function documentation already says that all callers must hold the main AioContext lock, but not all of them do. This can cause assertion failures when functions called by bdrv_open() try to drop the lock. Fix a few more callers to take the lock before calling bdrv_open(). Signed-off-by: Kevin Wolf Message-Id: <20230525124713.401149-4-kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- diff --git a/block.c b/block.c index 6ac47112fe..79bc9c01de 100644 --- a/block.c +++ b/block.c @@ -7037,6 +7037,8 @@ void bdrv_img_create(const char *filename, const char *fmt, return; } + aio_context_acquire(qemu_get_aio_context()); + /* Create parameter list */ create_opts = qemu_opts_append(create_opts, drv->create_opts); create_opts = qemu_opts_append(create_opts, proto_drv->create_opts); @@ -7186,6 +7188,7 @@ out: qemu_opts_del(opts); qemu_opts_free(create_opts); error_propagate(errp, local_err); + aio_context_release(qemu_get_aio_context()); } AioContext *bdrv_get_aio_context(BlockDriverState *bs) diff --git a/block/block-backend.c b/block/block-backend.c index 26447664ab..1d89fabd35 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -452,7 +452,9 @@ BlockBackend *blk_new_open(const char *filename, const char *reference, } blk = blk_new(qemu_get_aio_context(), perm, shared); + aio_context_acquire(qemu_get_aio_context()); bs = bdrv_open(filename, reference, options, flags, errp); + aio_context_release(qemu_get_aio_context()); if (!bs) { blk_unref(blk); return NULL; diff --git a/block/qapi-sysemu.c b/block/qapi-sysemu.c index cec3c1afb4..ef07151892 100644 --- a/block/qapi-sysemu.c +++ b/block/qapi-sysemu.c @@ -362,7 +362,10 @@ void qmp_blockdev_change_medium(const char *device, qdict_put_str(options, "driver", format); } + aio_context_acquire(qemu_get_aio_context()); medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp); + aio_context_release(qemu_get_aio_context()); + if (!medium_bs) { goto fail; } diff --git a/blockdev.c b/blockdev.c index 5d56b79df4..db2725fe74 100644 --- a/blockdev.c +++ b/blockdev.c @@ -662,6 +662,7 @@ err_no_opts: /* Takes the ownership of bs_opts */ BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp) { + BlockDriverState *bs; int bdrv_flags = 0; GLOBAL_STATE_CODE(); @@ -676,7 +677,11 @@ BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp) bdrv_flags |= BDRV_O_INACTIVE; } - return bdrv_open(NULL, NULL, bs_opts, bdrv_flags, errp); + aio_context_acquire(qemu_get_aio_context()); + bs = bdrv_open(NULL, NULL, bs_opts, bdrv_flags, errp); + aio_context_release(qemu_get_aio_context()); + + return bs; } void blockdev_close_all_bdrv_states(void) @@ -1480,14 +1485,20 @@ static void external_snapshot_action(TransactionAction *action, } qdict_put_str(options, "driver", format); } + aio_context_release(aio_context); + aio_context_acquire(qemu_get_aio_context()); state->new_bs = bdrv_open(new_image_file, snapshot_ref, options, flags, errp); + aio_context_release(qemu_get_aio_context()); + /* We will manually add the backing_hd field to the bs later */ if (!state->new_bs) { - goto out; + return; } + aio_context_acquire(aio_context); + /* * Allow attaching a backing file to an overlay that's already in use only * if the parents don't assume that they are already seeing a valid image. @@ -1732,15 +1743,18 @@ static void drive_backup_action(DriveBackup *backup, if (format) { qdict_put_str(options, "driver", format); } + aio_context_release(aio_context); + aio_context_acquire(qemu_get_aio_context()); target_bs = bdrv_open(backup->target, NULL, options, flags, errp); + aio_context_release(qemu_get_aio_context()); + if (!target_bs) { - goto out; + return; } /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ old_context = bdrv_get_aio_context(target_bs); - aio_context_release(aio_context); aio_context_acquire(old_context); ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); @@ -3066,13 +3080,17 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) if (format) { qdict_put_str(options, "driver", format); } + aio_context_release(aio_context); /* Mirroring takes care of copy-on-write using the source's backing * file. */ + aio_context_acquire(qemu_get_aio_context()); target_bs = bdrv_open(arg->target, NULL, options, flags, errp); + aio_context_release(qemu_get_aio_context()); + if (!target_bs) { - goto out; + return; } zero_target = (arg->sync == MIRROR_SYNC_MODE_FULL && @@ -3082,7 +3100,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ old_context = bdrv_get_aio_context(target_bs); - aio_context_release(aio_context); aio_context_acquire(old_context); ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); diff --git a/qemu-nbd.c b/qemu-nbd.c index 6ff45308a9..4276163564 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -1071,7 +1071,11 @@ int main(int argc, char **argv) qdict_put_str(raw_opts, "driver", "raw"); qdict_put_str(raw_opts, "file", bs->node_name); qdict_put_int(raw_opts, "offset", dev_offset); + + aio_context_acquire(qemu_get_aio_context()); bs = bdrv_open(NULL, NULL, raw_opts, flags, &error_fatal); + aio_context_release(qemu_get_aio_context()); + blk_remove_bs(blk); blk_insert_bs(blk, bs, &error_fatal); bdrv_unref(bs); diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c index 3a5e1eb2c4..1b40e65bad 100644 --- a/tests/unit/test-block-iothread.c +++ b/tests/unit/test-block-iothread.c @@ -833,8 +833,11 @@ static void test_attach_second_node(void) qdict_put_str(options, "driver", "raw"); qdict_put_str(options, "file", "base"); + /* FIXME raw_open() should take ctx's lock internally */ aio_context_acquire(ctx); + aio_context_acquire(main_ctx); filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort); + aio_context_release(main_ctx); aio_context_release(ctx); g_assert(blk_get_aio_context(blk) == ctx);