mirror of https://gitee.com/openkylin/qemu.git
block: Make bdrv_drain() use bdrv_drained_begin/end()
Until now, bdrv_drained_begin() used bdrv_drain() internally to drain the queue. This is kind of backwards and caused quiescing code to be duplicated because bdrv_drained_begin() had to ensure that no new requests come in even after bdrv_drain() returns, whereas bdrv_drain() had to have them because it could be called from other places. Instead move the bdrv_drain() code to bdrv_drained_begin() and make bdrv_drain() a simple wrapper around bdrv_drained_begin/end(). Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com>
This commit is contained in:
parent
e9740bc6d4
commit
6820643fdb
69
block/io.c
69
block/io.c
|
@ -225,6 +225,34 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
|
|||
assert(data.done);
|
||||
}
|
||||
|
||||
void bdrv_drained_begin(BlockDriverState *bs)
|
||||
{
|
||||
if (!bs->quiesce_counter++) {
|
||||
aio_disable_external(bdrv_get_aio_context(bs));
|
||||
bdrv_parent_drained_begin(bs);
|
||||
}
|
||||
|
||||
bdrv_io_unplugged_begin(bs);
|
||||
bdrv_drain_recurse(bs);
|
||||
if (qemu_in_coroutine()) {
|
||||
bdrv_co_yield_to_drain(bs);
|
||||
} else {
|
||||
bdrv_drain_poll(bs);
|
||||
}
|
||||
bdrv_io_unplugged_end(bs);
|
||||
}
|
||||
|
||||
void bdrv_drained_end(BlockDriverState *bs)
|
||||
{
|
||||
assert(bs->quiesce_counter > 0);
|
||||
if (--bs->quiesce_counter > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
bdrv_parent_drained_end(bs);
|
||||
aio_enable_external(bdrv_get_aio_context(bs));
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for pending requests to complete on a single BlockDriverState subtree,
|
||||
* and suspend block driver's internal I/O until next request arrives.
|
||||
|
@ -238,26 +266,15 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
|
|||
*/
|
||||
void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
|
||||
{
|
||||
bdrv_parent_drained_begin(bs);
|
||||
bdrv_io_unplugged_begin(bs);
|
||||
bdrv_drain_recurse(bs);
|
||||
bdrv_co_yield_to_drain(bs);
|
||||
bdrv_io_unplugged_end(bs);
|
||||
bdrv_parent_drained_end(bs);
|
||||
assert(qemu_in_coroutine());
|
||||
bdrv_drained_begin(bs);
|
||||
bdrv_drained_end(bs);
|
||||
}
|
||||
|
||||
void bdrv_drain(BlockDriverState *bs)
|
||||
{
|
||||
bdrv_parent_drained_begin(bs);
|
||||
bdrv_io_unplugged_begin(bs);
|
||||
bdrv_drain_recurse(bs);
|
||||
if (qemu_in_coroutine()) {
|
||||
bdrv_co_yield_to_drain(bs);
|
||||
} else {
|
||||
bdrv_drain_poll(bs);
|
||||
}
|
||||
bdrv_io_unplugged_end(bs);
|
||||
bdrv_parent_drained_end(bs);
|
||||
bdrv_drained_begin(bs);
|
||||
bdrv_drained_end(bs);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2541,23 +2558,3 @@ void bdrv_io_unplugged_end(BlockDriverState *bs)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bdrv_drained_begin(BlockDriverState *bs)
|
||||
{
|
||||
if (!bs->quiesce_counter++) {
|
||||
aio_disable_external(bdrv_get_aio_context(bs));
|
||||
}
|
||||
bdrv_parent_drained_begin(bs);
|
||||
bdrv_drain(bs);
|
||||
}
|
||||
|
||||
void bdrv_drained_end(BlockDriverState *bs)
|
||||
{
|
||||
bdrv_parent_drained_end(bs);
|
||||
|
||||
assert(bs->quiesce_counter > 0);
|
||||
if (--bs->quiesce_counter > 0) {
|
||||
return;
|
||||
}
|
||||
aio_enable_external(bdrv_get_aio_context(bs));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue