mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2024-09-10 15:56:45 +03:00
block: remove AioContext locking
This is the big patch that removes aio_context_acquire()/aio_context_release() from the block layer and affected block layer users. There isn't a clean way to split this patch and the reviewers are likely the same group of people, so I decided to do it in one patch. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Paul Durrant <paul@xen.org> Message-ID: <20231205182011.1976568-7-stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
6bc30f1949
commit
b49f4755c7
234
block.c
234
block.c
|
@ -1625,7 +1625,6 @@ static int no_coroutine_fn GRAPH_UNLOCKED
|
|||
bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name,
|
||||
QDict *options, int open_flags, Error **errp)
|
||||
{
|
||||
AioContext *ctx;
|
||||
Error *local_err = NULL;
|
||||
int i, ret;
|
||||
GLOBAL_STATE_CODE();
|
||||
|
@ -1673,21 +1672,15 @@ bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name,
|
|||
bs->supported_read_flags |= BDRV_REQ_REGISTERED_BUF;
|
||||
bs->supported_write_flags |= BDRV_REQ_REGISTERED_BUF;
|
||||
|
||||
/* Get the context after .bdrv_open, it can change the context */
|
||||
ctx = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(ctx);
|
||||
|
||||
ret = bdrv_refresh_total_sectors(bs, bs->total_sectors);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Could not refresh total sector count");
|
||||
aio_context_release(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
bdrv_refresh_limits(bs, NULL, &local_err);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
aio_context_release(ctx);
|
||||
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
|
@ -3062,7 +3055,7 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
|
|||
Transaction *tran, Error **errp)
|
||||
{
|
||||
BdrvChild *new_child;
|
||||
AioContext *parent_ctx, *new_child_ctx;
|
||||
AioContext *parent_ctx;
|
||||
AioContext *child_ctx = bdrv_get_aio_context(child_bs);
|
||||
|
||||
assert(child_class->get_parent_desc);
|
||||
|
@ -3114,12 +3107,6 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
|
|||
}
|
||||
}
|
||||
|
||||
new_child_ctx = bdrv_get_aio_context(child_bs);
|
||||
if (new_child_ctx != child_ctx) {
|
||||
aio_context_release(child_ctx);
|
||||
aio_context_acquire(new_child_ctx);
|
||||
}
|
||||
|
||||
bdrv_ref(child_bs);
|
||||
/*
|
||||
* Let every new BdrvChild start with a drained parent. Inserting the child
|
||||
|
@ -3149,11 +3136,6 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
|
|||
};
|
||||
tran_add(tran, &bdrv_attach_child_common_drv, s);
|
||||
|
||||
if (new_child_ctx != child_ctx) {
|
||||
aio_context_release(new_child_ctx);
|
||||
aio_context_acquire(child_ctx);
|
||||
}
|
||||
|
||||
return new_child;
|
||||
}
|
||||
|
||||
|
@ -3605,7 +3587,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
|||
int ret = 0;
|
||||
bool implicit_backing = false;
|
||||
BlockDriverState *backing_hd;
|
||||
AioContext *backing_hd_ctx;
|
||||
QDict *options;
|
||||
QDict *tmp_parent_options = NULL;
|
||||
Error *local_err = NULL;
|
||||
|
@ -3691,11 +3672,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
|||
|
||||
/* Hook up the backing file link; drop our reference, bs owns the
|
||||
* backing_hd reference now */
|
||||
backing_hd_ctx = bdrv_get_aio_context(backing_hd);
|
||||
aio_context_acquire(backing_hd_ctx);
|
||||
ret = bdrv_set_backing_hd(bs, backing_hd, errp);
|
||||
bdrv_unref(backing_hd);
|
||||
aio_context_release(backing_hd_ctx);
|
||||
|
||||
if (ret < 0) {
|
||||
goto free_exit;
|
||||
|
@ -3780,7 +3758,6 @@ BdrvChild *bdrv_open_child(const char *filename,
|
|||
{
|
||||
BlockDriverState *bs;
|
||||
BdrvChild *child;
|
||||
AioContext *ctx;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
|
@ -3791,11 +3768,8 @@ BdrvChild *bdrv_open_child(const char *filename,
|
|||
}
|
||||
|
||||
bdrv_graph_wrlock();
|
||||
ctx = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(ctx);
|
||||
child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
|
||||
errp);
|
||||
aio_context_release(ctx);
|
||||
bdrv_graph_wrunlock();
|
||||
|
||||
return child;
|
||||
|
@ -3881,7 +3855,6 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
|
|||
int64_t total_size;
|
||||
QemuOpts *opts = NULL;
|
||||
BlockDriverState *bs_snapshot = NULL;
|
||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||
int ret;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
@ -3890,9 +3863,7 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
|
|||
instead of opening 'filename' directly */
|
||||
|
||||
/* Get the required size from the image */
|
||||
aio_context_acquire(ctx);
|
||||
total_size = bdrv_getlength(bs);
|
||||
aio_context_release(ctx);
|
||||
|
||||
if (total_size < 0) {
|
||||
error_setg_errno(errp, -total_size, "Could not get image size");
|
||||
|
@ -3927,10 +3898,7 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
|
|||
goto out;
|
||||
}
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
ret = bdrv_append(bs_snapshot, bs, errp);
|
||||
aio_context_release(ctx);
|
||||
|
||||
if (ret < 0) {
|
||||
bs_snapshot = NULL;
|
||||
goto out;
|
||||
|
@ -3974,7 +3942,6 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
|
|||
Error *local_err = NULL;
|
||||
QDict *snapshot_options = NULL;
|
||||
int snapshot_flags = 0;
|
||||
AioContext *ctx = qemu_get_aio_context();
|
||||
|
||||
assert(!child_class || !flags);
|
||||
assert(!child_class == !parent);
|
||||
|
@ -4115,12 +4082,10 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
|
|||
/* Not requesting BLK_PERM_CONSISTENT_READ because we're only
|
||||
* looking at the header to guess the image format. This works even
|
||||
* in cases where a guest would not see a consistent state. */
|
||||
ctx = bdrv_get_aio_context(file_bs);
|
||||
aio_context_acquire(ctx);
|
||||
AioContext *ctx = bdrv_get_aio_context(file_bs);
|
||||
file = blk_new(ctx, 0, BLK_PERM_ALL);
|
||||
blk_insert_bs(file, file_bs, &local_err);
|
||||
bdrv_unref(file_bs);
|
||||
aio_context_release(ctx);
|
||||
|
||||
if (local_err) {
|
||||
goto fail;
|
||||
|
@ -4167,13 +4132,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
/* The AioContext could have changed during bdrv_open_common() */
|
||||
ctx = bdrv_get_aio_context(bs);
|
||||
|
||||
if (file) {
|
||||
aio_context_acquire(ctx);
|
||||
blk_unref(file);
|
||||
aio_context_release(ctx);
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
|
@ -4231,16 +4191,13 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
|
|||
* (snapshot_bs); thus, we have to drop the strong reference to bs
|
||||
* (which we obtained by calling bdrv_new()). bs will not be deleted,
|
||||
* though, because the overlay still has a reference to it. */
|
||||
aio_context_acquire(ctx);
|
||||
bdrv_unref(bs);
|
||||
aio_context_release(ctx);
|
||||
bs = snapshot_bs;
|
||||
}
|
||||
|
||||
return bs;
|
||||
|
||||
fail:
|
||||
aio_context_acquire(ctx);
|
||||
blk_unref(file);
|
||||
qobject_unref(snapshot_options);
|
||||
qobject_unref(bs->explicit_options);
|
||||
|
@ -4249,14 +4206,11 @@ fail:
|
|||
bs->options = NULL;
|
||||
bs->explicit_options = NULL;
|
||||
bdrv_unref(bs);
|
||||
aio_context_release(ctx);
|
||||
error_propagate(errp, local_err);
|
||||
return NULL;
|
||||
|
||||
close_and_fail:
|
||||
aio_context_acquire(ctx);
|
||||
bdrv_unref(bs);
|
||||
aio_context_release(ctx);
|
||||
qobject_unref(snapshot_options);
|
||||
qobject_unref(options);
|
||||
error_propagate(errp, local_err);
|
||||
|
@ -4540,12 +4494,7 @@ void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue)
|
|||
if (bs_queue) {
|
||||
BlockReopenQueueEntry *bs_entry, *next;
|
||||
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
|
||||
AioContext *ctx = bdrv_get_aio_context(bs_entry->state.bs);
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
bdrv_drained_end(bs_entry->state.bs);
|
||||
aio_context_release(ctx);
|
||||
|
||||
qobject_unref(bs_entry->state.explicit_options);
|
||||
qobject_unref(bs_entry->state.options);
|
||||
g_free(bs_entry);
|
||||
|
@ -4577,7 +4526,6 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
|
|||
{
|
||||
int ret = -1;
|
||||
BlockReopenQueueEntry *bs_entry, *next;
|
||||
AioContext *ctx;
|
||||
Transaction *tran = tran_new();
|
||||
g_autoptr(GSList) refresh_list = NULL;
|
||||
|
||||
|
@ -4586,10 +4534,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
|
|||
GLOBAL_STATE_CODE();
|
||||
|
||||
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
|
||||
ctx = bdrv_get_aio_context(bs_entry->state.bs);
|
||||
aio_context_acquire(ctx);
|
||||
ret = bdrv_flush(bs_entry->state.bs);
|
||||
aio_context_release(ctx);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Error flushing drive");
|
||||
goto abort;
|
||||
|
@ -4598,10 +4543,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
|
|||
|
||||
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
|
||||
assert(bs_entry->state.bs->quiesce_counter > 0);
|
||||
ctx = bdrv_get_aio_context(bs_entry->state.bs);
|
||||
aio_context_acquire(ctx);
|
||||
ret = bdrv_reopen_prepare(&bs_entry->state, bs_queue, tran, errp);
|
||||
aio_context_release(ctx);
|
||||
if (ret < 0) {
|
||||
goto abort;
|
||||
}
|
||||
|
@ -4644,10 +4586,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
|
|||
* to first element.
|
||||
*/
|
||||
QTAILQ_FOREACH_REVERSE(bs_entry, bs_queue, entry) {
|
||||
ctx = bdrv_get_aio_context(bs_entry->state.bs);
|
||||
aio_context_acquire(ctx);
|
||||
bdrv_reopen_commit(&bs_entry->state);
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
|
||||
bdrv_graph_wrlock();
|
||||
|
@ -4658,10 +4597,7 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
|
|||
BlockDriverState *bs = bs_entry->state.bs;
|
||||
|
||||
if (bs->drv->bdrv_reopen_commit_post) {
|
||||
ctx = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(ctx);
|
||||
bs->drv->bdrv_reopen_commit_post(&bs_entry->state);
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4675,10 +4611,7 @@ abort:
|
|||
|
||||
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
|
||||
if (bs_entry->prepared) {
|
||||
ctx = bdrv_get_aio_context(bs_entry->state.bs);
|
||||
aio_context_acquire(ctx);
|
||||
bdrv_reopen_abort(&bs_entry->state);
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4691,24 +4624,13 @@ cleanup:
|
|||
int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
|
||||
Error **errp)
|
||||
{
|
||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||
BlockReopenQueue *queue;
|
||||
int ret;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
queue = bdrv_reopen_queue(NULL, bs, opts, keep_old_opts);
|
||||
|
||||
if (ctx != qemu_get_aio_context()) {
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
ret = bdrv_reopen_multiple(queue, errp);
|
||||
|
||||
if (ctx != qemu_get_aio_context()) {
|
||||
aio_context_acquire(ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return bdrv_reopen_multiple(queue, errp);
|
||||
}
|
||||
|
||||
int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
|
||||
|
@ -4760,7 +4682,6 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
|
|||
const char *child_name = is_backing ? "backing" : "file";
|
||||
QObject *value;
|
||||
const char *str;
|
||||
AioContext *ctx, *old_ctx;
|
||||
bool has_child;
|
||||
int ret;
|
||||
|
||||
|
@ -4844,13 +4765,6 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
|
|||
bdrv_drained_begin(old_child_bs);
|
||||
}
|
||||
|
||||
old_ctx = bdrv_get_aio_context(bs);
|
||||
ctx = bdrv_get_aio_context(new_child_bs);
|
||||
if (old_ctx != ctx) {
|
||||
aio_context_release(old_ctx);
|
||||
aio_context_acquire(ctx);
|
||||
}
|
||||
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
bdrv_graph_wrlock();
|
||||
|
||||
|
@ -4859,11 +4773,6 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
|
|||
|
||||
bdrv_graph_wrunlock();
|
||||
|
||||
if (old_ctx != ctx) {
|
||||
aio_context_release(ctx);
|
||||
aio_context_acquire(old_ctx);
|
||||
}
|
||||
|
||||
if (old_child_bs) {
|
||||
bdrv_drained_end(old_child_bs);
|
||||
bdrv_unref(old_child_bs);
|
||||
|
@ -5537,7 +5446,6 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
|||
int ret;
|
||||
BdrvChild *child;
|
||||
Transaction *tran = tran_new();
|
||||
AioContext *old_context, *new_context = NULL;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
|
@ -5545,21 +5453,8 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
|||
assert(!bs_new->backing);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
|
||||
old_context = bdrv_get_aio_context(bs_top);
|
||||
bdrv_drained_begin(bs_top);
|
||||
|
||||
/*
|
||||
* bdrv_drained_begin() requires that only the AioContext of the drained
|
||||
* node is locked, and at this point it can still differ from the AioContext
|
||||
* of bs_top.
|
||||
*/
|
||||
new_context = bdrv_get_aio_context(bs_new);
|
||||
aio_context_release(old_context);
|
||||
aio_context_acquire(new_context);
|
||||
bdrv_drained_begin(bs_new);
|
||||
aio_context_release(new_context);
|
||||
aio_context_acquire(old_context);
|
||||
new_context = NULL;
|
||||
|
||||
bdrv_graph_wrlock();
|
||||
|
||||
|
@ -5571,18 +5466,6 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* bdrv_attach_child_noperm could change the AioContext of bs_top and
|
||||
* bs_new, but at least they are in the same AioContext now. This is the
|
||||
* AioContext that we need to lock for the rest of the function.
|
||||
*/
|
||||
new_context = bdrv_get_aio_context(bs_top);
|
||||
|
||||
if (old_context != new_context) {
|
||||
aio_context_release(old_context);
|
||||
aio_context_acquire(new_context);
|
||||
}
|
||||
|
||||
ret = bdrv_replace_node_noperm(bs_top, bs_new, true, tran, errp);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
|
@ -5598,11 +5481,6 @@ out:
|
|||
bdrv_drained_end(bs_top);
|
||||
bdrv_drained_end(bs_new);
|
||||
|
||||
if (new_context && old_context != new_context) {
|
||||
aio_context_release(new_context);
|
||||
aio_context_acquire(old_context);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -5697,12 +5575,8 @@ 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 */
|
||||
|
@ -7037,12 +6911,9 @@ void bdrv_activate_all(Error **errp)
|
|||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
int ret;
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
ret = bdrv_activate(bs, errp);
|
||||
aio_context_release(aio_context);
|
||||
if (ret < 0) {
|
||||
bdrv_next_cleanup(&it);
|
||||
return;
|
||||
|
@ -7137,20 +7008,10 @@ int bdrv_inactivate_all(void)
|
|||
BlockDriverState *bs = NULL;
|
||||
BdrvNextIterator it;
|
||||
int ret = 0;
|
||||
GSList *aio_ctxs = NULL, *ctx;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
|
||||
if (!g_slist_find(aio_ctxs, aio_context)) {
|
||||
aio_ctxs = g_slist_prepend(aio_ctxs, aio_context);
|
||||
aio_context_acquire(aio_context);
|
||||
}
|
||||
}
|
||||
|
||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
||||
/* Nodes with BDS parents are covered by recursion from the last
|
||||
* parent that gets inactivated. Don't inactivate them a second
|
||||
|
@ -7161,17 +7022,10 @@ int bdrv_inactivate_all(void)
|
|||
ret = bdrv_inactivate_recurse(bs);
|
||||
if (ret < 0) {
|
||||
bdrv_next_cleanup(&it);
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
for (ctx = aio_ctxs; ctx != NULL; ctx = ctx->next) {
|
||||
AioContext *aio_context = ctx->data;
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
g_slist_free(aio_ctxs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -7257,11 +7111,8 @@ void bdrv_unref(BlockDriverState *bs)
|
|||
static void bdrv_schedule_unref_bh(void *opaque)
|
||||
{
|
||||
BlockDriverState *bs = opaque;
|
||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
bdrv_unref(bs);
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -7398,8 +7249,6 @@ 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);
|
||||
|
@ -7549,7 +7398,6 @@ 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)
|
||||
|
@ -7585,29 +7433,12 @@ void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx)
|
|||
|
||||
void coroutine_fn bdrv_co_lock(BlockDriverState *bs)
|
||||
{
|
||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||
|
||||
/* In the main thread, bs->aio_context won't change concurrently */
|
||||
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
|
||||
|
||||
/*
|
||||
* We're in coroutine context, so we already hold the lock of the main
|
||||
* loop AioContext. Don't lock it twice to avoid deadlocks.
|
||||
*/
|
||||
assert(qemu_in_coroutine());
|
||||
if (ctx != qemu_get_aio_context()) {
|
||||
aio_context_acquire(ctx);
|
||||
}
|
||||
/* TODO removed in next patch */
|
||||
}
|
||||
|
||||
void coroutine_fn bdrv_co_unlock(BlockDriverState *bs)
|
||||
{
|
||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||
|
||||
assert(qemu_in_coroutine());
|
||||
if (ctx != qemu_get_aio_context()) {
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
/* TODO removed in next patch */
|
||||
}
|
||||
|
||||
static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
|
||||
|
@ -7728,21 +7559,8 @@ static void bdrv_set_aio_context_commit(void *opaque)
|
|||
BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque;
|
||||
BlockDriverState *bs = (BlockDriverState *) state->bs;
|
||||
AioContext *new_context = state->new_ctx;
|
||||
AioContext *old_context = bdrv_get_aio_context(bs);
|
||||
|
||||
/*
|
||||
* Take the old AioContex when detaching it from bs.
|
||||
* At this point, new_context lock is already acquired, and we are now
|
||||
* also taking old_context. This is safe as long as bdrv_detach_aio_context
|
||||
* does not call AIO_POLL_WHILE().
|
||||
*/
|
||||
if (old_context != qemu_get_aio_context()) {
|
||||
aio_context_acquire(old_context);
|
||||
}
|
||||
bdrv_detach_aio_context(bs);
|
||||
if (old_context != qemu_get_aio_context()) {
|
||||
aio_context_release(old_context);
|
||||
}
|
||||
bdrv_attach_aio_context(bs, new_context);
|
||||
}
|
||||
|
||||
|
@ -7827,7 +7645,6 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
|||
Transaction *tran;
|
||||
GHashTable *visited;
|
||||
int ret;
|
||||
AioContext *old_context = bdrv_get_aio_context(bs);
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
/*
|
||||
|
@ -7857,34 +7674,7 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release old AioContext, it won't be needed anymore, as all
|
||||
* bdrv_drained_begin() have been called already.
|
||||
*/
|
||||
if (qemu_get_aio_context() != old_context) {
|
||||
aio_context_release(old_context);
|
||||
}
|
||||
|
||||
/*
|
||||
* Acquire new AioContext since bdrv_drained_end() is going to be called
|
||||
* after we switched all nodes in the new AioContext, and the function
|
||||
* assumes that the lock of the bs is always taken.
|
||||
*/
|
||||
if (qemu_get_aio_context() != ctx) {
|
||||
aio_context_acquire(ctx);
|
||||
}
|
||||
|
||||
tran_commit(tran);
|
||||
|
||||
if (qemu_get_aio_context() != ctx) {
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
|
||||
/* Re-acquire the old AioContext, since the caller takes and releases it. */
|
||||
if (qemu_get_aio_context() != old_context) {
|
||||
aio_context_acquire(old_context);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -8006,7 +7796,6 @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
|
|||
const char *node_name, Error **errp)
|
||||
{
|
||||
BlockDriverState *to_replace_bs = bdrv_find_node(node_name);
|
||||
AioContext *aio_context;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
|
@ -8015,12 +7804,8 @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
aio_context = bdrv_get_aio_context(to_replace_bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
if (bdrv_op_is_blocked(to_replace_bs, BLOCK_OP_TYPE_REPLACE, errp)) {
|
||||
to_replace_bs = NULL;
|
||||
goto out;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We don't want arbitrary node of the BDS chain to be replaced only the top
|
||||
|
@ -8033,12 +7818,9 @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
|
|||
"because it cannot be guaranteed that doing so would not "
|
||||
"lead to an abrupt change of visible data",
|
||||
node_name, parent_bs->node_name);
|
||||
to_replace_bs = NULL;
|
||||
goto out;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
return to_replace_bs;
|
||||
}
|
||||
|
||||
|
|
|
@ -429,7 +429,6 @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
|
|||
{
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
AioContext *ctx;
|
||||
uint64_t perm = 0;
|
||||
uint64_t shared = BLK_PERM_ALL;
|
||||
|
||||
|
@ -459,23 +458,18 @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
|
|||
shared = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
|
||||
}
|
||||
|
||||
aio_context_acquire(qemu_get_aio_context());
|
||||
bs = bdrv_open(filename, reference, options, flags, errp);
|
||||
aio_context_release(qemu_get_aio_context());
|
||||
if (!bs) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* bdrv_open() could have moved bs to a different AioContext */
|
||||
ctx = bdrv_get_aio_context(bs);
|
||||
blk = blk_new(bdrv_get_aio_context(bs), perm, shared);
|
||||
blk->perm = perm;
|
||||
blk->shared_perm = shared;
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
blk_insert_bs(blk, bs, errp);
|
||||
bdrv_unref(bs);
|
||||
aio_context_release(ctx);
|
||||
|
||||
if (!blk->root) {
|
||||
blk_unref(blk);
|
||||
|
@ -577,13 +571,9 @@ void blk_remove_all_bs(void)
|
|||
GLOBAL_STATE_CODE();
|
||||
|
||||
while ((blk = blk_all_next(blk)) != NULL) {
|
||||
AioContext *ctx = blk_get_aio_context(blk);
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
if (blk->root) {
|
||||
blk_remove_bs(blk);
|
||||
}
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2736,20 +2726,16 @@ int blk_commit_all(void)
|
|||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
while ((blk = blk_all_next(blk)) != NULL) {
|
||||
AioContext *aio_context = blk_get_aio_context(blk);
|
||||
BlockDriverState *unfiltered_bs = bdrv_skip_filters(blk_bs(blk));
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
if (blk_is_inserted(blk) && bdrv_cow_child(unfiltered_bs)) {
|
||||
int ret;
|
||||
|
||||
ret = bdrv_commit(unfiltered_bs);
|
||||
if (ret < 0) {
|
||||
aio_context_release(aio_context);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -412,7 +412,6 @@ 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);
|
||||
|
@ -435,15 +434,11 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
|
|||
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
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) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
s->on_cbw_error = opts->has_on_cbw_error ? opts->on_cbw_error :
|
||||
|
@ -461,24 +456,21 @@ 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: ");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cluster_size = block_copy_cluster_size(s->bcs);
|
||||
|
||||
s->done_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp);
|
||||
if (!s->done_bitmap) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
}
|
||||
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) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
}
|
||||
bdrv_disable_dirty_bitmap(s->access_bitmap);
|
||||
bdrv_dirty_bitmap_merge_internal(s->access_bitmap,
|
||||
|
@ -487,11 +479,7 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
|
|||
|
||||
qemu_co_mutex_init(&s->lock);
|
||||
QLIST_INIT(&s->frozen_read_reqs);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
aio_context_release(ctx);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cbw_close(BlockDriverState *bs)
|
||||
|
|
|
@ -114,7 +114,6 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
|
|||
}
|
||||
|
||||
ctx = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(ctx);
|
||||
|
||||
if (export->iothread) {
|
||||
IOThread *iothread;
|
||||
|
@ -133,8 +132,6 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
|
|||
set_context_errp = fixed_iothread ? errp : NULL;
|
||||
ret = bdrv_try_change_aio_context(bs, new_ctx, NULL, set_context_errp);
|
||||
if (ret == 0) {
|
||||
aio_context_release(ctx);
|
||||
aio_context_acquire(new_ctx);
|
||||
ctx = new_ctx;
|
||||
} else if (fixed_iothread) {
|
||||
goto fail;
|
||||
|
@ -191,8 +188,6 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
|
|||
assert(exp->blk != NULL);
|
||||
|
||||
QLIST_INSERT_HEAD(&block_exports, exp, next);
|
||||
|
||||
aio_context_release(ctx);
|
||||
return exp;
|
||||
|
||||
fail:
|
||||
|
@ -200,7 +195,6 @@ fail:
|
|||
blk_set_dev_ops(blk, NULL, NULL);
|
||||
blk_unref(blk);
|
||||
}
|
||||
aio_context_release(ctx);
|
||||
if (exp) {
|
||||
g_free(exp->id);
|
||||
g_free(exp);
|
||||
|
@ -218,9 +212,6 @@ void blk_exp_ref(BlockExport *exp)
|
|||
static void blk_exp_delete_bh(void *opaque)
|
||||
{
|
||||
BlockExport *exp = opaque;
|
||||
AioContext *aio_context = exp->ctx;
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
assert(exp->refcount == 0);
|
||||
QLIST_REMOVE(exp, next);
|
||||
|
@ -230,8 +221,6 @@ static void blk_exp_delete_bh(void *opaque)
|
|||
qapi_event_send_block_export_deleted(exp->id);
|
||||
g_free(exp->id);
|
||||
g_free(exp);
|
||||
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
void blk_exp_unref(BlockExport *exp)
|
||||
|
@ -249,22 +238,16 @@ void blk_exp_unref(BlockExport *exp)
|
|||
* connections and other internally held references start to shut down. When
|
||||
* the function returns, there may still be active references while the export
|
||||
* is in the process of shutting down.
|
||||
*
|
||||
* Acquires exp->ctx internally. Callers must *not* hold the lock.
|
||||
*/
|
||||
void blk_exp_request_shutdown(BlockExport *exp)
|
||||
{
|
||||
AioContext *aio_context = exp->ctx;
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
/*
|
||||
* If the user doesn't own the export any more, it is already shutting
|
||||
* down. We must not call .request_shutdown and decrease the refcount a
|
||||
* second time.
|
||||
*/
|
||||
if (!exp->user_owned) {
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
exp->drv->request_shutdown(exp);
|
||||
|
@ -272,9 +255,6 @@ void blk_exp_request_shutdown(BlockExport *exp)
|
|||
assert(exp->user_owned);
|
||||
exp->user_owned = false;
|
||||
blk_exp_unref(exp);
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
45
block/io.c
45
block/io.c
|
@ -294,8 +294,6 @@ static void bdrv_co_drain_bh_cb(void *opaque)
|
|||
BlockDriverState *bs = data->bs;
|
||||
|
||||
if (bs) {
|
||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(ctx);
|
||||
bdrv_dec_in_flight(bs);
|
||||
if (data->begin) {
|
||||
bdrv_do_drained_begin(bs, data->parent, data->poll);
|
||||
|
@ -303,7 +301,6 @@ static void bdrv_co_drain_bh_cb(void *opaque)
|
|||
assert(!data->poll);
|
||||
bdrv_do_drained_end(bs, data->parent);
|
||||
}
|
||||
aio_context_release(ctx);
|
||||
} else {
|
||||
assert(data->begin);
|
||||
bdrv_drain_all_begin();
|
||||
|
@ -320,8 +317,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
|
|||
{
|
||||
BdrvCoDrainData data;
|
||||
Coroutine *self = qemu_coroutine_self();
|
||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||
AioContext *co_ctx = qemu_coroutine_get_aio_context(self);
|
||||
|
||||
/* Calling bdrv_drain() from a BH ensures the current coroutine yields and
|
||||
* other coroutines run if they were queued by aio_co_enter(). */
|
||||
|
@ -340,17 +335,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
|
|||
bdrv_inc_in_flight(bs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Temporarily drop the lock across yield or we would get deadlocks.
|
||||
* bdrv_co_drain_bh_cb() reaquires the lock as needed.
|
||||
*
|
||||
* When we yield below, the lock for the current context will be
|
||||
* released, so if this is actually the lock that protects bs, don't drop
|
||||
* it a second time.
|
||||
*/
|
||||
if (ctx != co_ctx) {
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
replay_bh_schedule_oneshot_event(qemu_get_aio_context(),
|
||||
bdrv_co_drain_bh_cb, &data);
|
||||
|
||||
|
@ -358,11 +342,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
|
|||
/* If we are resumed from some other event (such as an aio completion or a
|
||||
* timer callback), it is a bug in the caller that should be fixed. */
|
||||
assert(data.done);
|
||||
|
||||
/* Reacquire the AioContext of bs if we dropped it */
|
||||
if (ctx != co_ctx) {
|
||||
aio_context_acquire(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent,
|
||||
|
@ -478,13 +457,12 @@ static bool bdrv_drain_all_poll(void)
|
|||
GLOBAL_STATE_CODE();
|
||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||
|
||||
/* bdrv_drain_poll() can't make changes to the graph and we are holding the
|
||||
* main AioContext lock, so iterating bdrv_next_all_states() is safe. */
|
||||
/*
|
||||
* bdrv_drain_poll() can't make changes to the graph and we hold the BQL,
|
||||
* so iterating bdrv_next_all_states() is safe.
|
||||
*/
|
||||
while ((bs = bdrv_next_all_states(bs))) {
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
result |= bdrv_drain_poll(bs, NULL, true);
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -525,11 +503,7 @@ void bdrv_drain_all_begin_nopoll(void)
|
|||
/* Quiesce all nodes, without polling in-flight requests yet. The graph
|
||||
* cannot change during this loop. */
|
||||
while ((bs = bdrv_next_all_states(bs))) {
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
bdrv_do_drained_begin(bs, NULL, false);
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,11 +562,7 @@ void bdrv_drain_all_end(void)
|
|||
}
|
||||
|
||||
while ((bs = bdrv_next_all_states(bs))) {
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
bdrv_do_drained_end(bs, NULL);
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
|
||||
|
@ -2368,15 +2338,10 @@ int bdrv_flush_all(void)
|
|||
}
|
||||
|
||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
int ret;
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
ret = bdrv_flush(bs);
|
||||
int ret = bdrv_flush(bs);
|
||||
if (ret < 0 && !result) {
|
||||
result = ret;
|
||||
}
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -662,7 +662,6 @@ static int mirror_exit_common(Job *job)
|
|||
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
|
||||
BlockJob *bjob = &s->common;
|
||||
MirrorBDSOpaque *bs_opaque;
|
||||
AioContext *replace_aio_context = NULL;
|
||||
BlockDriverState *src;
|
||||
BlockDriverState *target_bs;
|
||||
BlockDriverState *mirror_top_bs;
|
||||
|
@ -677,7 +676,6 @@ static int mirror_exit_common(Job *job)
|
|||
}
|
||||
s->prepared = true;
|
||||
|
||||
aio_context_acquire(qemu_get_aio_context());
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
|
||||
mirror_top_bs = s->mirror_top_bs;
|
||||
|
@ -742,11 +740,6 @@ static int mirror_exit_common(Job *job)
|
|||
}
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
|
||||
if (s->to_replace) {
|
||||
replace_aio_context = bdrv_get_aio_context(s->to_replace);
|
||||
aio_context_acquire(replace_aio_context);
|
||||
}
|
||||
|
||||
if (s->should_complete && !abort) {
|
||||
BlockDriverState *to_replace = s->to_replace ?: src;
|
||||
bool ro = bdrv_is_read_only(to_replace);
|
||||
|
@ -785,9 +778,6 @@ static int mirror_exit_common(Job *job)
|
|||
error_free(s->replace_blocker);
|
||||
bdrv_unref(s->to_replace);
|
||||
}
|
||||
if (replace_aio_context) {
|
||||
aio_context_release(replace_aio_context);
|
||||
}
|
||||
g_free(s->replaces);
|
||||
|
||||
/*
|
||||
|
@ -811,8 +801,6 @@ static int mirror_exit_common(Job *job)
|
|||
bdrv_unref(mirror_top_bs);
|
||||
bdrv_unref(src);
|
||||
|
||||
aio_context_release(qemu_get_aio_context());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1191,24 +1179,17 @@ static void mirror_complete(Job *job, Error **errp)
|
|||
|
||||
/* block all operations on to_replace bs */
|
||||
if (s->replaces) {
|
||||
AioContext *replace_aio_context;
|
||||
|
||||
s->to_replace = bdrv_find_node(s->replaces);
|
||||
if (!s->to_replace) {
|
||||
error_setg(errp, "Node name '%s' not found", s->replaces);
|
||||
return;
|
||||
}
|
||||
|
||||
replace_aio_context = bdrv_get_aio_context(s->to_replace);
|
||||
aio_context_acquire(replace_aio_context);
|
||||
|
||||
/* TODO Translate this into child freeze system. */
|
||||
error_setg(&s->replace_blocker,
|
||||
"block device is in use by block-job-complete");
|
||||
bdrv_op_block_all(s->to_replace, s->replace_blocker);
|
||||
bdrv_ref(s->to_replace);
|
||||
|
||||
aio_context_release(replace_aio_context);
|
||||
}
|
||||
|
||||
s->should_complete = true;
|
||||
|
|
|
@ -95,7 +95,6 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
|
|||
{
|
||||
BlockDriverState *bs;
|
||||
BdrvDirtyBitmap *bitmap;
|
||||
AioContext *aio_context;
|
||||
|
||||
if (!name || name[0] == '\0') {
|
||||
error_setg(errp, "Bitmap name cannot be empty");
|
||||
|
@ -107,14 +106,11 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
|
|||
return;
|
||||
}
|
||||
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
if (has_granularity) {
|
||||
if (granularity < 512 || !is_power_of_2(granularity)) {
|
||||
error_setg(errp, "Granularity must be power of 2 "
|
||||
"and at least 512");
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* Default to cluster size, if available: */
|
||||
|
@ -132,12 +128,12 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
|
|||
if (persistent &&
|
||||
!bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
|
||||
{
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
|
||||
if (bitmap == NULL) {
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
|
@ -145,9 +141,6 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
|
|||
}
|
||||
|
||||
bdrv_dirty_bitmap_set_persistence(bitmap, persistent);
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
|
||||
|
@ -157,7 +150,6 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
|
|||
{
|
||||
BlockDriverState *bs;
|
||||
BdrvDirtyBitmap *bitmap;
|
||||
AioContext *aio_context;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
|
@ -166,19 +158,14 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO,
|
||||
errp)) {
|
||||
aio_context_release(aio_context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bdrv_dirty_bitmap_get_persistence(bitmap) &&
|
||||
bdrv_remove_persistent_dirty_bitmap(bs, name, errp) < 0)
|
||||
{
|
||||
aio_context_release(aio_context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -190,7 +177,6 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
|
|||
*bitmap_bs = bs;
|
||||
}
|
||||
|
||||
aio_context_release(aio_context);
|
||||
return release ? NULL : bitmap;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,6 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
|
|||
const char *id = qdict_get_str(qdict, "id");
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
Error *local_err = NULL;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
@ -168,14 +167,10 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
|
|||
return;
|
||||
}
|
||||
|
||||
aio_context = blk_get_aio_context(blk);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
bs = blk_bs(blk);
|
||||
if (bs) {
|
||||
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
|
||||
error_report_err(local_err);
|
||||
aio_context_release(aio_context);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -196,8 +191,6 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
|
|||
} else {
|
||||
blk_unref(blk);
|
||||
}
|
||||
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
void hmp_commit(Monitor *mon, const QDict *qdict)
|
||||
|
@ -213,7 +206,6 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
|
|||
ret = blk_commit_all();
|
||||
} else {
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
|
||||
blk = blk_by_name(device);
|
||||
if (!blk) {
|
||||
|
@ -222,18 +214,13 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
|
|||
}
|
||||
|
||||
bs = bdrv_skip_implicit_filters(blk_bs(blk));
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
if (!blk_is_available(blk)) {
|
||||
error_report("Device '%s' has no medium", device);
|
||||
aio_context_release(aio_context);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = bdrv_commit(bs);
|
||||
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
if (ret < 0) {
|
||||
error_report("'commit' error for '%s': %s", device, strerror(-ret));
|
||||
|
@ -560,7 +547,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
|
|||
BlockBackend *blk = NULL;
|
||||
BlockDriverState *bs = NULL;
|
||||
BlockBackend *local_blk = NULL;
|
||||
AioContext *ctx = NULL;
|
||||
bool qdev = qdict_get_try_bool(qdict, "qdev", false);
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
const char *command = qdict_get_str(qdict, "command");
|
||||
|
@ -582,9 +568,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
|
|||
}
|
||||
}
|
||||
|
||||
ctx = blk ? blk_get_aio_context(blk) : bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(ctx);
|
||||
|
||||
if (bs) {
|
||||
blk = local_blk = blk_new(bdrv_get_aio_context(bs), 0, BLK_PERM_ALL);
|
||||
ret = blk_insert_bs(blk, bs, &err);
|
||||
|
@ -622,11 +605,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
|
|||
|
||||
fail:
|
||||
blk_unref(local_blk);
|
||||
|
||||
if (ctx) {
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
|
@ -882,7 +860,6 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
|||
int nb_sns, i;
|
||||
int total;
|
||||
int *global_snapshots;
|
||||
AioContext *aio_context;
|
||||
|
||||
typedef struct SnapshotEntry {
|
||||
QEMUSnapshotInfo sn;
|
||||
|
@ -909,11 +886,8 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
|||
error_report_err(err);
|
||||
return;
|
||||
}
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
nb_sns = bdrv_snapshot_list(bs, &sn_tab);
|
||||
aio_context_release(aio_context);
|
||||
|
||||
if (nb_sns < 0) {
|
||||
monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
|
||||
|
@ -924,9 +898,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
|||
int bs1_nb_sns = 0;
|
||||
ImageEntry *ie;
|
||||
SnapshotEntry *se;
|
||||
AioContext *ctx = bdrv_get_aio_context(bs1);
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
if (bdrv_can_snapshot(bs1)) {
|
||||
sn = NULL;
|
||||
bs1_nb_sns = bdrv_snapshot_list(bs1, &sn);
|
||||
|
@ -944,7 +916,6 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
|||
}
|
||||
g_free(sn);
|
||||
}
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
|
||||
if (no_snapshot) {
|
||||
|
|
|
@ -174,7 +174,6 @@ blockdev_remove_medium(const char *device, const char *id, Error **errp)
|
|||
{
|
||||