Commit bcdc1857 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Kevin Wolf
Browse files

aio: return "AIO in progress" state from qemu_aio_wait



The definition of when qemu_aio_flush should loop is much simpler
than it looks.  It just has to call qemu_aio_wait until it makes
no progress and all flush callbacks return false.  qemu_aio_wait
is the logical place to tell the caller about this.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent bafbd6a1
Loading
Loading
Loading
Loading
+18 −26
Original line number Diff line number Diff line
@@ -99,41 +99,26 @@ int qemu_aio_set_fd_handler(int fd,

void qemu_aio_flush(void)
{
    AioHandler *node;
    int ret;

    do {
        ret = 0;

	/*
	 * If there are pending emulated aio start them now so flush
	 * will be able to return 1.
	 */
        qemu_aio_wait();

        QLIST_FOREACH(node, &aio_handlers, node) {
            if (node->io_flush) {
                ret |= node->io_flush(node->opaque);
            }
        }
    } while (qemu_bh_poll() || ret > 0);
    while (qemu_aio_wait());
}

void qemu_aio_wait(void)
bool qemu_aio_wait(void)
{
    int ret;

    /*
     * If there are callbacks left that have been queued, we need to call then.
     * Return afterwards to avoid waiting needlessly in select().
     * Do not call select in this case, because it is possible that the caller
     * does not need a complete flush (as is the case for qemu_aio_wait loops).
     */
    if (qemu_bh_poll()) {
        return;
        return true;
    }

    do {
        AioHandler *node;
        fd_set rdfds, wrfds;
        bool busy;
        int max_fd = -1;

        walking_handlers = 1;
@@ -142,14 +127,18 @@ void qemu_aio_wait(void)
        FD_ZERO(&wrfds);

        /* fill fd sets */
        busy = false;
        QLIST_FOREACH(node, &aio_handlers, node) {
            /* If there aren't pending AIO operations, don't invoke callbacks.
             * Otherwise, if there are no AIO requests, qemu_aio_wait() would
             * wait indefinitely.
             */
            if (node->io_flush && node->io_flush(node->opaque) == 0)
            if (node->io_flush) {
                if (node->io_flush(node->opaque) == 0) {
                    continue;

                }
                busy = true;
            }
            if (!node->deleted && node->io_read) {
                FD_SET(node->fd, &rdfds);
                max_fd = MAX(max_fd, node->fd + 1);
@@ -163,8 +152,9 @@ void qemu_aio_wait(void)
        walking_handlers = 0;

        /* No AIO operations?  Get us out of here */
        if (max_fd == -1)
            break;
        if (!busy) {
            return false;
        }

        /* wait until next event */
        ret = select(max_fd, &rdfds, &wrfds, NULL, NULL);
@@ -204,4 +194,6 @@ void qemu_aio_wait(void)
            walking_handlers = 0;
        }
    } while (ret == 0);

    return true;
}
+4 −2
Original line number Diff line number Diff line
@@ -48,8 +48,10 @@ void qemu_aio_flush(void);
/* Wait for a single AIO completion to occur.  This function will wait
 * until a single AIO event has completed and it will ensure something
 * 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);
 * result of executing I/O completion or bh callbacks.
 *
 * Return whether there is still any pending AIO operation.  */
bool qemu_aio_wait(void);

/* Register a file descriptor and associated callbacks.  Behaves very similarly
 * to qemu_set_fd_handler2.  Unlike qemu_set_fd_handler2, these callbacks will