mirror of https://github.com/xemu-project/xemu.git
block: extract bdrv_drain_poll/bdrv_co_yield_to_drain from bdrv_drain/bdrv_co_drain
Do not call bdrv_drain_recurse twice in bdrv_co_drain. A small tweak to the logic in Fam's patch, which is harmless since no one implements bdrv_drain anyway. But better get it right. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Acked-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
a72f641407
commit
b6e84c97ed
35
block/io.c
35
block/io.c
|
@ -243,18 +243,30 @@ typedef struct {
|
||||||
bool done;
|
bool done;
|
||||||
} BdrvCoDrainData;
|
} BdrvCoDrainData;
|
||||||
|
|
||||||
|
static void bdrv_drain_poll(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
bool busy = true;
|
||||||
|
|
||||||
|
while (busy) {
|
||||||
|
/* Keep iterating */
|
||||||
|
bdrv_flush_io_queue(bs);
|
||||||
|
busy = bdrv_requests_pending(bs);
|
||||||
|
busy |= aio_poll(bdrv_get_aio_context(bs), busy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void bdrv_co_drain_bh_cb(void *opaque)
|
static void bdrv_co_drain_bh_cb(void *opaque)
|
||||||
{
|
{
|
||||||
BdrvCoDrainData *data = opaque;
|
BdrvCoDrainData *data = opaque;
|
||||||
Coroutine *co = data->co;
|
Coroutine *co = data->co;
|
||||||
|
|
||||||
qemu_bh_delete(data->bh);
|
qemu_bh_delete(data->bh);
|
||||||
bdrv_drain(data->bs);
|
bdrv_drain_poll(data->bs);
|
||||||
data->done = true;
|
data->done = true;
|
||||||
qemu_coroutine_enter(co, NULL);
|
qemu_coroutine_enter(co, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
|
static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BdrvCoDrainData data;
|
BdrvCoDrainData data;
|
||||||
|
|
||||||
|
@ -288,20 +300,19 @@ void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
|
||||||
* not depend on events in other AioContexts. In that case, use
|
* not depend on events in other AioContexts. In that case, use
|
||||||
* bdrv_drain_all() instead.
|
* bdrv_drain_all() instead.
|
||||||
*/
|
*/
|
||||||
|
void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
bdrv_drain_recurse(bs);
|
||||||
|
bdrv_co_yield_to_drain(bs);
|
||||||
|
}
|
||||||
|
|
||||||
void bdrv_drain(BlockDriverState *bs)
|
void bdrv_drain(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
bool busy = true;
|
|
||||||
|
|
||||||
bdrv_drain_recurse(bs);
|
bdrv_drain_recurse(bs);
|
||||||
if (qemu_in_coroutine()) {
|
if (qemu_in_coroutine()) {
|
||||||
bdrv_co_drain(bs);
|
bdrv_co_yield_to_drain(bs);
|
||||||
return;
|
} else {
|
||||||
}
|
bdrv_drain_poll(bs);
|
||||||
while (busy) {
|
|
||||||
/* Keep iterating */
|
|
||||||
bdrv_flush_io_queue(bs);
|
|
||||||
busy = bdrv_requests_pending(bs);
|
|
||||||
busy |= aio_poll(bdrv_get_aio_context(bs), busy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue