Message ID | 1334140821-16247-4-git-send-email-kwolf@redhat.com |
---|---|
State | New |
Headers | show |
Il 11/04/2012 12:40, Kevin Wolf ha scritto: > @@ -816,6 +816,8 @@ void bdrv_close(BlockDriverState *bs) > if (bs->job) { > block_job_cancel_sync(bs->job); > } > + bdrv_drain_all(); Actually the bdrv_drain_all needs to go first. This is because block_job_cancel_sync guarantees to exit only after the block job's own I/O has finished, *but* it needs to see all I/O from the guest. Paolo
diff --git a/block.c b/block.c index c0c90f0..4b96654 100644 --- a/block.c +++ b/block.c @@ -816,6 +816,8 @@ void bdrv_close(BlockDriverState *bs) if (bs->job) { block_job_cancel_sync(bs->job); } + bdrv_drain_all(); + if (bs == bs_snapshots) { bs_snapshots = NULL; }
If an AIO request is in flight that refers to a BlockDriverState that has been closed and possibly even freed, more or less anything could happen. I have seen segfaults, -EBADF return values and qcow2 sometimes actually catches the situation in bdrv_close() and abort()s. Signed-off-by: Kevin Wolf <kwolf@redhat.com> --- block.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)