Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
copy-before-write: Fix open with child in iothread
The AioContext lock must not be held for bdrv_open_child(), but it is
necessary for the following operations, in particular those using nested
event loops in coroutine wrappers.

Temporarily dropping the main AioContext lock is not necessary because
we know we run in the main thread.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20230525124713.401149-9-kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
Kevin Wolf committed May 30, 2023
1 parent 6e01215 commit 9102f2e
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions block/copy-before-write.c
Expand Up @@ -412,6 +412,7 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
int64_t cluster_size;
g_autoptr(BlockdevOptions) full_opts = NULL;
BlockdevOptionsCbw *opts;
AioContext *ctx;
int ret;

full_opts = cbw_parse_options(options, errp);
Expand All @@ -432,11 +433,15 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
return -EINVAL;
}

ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);

if (opts->bitmap) {
bitmap = block_dirty_bitmap_lookup(opts->bitmap->node,
opts->bitmap->name, NULL, errp);
if (!bitmap) {
return -EINVAL;
ret = -EINVAL;
goto out;
}
}
s->on_cbw_error = opts->has_on_cbw_error ? opts->on_cbw_error :
Expand All @@ -454,21 +459,24 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
s->bcs = block_copy_state_new(bs->file, s->target, bitmap, errp);
if (!s->bcs) {
error_prepend(errp, "Cannot create block-copy-state: ");
return -EINVAL;
ret = -EINVAL;
goto out;
}

cluster_size = block_copy_cluster_size(s->bcs);

s->done_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp);
if (!s->done_bitmap) {
return -EINVAL;
ret = -EINVAL;
goto out;
}
bdrv_disable_dirty_bitmap(s->done_bitmap);

/* s->access_bitmap starts equal to bcs bitmap */
s->access_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp);
if (!s->access_bitmap) {
return -EINVAL;
ret = -EINVAL;
goto out;
}
bdrv_disable_dirty_bitmap(s->access_bitmap);
bdrv_dirty_bitmap_merge_internal(s->access_bitmap,
Expand All @@ -478,7 +486,10 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
qemu_co_mutex_init(&s->lock);
QLIST_INIT(&s->frozen_read_reqs);

return 0;
ret = 0;
out:
aio_context_release(ctx);
return ret;
}

static void cbw_close(BlockDriverState *bs)
Expand Down

0 comments on commit 9102f2e

Please sign in to comment.