block: Drain individual nodes during reopen
bdrv_reopen() and friends use subtree drains as a lazy way of covering all the nodes they touch. Turns out that this lazy way is a lot more complicated than just draining the nodes individually, even not accounting for the additional complexity in the drain mechanism itself. Simplify the code by switching to draining the individual nodes that are already managed in the BlockReopenQueue anyway. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20221118174110.55183-8-kwolf@redhat.com> Reviewed-by: Hanna Reitz <hreitz@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
2e117866d7
commit
d22933acd2
16
block.c
16
block.c
@ -4173,7 +4173,7 @@ static bool bdrv_recurse_has_child(BlockDriverState *bs,
|
|||||||
* returns a pointer to bs_queue, which is either the newly allocated
|
* returns a pointer to bs_queue, which is either the newly allocated
|
||||||
* bs_queue, or the existing bs_queue being used.
|
* bs_queue, or the existing bs_queue being used.
|
||||||
*
|
*
|
||||||
* bs must be drained between bdrv_reopen_queue() and bdrv_reopen_multiple().
|
* bs is drained here and undrained by bdrv_reopen_queue_free().
|
||||||
*
|
*
|
||||||
* To be called with bs->aio_context locked.
|
* To be called with bs->aio_context locked.
|
||||||
*/
|
*/
|
||||||
@ -4195,12 +4195,10 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
|||||||
int flags;
|
int flags;
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
|
|
||||||
/* Make sure that the caller remembered to use a drained section. This is
|
|
||||||
* important to avoid graph changes between the recursive queuing here and
|
|
||||||
* bdrv_reopen_multiple(). */
|
|
||||||
assert(bs->quiesce_counter > 0);
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
|
|
||||||
|
bdrv_drained_begin(bs);
|
||||||
|
|
||||||
if (bs_queue == NULL) {
|
if (bs_queue == NULL) {
|
||||||
bs_queue = g_new0(BlockReopenQueue, 1);
|
bs_queue = g_new0(BlockReopenQueue, 1);
|
||||||
QTAILQ_INIT(bs_queue);
|
QTAILQ_INIT(bs_queue);
|
||||||
@ -4351,6 +4349,12 @@ void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue)
|
|||||||
if (bs_queue) {
|
if (bs_queue) {
|
||||||
BlockReopenQueueEntry *bs_entry, *next;
|
BlockReopenQueueEntry *bs_entry, *next;
|
||||||
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, 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.explicit_options);
|
||||||
qobject_unref(bs_entry->state.options);
|
qobject_unref(bs_entry->state.options);
|
||||||
g_free(bs_entry);
|
g_free(bs_entry);
|
||||||
@ -4494,7 +4498,6 @@ int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
|
|||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
|
|
||||||
bdrv_subtree_drained_begin(bs);
|
|
||||||
queue = bdrv_reopen_queue(NULL, bs, opts, keep_old_opts);
|
queue = bdrv_reopen_queue(NULL, bs, opts, keep_old_opts);
|
||||||
|
|
||||||
if (ctx != qemu_get_aio_context()) {
|
if (ctx != qemu_get_aio_context()) {
|
||||||
@ -4505,7 +4508,6 @@ int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
|
|||||||
if (ctx != qemu_get_aio_context()) {
|
if (ctx != qemu_get_aio_context()) {
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
}
|
}
|
||||||
bdrv_subtree_drained_end(bs);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -374,9 +374,6 @@ static void reopen_backing_file(BlockDriverState *bs, bool writable,
|
|||||||
s->orig_secondary_read_only = bdrv_is_read_only(secondary_disk->bs);
|
s->orig_secondary_read_only = bdrv_is_read_only(secondary_disk->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bdrv_subtree_drained_begin(hidden_disk->bs);
|
|
||||||
bdrv_subtree_drained_begin(secondary_disk->bs);
|
|
||||||
|
|
||||||
if (s->orig_hidden_read_only) {
|
if (s->orig_hidden_read_only) {
|
||||||
QDict *opts = qdict_new();
|
QDict *opts = qdict_new();
|
||||||
qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !writable);
|
qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !writable);
|
||||||
@ -401,9 +398,6 @@ static void reopen_backing_file(BlockDriverState *bs, bool writable,
|
|||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bdrv_subtree_drained_end(hidden_disk->bs);
|
|
||||||
bdrv_subtree_drained_end(secondary_disk->bs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void backup_job_cleanup(BlockDriverState *bs)
|
static void backup_job_cleanup(BlockDriverState *bs)
|
||||||
|
13
blockdev.c
13
blockdev.c
@ -3515,8 +3515,6 @@ fail:
|
|||||||
void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
|
void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
|
||||||
{
|
{
|
||||||
BlockReopenQueue *queue = NULL;
|
BlockReopenQueue *queue = NULL;
|
||||||
GSList *drained = NULL;
|
|
||||||
GSList *p;
|
|
||||||
|
|
||||||
/* Add each one of the BDS that we want to reopen to the queue */
|
/* Add each one of the BDS that we want to reopen to the queue */
|
||||||
for (; reopen_list != NULL; reopen_list = reopen_list->next) {
|
for (; reopen_list != NULL; reopen_list = reopen_list->next) {
|
||||||
@ -3553,9 +3551,7 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
|
|||||||
ctx = bdrv_get_aio_context(bs);
|
ctx = bdrv_get_aio_context(bs);
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
|
|
||||||
bdrv_subtree_drained_begin(bs);
|
|
||||||
queue = bdrv_reopen_queue(queue, bs, qdict, false);
|
queue = bdrv_reopen_queue(queue, bs, qdict, false);
|
||||||
drained = g_slist_prepend(drained, bs);
|
|
||||||
|
|
||||||
aio_context_release(ctx);
|
aio_context_release(ctx);
|
||||||
}
|
}
|
||||||
@ -3566,15 +3562,6 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
bdrv_reopen_queue_free(queue);
|
bdrv_reopen_queue_free(queue);
|
||||||
for (p = drained; p; p = p->next) {
|
|
||||||
BlockDriverState *bs = p->data;
|
|
||||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
|
||||||
bdrv_subtree_drained_end(bs);
|
|
||||||
aio_context_release(ctx);
|
|
||||||
}
|
|
||||||
g_slist_free(drained);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void qmp_blockdev_del(const char *node_name, Error **errp)
|
void qmp_blockdev_del(const char *node_name, Error **errp)
|
||||||
|
Loading…
Reference in New Issue
Block a user