diff options
Diffstat (limited to 'block/block-backend.c')
| -rw-r--r-- | block/block-backend.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/block/block-backend.c b/block/block-backend.c index 4c0a8ef88d..f5d9407d20 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -42,6 +42,7 @@ struct BlockBackend { char *name; int refcnt; BdrvChild *root; + AioContext *ctx; DriveInfo *legacy_dinfo; /* null unless created by drive_new() */ QTAILQ_ENTRY(BlockBackend) link; /* for block_backends */ QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */ @@ -322,12 +323,13 @@ static const BdrvChildRole child_root = { * * Return the new BlockBackend on success, null on failure. */ -BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm) +BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm) { BlockBackend *blk; blk = g_new0(BlockBackend, 1); blk->refcnt = 1; + blk->ctx = ctx; blk->perm = perm; blk->shared_perm = shared_perm; blk_set_enable_write_cache(blk, true); @@ -347,6 +349,7 @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm) /* * Creates a new BlockBackend, opens a new BlockDriverState, and connects both. + * The new BlockBackend is in the main AioContext. * * Just as with bdrv_open(), after having called this function the reference to * @options belongs to the block layer (even on failure). @@ -382,17 +385,16 @@ BlockBackend *blk_new_open(const char *filename, const char *reference, perm |= BLK_PERM_RESIZE; } - blk = blk_new(perm, BLK_PERM_ALL); + blk = blk_new(qemu_get_aio_context(), perm, BLK_PERM_ALL); bs = bdrv_open(filename, reference, options, flags, errp); if (!bs) { blk_unref(blk); return NULL; } - blk->root = bdrv_root_attach_child(bs, "root", &child_root, + blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx, perm, BLK_PERM_ALL, blk, errp); if (!blk->root) { - bdrv_unref(bs); blk_unref(blk); return NULL; } @@ -800,12 +802,12 @@ void blk_remove_bs(BlockBackend *blk) int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp) { ThrottleGroupMember *tgm = &blk->public.throttle_group_member; - blk->root = bdrv_root_attach_child(bs, "root", &child_root, + bdrv_ref(bs); + blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx, blk->perm, blk->shared_perm, blk, errp); if (blk->root == NULL) { return -EPERM; } - bdrv_ref(bs); notifier_list_notify(&blk->insert_bs_notifiers, blk); if (tgm->throttle_state) { @@ -1857,7 +1859,14 @@ void blk_op_unblock_all(BlockBackend *blk, Error *reason) AioContext *blk_get_aio_context(BlockBackend *blk) { - return bdrv_get_aio_context(blk_bs(blk)); + BlockDriverState *bs = blk_bs(blk); + + if (bs) { + AioContext *ctx = bdrv_get_aio_context(blk_bs(blk)); + assert(ctx == blk->ctx); + } + + return blk->ctx; } static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb) @@ -1866,30 +1875,37 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb) return blk_get_aio_context(blk_acb->blk); } -static void blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, - bool update_root_node) +static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, + bool update_root_node, Error **errp) { BlockDriverState *bs = blk_bs(blk); ThrottleGroupMember *tgm = &blk->public.throttle_group_member; + int ret; if (bs) { + if (update_root_node) { + ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root, + errp); + if (ret < 0) { + return ret; + } + } if (tgm->throttle_state) { bdrv_drained_begin(bs); throttle_group_detach_aio_context(tgm); throttle_group_attach_aio_context(tgm, new_context); bdrv_drained_end(bs); } - if (update_root_node) { - GSList *ignore = g_slist_prepend(NULL, blk->root); - bdrv_set_aio_context_ignore(bs, new_context, &ignore); - g_slist_free(ignore); - } } + + blk->ctx = new_context; + return 0; } -void blk_set_aio_context(BlockBackend *blk, AioContext *new_context) +int blk_set_aio_context(BlockBackend *blk, AioContext *new_context, + Error **errp) { - blk_do_set_aio_context(blk, new_context, true); + return blk_do_set_aio_context(blk, new_context, true, errp); } static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, @@ -1916,7 +1932,7 @@ static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, GSList **ignore) { BlockBackend *blk = child->opaque; - blk_do_set_aio_context(blk, ctx, false); + blk_do_set_aio_context(blk, ctx, false, &error_abort); } void blk_add_aio_context_notifier(BlockBackend *blk, |