]> git.proxmox.com Git - qemu.git/blobdiff - linux-aio.c
qapi: modify visitor code generation for list iteration
[qemu.git] / linux-aio.c
index f53a08cb0c3e91af7d5bfa5193ae9a5a2387a0c6..bffa6cd0e393fe5b5b125ca8cdf0d3b795aad76b 100644 (file)
@@ -31,6 +31,7 @@ struct qemu_laiocb {
     struct iocb iocb;
     ssize_t ret;
     size_t nbytes;
+    QLIST_ENTRY(qemu_laiocb) node;
 };
 
 struct qemu_laio_state {
@@ -44,6 +45,29 @@ static inline ssize_t io_event_ret(struct io_event *ev)
     return (ssize_t)(((uint64_t)ev->res2 << 32) | ev->res);
 }
 
+/*
+ * Completes an AIO request (calls the callback and frees the ACB).
+ */
+static void qemu_laio_process_completion(struct qemu_laio_state *s,
+    struct qemu_laiocb *laiocb)
+{
+    int ret;
+
+    s->count--;
+
+    ret = laiocb->ret;
+    if (ret != -ECANCELED) {
+        if (ret == laiocb->nbytes)
+            ret = 0;
+        else if (ret >= 0)
+            ret = -EINVAL;
+
+        laiocb->common.cb(laiocb->common.opaque, ret);
+    }
+
+    qemu_aio_release(laiocb);
+}
+
 static void qemu_laio_completion_cb(void *opaque)
 {
     struct qemu_laio_state *s = opaque;
@@ -57,7 +81,7 @@ static void qemu_laio_completion_cb(void *opaque)
 
         do {
             ret = read(s->efd, &val, sizeof(val));
-        } while (ret == 1 && errno == EINTR);
+        } while (ret == -1 && errno == EINTR);
 
         if (ret == -1 && errno == EAGAIN)
             break;
@@ -74,19 +98,8 @@ static void qemu_laio_completion_cb(void *opaque)
             struct qemu_laiocb *laiocb =
                     container_of(iocb, struct qemu_laiocb, iocb);
 
-            s->count--;
-
-            ret = laiocb->ret = io_event_ret(&events[i]);
-            if (ret != -ECANCELED) {
-                if (ret == laiocb->nbytes)
-                    ret = 0;
-                else if (ret >= 0)
-                    ret = -EINVAL;
-
-                laiocb->common.cb(laiocb->common.opaque, ret);
-            }
-
-            qemu_aio_release(laiocb);
+            laiocb->ret = io_event_ret(&events[i]);
+            qemu_laio_process_completion(s, laiocb);
         }
     }
 }
@@ -159,6 +172,7 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
     case QEMU_AIO_READ:
         io_prep_preadv(iocbs, fd, qiov->iov, qiov->niov, offset);
        break;
+    /* Currently Linux kernel does not support other operations */
     default:
         fprintf(stderr, "%s: invalid AIO request type 0x%x.\n",
                         __func__, type);
@@ -182,7 +196,7 @@ void *laio_init(void)
 {
     struct qemu_laio_state *s;
 
-    s = qemu_mallocz(sizeof(*s));
+    s = g_malloc0(sizeof(*s));
     s->efd = eventfd(0, 0);
     if (s->efd == -1)
         goto out_free_state;
@@ -191,14 +205,14 @@ void *laio_init(void)
     if (io_setup(MAX_EVENTS, &s->ctx) != 0)
         goto out_close_efd;
 
-    qemu_aio_set_fd_handler(s->efd, qemu_laio_completion_cb,
-                            NULL, qemu_laio_flush_cb, s);
+    qemu_aio_set_fd_handler(s->efd, qemu_laio_completion_cb, NULL,
+        qemu_laio_flush_cb, NULL, s);
 
     return s;
 
 out_close_efd:
     close(s->efd);
 out_free_state:
-    qemu_free(s);
+    g_free(s);
     return NULL;
 }