block: ignore_bds_parents parameter for drain functions
In the future, bdrv_drained_all_begin/end() will drain all invidiual
nodes separately rather than whole subtrees. This means that we don't
want to propagate the drain to all parents any more: If the parent is a
BDS, it will already be drained separately. Recursing to all parents is
unnecessary work and would make it an O(n²) operation.
Prepare the drain function for the changed drain_all by adding an
ignore_bds_parents parameter to the internal implementation that
prevents the propagation of the drain to BDS parents. We still (have to)
propagate it to non-BDS parents like BlockBackends or Jobs because those
are not drained separately.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
diff --git a/block.c b/block.c
index 50f8e3d..c8586f4 100644
--- a/block.c
+++ b/block.c
@@ -818,13 +818,13 @@
static void bdrv_child_cb_drained_begin(BdrvChild *child)
{
BlockDriverState *bs = child->opaque;
- bdrv_do_drained_begin_quiesce(bs, NULL);
+ bdrv_do_drained_begin_quiesce(bs, NULL, false);
}
static bool bdrv_child_cb_drained_poll(BdrvChild *child)
{
BlockDriverState *bs = child->opaque;
- return bdrv_drain_poll(bs, false, NULL);
+ return bdrv_drain_poll(bs, false, NULL, false);
}
static void bdrv_child_cb_drained_end(BdrvChild *child)
@@ -908,6 +908,7 @@
}
const BdrvChildRole child_file = {
+ .parent_is_bds = true,
.get_parent_desc = bdrv_child_get_parent_desc,
.inherit_options = bdrv_inherited_options,
.drained_begin = bdrv_child_cb_drained_begin,
@@ -933,6 +934,7 @@
}
const BdrvChildRole child_format = {
+ .parent_is_bds = true,
.get_parent_desc = bdrv_child_get_parent_desc,
.inherit_options = bdrv_inherited_fmt_options,
.drained_begin = bdrv_child_cb_drained_begin,
@@ -1051,6 +1053,7 @@
}
const BdrvChildRole child_backing = {
+ .parent_is_bds = true,
.get_parent_desc = bdrv_child_get_parent_desc,
.attach = bdrv_backing_attach,
.detach = bdrv_backing_detach,
@@ -4957,7 +4960,7 @@
AioContext *ctx = bdrv_get_aio_context(bs);
aio_disable_external(ctx);
- bdrv_parent_drained_begin(bs, NULL);
+ bdrv_parent_drained_begin(bs, NULL, false);
bdrv_drain(bs); /* ensure there are no in-flight requests */
while (aio_poll(ctx, false)) {
@@ -4971,7 +4974,7 @@
*/
aio_context_acquire(new_context);
bdrv_attach_aio_context(bs, new_context);
- bdrv_parent_drained_end(bs, NULL);
+ bdrv_parent_drained_end(bs, NULL, false);
aio_enable_external(ctx);
aio_context_release(new_context);
}