On 13/05/2015 19:28, Fam Zheng wrote: > We don't want new requests from guest, so block the operation around the > nested poll. > > Signed-off-by: Fam Zheng <f...@redhat.com> > --- > block/io.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/block/io.c b/block/io.c > index 1ce62c4..d369de3 100644 > --- a/block/io.c > +++ b/block/io.c > @@ -289,9 +289,15 @@ static bool bdrv_drain_one(BlockDriverState *bs) > */ > void bdrv_drain(BlockDriverState *bs) > { > + Error *blocker = NULL; > + > + error_setg(&blocker, "bdrv_drain in progress"); > + bdrv_op_block(bs, BLOCK_OP_TYPE_DEVICE_IO, blocker); > while (bdrv_drain_one(bs)) { > /* Keep iterating */ > } > + bdrv_op_unblock(bs, BLOCK_OP_TYPE_DEVICE_IO, blocker); > + error_free(blocker); > } > > /* > @@ -311,6 +317,9 @@ void bdrv_drain_all(void) > /* Always run first iteration so any pending completion BHs run */ > bool busy = true; > BlockDriverState *bs = NULL; > + Error *blocker = NULL; > + > + error_setg(&blocker, "bdrv_drain_all in progress"); > > while ((bs = bdrv_next(bs))) { > AioContext *aio_context = bdrv_get_aio_context(bs); > @@ -319,6 +328,7 @@ void bdrv_drain_all(void) > if (bs->job) { > block_job_pause(bs->job); > } > + bdrv_op_block(bs, BLOCK_OP_TYPE_DEVICE_IO, blocker); > aio_context_release(aio_context); > } > > @@ -343,8 +353,10 @@ void bdrv_drain_all(void) > if (bs->job) { > block_job_resume(bs->job); > } > + bdrv_op_unblock(bs, BLOCK_OP_TYPE_DEVICE_IO, blocker); > aio_context_release(aio_context); > } > + error_free(blocker); > } > > /** >
I think this isn't enough. It's the callers of bdrv_drain and bdrv_drain_all that need to block before drain and unblock before aio_context_release. Paolo