Skip to content

Commit

Permalink
block: Drain individual nodes during reopen
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
kevmw committed Dec 15, 2022
1 parent 2e11786 commit d22933a
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 26 deletions.
16 changes: 9 additions & 7 deletions block.c
Expand Up @@ -4173,7 +4173,7 @@ static bool bdrv_recurse_has_child(BlockDriverState *bs,
* returns a pointer to bs_queue, which is either the newly allocated
* 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.
*/
Expand All @@ -4195,12 +4195,10 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
int flags;
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();

bdrv_drained_begin(bs);

if (bs_queue == NULL) {
bs_queue = g_new0(BlockReopenQueue, 1);
QTAILQ_INIT(bs_queue);
Expand Down Expand Up @@ -4351,6 +4349,12 @@ 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);
Expand Down Expand Up @@ -4494,7 +4498,6 @@ int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,

GLOBAL_STATE_CODE();

bdrv_subtree_drained_begin(bs);
queue = bdrv_reopen_queue(NULL, bs, opts, keep_old_opts);

if (ctx != qemu_get_aio_context()) {
Expand All @@ -4505,7 +4508,6 @@ int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
if (ctx != qemu_get_aio_context()) {
aio_context_acquire(ctx);
}
bdrv_subtree_drained_end(bs);

return ret;
}
Expand Down
6 changes: 0 additions & 6 deletions block/replication.c
Expand Up @@ -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);
}

bdrv_subtree_drained_begin(hidden_disk->bs);
bdrv_subtree_drained_begin(secondary_disk->bs);

if (s->orig_hidden_read_only) {
QDict *opts = qdict_new();
qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !writable);
Expand All @@ -401,9 +398,6 @@ static void reopen_backing_file(BlockDriverState *bs, bool writable,
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)
Expand Down
13 changes: 0 additions & 13 deletions blockdev.c
Expand Up @@ -3515,8 +3515,6 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
{
BlockReopenQueue *queue = NULL;
GSList *drained = NULL;
GSList *p;

/* Add each one of the BDS that we want to reopen to the queue */
for (; reopen_list != NULL; reopen_list = reopen_list->next) {
Expand Down Expand Up @@ -3553,9 +3551,7 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);

bdrv_subtree_drained_begin(bs);
queue = bdrv_reopen_queue(queue, bs, qdict, false);
drained = g_slist_prepend(drained, bs);

aio_context_release(ctx);
}
Expand All @@ -3566,15 +3562,6 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)

fail:
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)
Expand Down

0 comments on commit d22933a

Please sign in to comment.