@@ -1211,7 +1211,7 @@ static char *bdrv_child_get_parent_desc(BdrvChild *c)
static void bdrv_child_cb_drained_begin(BdrvChild *child)
{
BlockDriverState *bs = child->opaque;
- bdrv_do_drained_begin_quiesce(bs, NULL, false);
+ bdrv_drained_begin_no_poll(bs);
}
static bool bdrv_child_cb_drained_poll(BdrvChild *child)
@@ -523,7 +523,7 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
}
}
-void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
+static void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
BdrvChild *parent, bool ignore_bds_parents)
{
IO_OR_GS_CODE();
@@ -587,6 +587,12 @@ void bdrv_subtree_drained_begin(BlockDriverState *bs)
bdrv_do_drained_begin(bs, true, NULL, false, true);
}
+void bdrv_drained_begin_no_poll(BlockDriverState *bs)
+{
+ IO_CODE();
+ bdrv_do_drained_begin(bs, false, NULL, false, false);
+}
+
/**
* This function does not poll, nor must any of its recursively called
* functions. The *drained_end_counter pointee will be incremented
@@ -226,6 +226,17 @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
int64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags);
+/**
+ * bdrv_drained_begin_no_poll:
+ *
+ * Quiesces a BDS like bdrv_drained_begin(), but does not wait for already
+ * running requests to complete.
+ * Same as bdrv_drained_begin(), but do not poll for the subgraph to
+ * actually become unquiesced. Therefore, no graph changes will occur
+ * with this function.
+ */
+void bdrv_drained_begin_no_poll(BlockDriverState *bs);
+
/**
* bdrv_drained_end_no_poll:
*
@@ -332,15 +343,6 @@ bool bdrv_drain_poll(BlockDriverState *bs, bool recursive,
*/
void bdrv_drained_begin(BlockDriverState *bs);
-/**
- * bdrv_do_drained_begin_quiesce:
- *
- * Quiesces a BDS like bdrv_drained_begin(), but does not wait for already
- * running requests to complete.
- */
-void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
- BdrvChild *parent, bool ignore_bds_parents);
-
/**
* Like bdrv_drained_begin, but recursively begins a quiesced section for
* exclusive access to all child nodes as well.
Using bdrv_do_drained_begin_quiesce() in bdrv_child_cb_drained_begin() is not a good idea: the callback might be called when running a drain in a coroutine, and bdrv_drained_begin_poll() does not handle that case, resulting in assertion failure. Instead, bdrv_do_drained_begin with no recursion and poll will accomplish the same thing (invoking bdrv_do_drained_begin_quiesce) but will firstly check if we are already in a coroutine, and exit from that via bdrv_co_yield_to_drain(). Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> --- block.c | 2 +- block/io.c | 8 +++++++- include/block/block-io.h | 20 +++++++++++--------- 3 files changed, 19 insertions(+), 11 deletions(-)