fix qemu_aio_flush

qemu_aio_wait by invoking the bh or one of the aio completion
callbacks, could end up submitting new pending aio, breaking the
invariant that qemu_aio_flush returns only when no pending aio is
outstanding (possibly a problem for migration as such).

Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Andrea Arcangeli 2009-06-15 13:52:27 +02:00 committed by Christoph Hellwig
parent e19252d32c
commit 986c28d655
2 changed files with 10 additions and 5 deletions

8
aio.c
View File

@ -103,11 +103,15 @@ void qemu_aio_flush(void)
do { do {
ret = 0; ret = 0;
/*
* If there are pending emulated aio start them now so flush
* will be able to return 1.
*/
qemu_aio_wait();
LIST_FOREACH(node, &aio_handlers, node) { LIST_FOREACH(node, &aio_handlers, node) {
ret |= node->io_flush(node->opaque); ret |= node->io_flush(node->opaque);
} }
qemu_aio_wait();
} while (ret > 0); } while (ret > 0);
} }

View File

@ -24,9 +24,10 @@ typedef int (AioFlushHandler)(void *opaque);
* outstanding AIO operations have been completed or cancelled. */ * outstanding AIO operations have been completed or cancelled. */
void qemu_aio_flush(void); void qemu_aio_flush(void);
/* Wait for a single AIO completion to occur. This function will until a /* Wait for a single AIO completion to occur. This function will wait
* single AIO opeartion has completed. It is intended to be used as a looping * until a single AIO event has completed and it will ensure something
* primative when simulating synchronous IO based on asynchronous IO. */ * has moved before returning. This can issue new pending aio as
* result of executing I/O completion or bh callbacks. */
void qemu_aio_wait(void); void qemu_aio_wait(void);
/* Register a file descriptor and associated callbacks. Behaves very similarly /* Register a file descriptor and associated callbacks. Behaves very similarly