]> git.proxmox.com Git - qemu.git/blobdiff - linux-aio.c
update VERSION for 1.1.2
[qemu.git] / linux-aio.c
index bffa6cd0e393fe5b5b125ca8cdf0d3b795aad76b..fa0fbf34aaaddd57eba83b3d3a56436552175e3b 100644 (file)
@@ -9,7 +9,6 @@
  */
 #include "qemu-common.h"
 #include "qemu-aio.h"
-#include "block_int.h"
 #include "block/raw-posix-aio.h"
 
 #include <sys/eventfd.h>
@@ -31,6 +30,8 @@ struct qemu_laiocb {
     struct iocb iocb;
     ssize_t ret;
     size_t nbytes;
+    QEMUIOVector *qiov;
+    bool is_read;
     QLIST_ENTRY(qemu_laiocb) node;
 };
 
@@ -57,10 +58,17 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s,
 
     ret = laiocb->ret;
     if (ret != -ECANCELED) {
-        if (ret == laiocb->nbytes)
+        if (ret == laiocb->nbytes) {
             ret = 0;
-        else if (ret >= 0)
-            ret = -EINVAL;
+        } else if (ret >= 0) {
+            /* Short reads mean EOF, pad with zeros. */
+            if (laiocb->is_read) {
+                qemu_iovec_memset_skip(laiocb->qiov, 0,
+                    laiocb->qiov->size - ret, ret);
+            } else {
+                ret = -EINVAL;
+            }
+        }
 
         laiocb->common.cb(laiocb->common.opaque, ret);
     }
@@ -157,11 +165,11 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
     off_t offset = sector_num * 512;
 
     laiocb = qemu_aio_get(&laio_pool, bs, cb, opaque);
-    if (!laiocb)
-        return NULL;
     laiocb->nbytes = nb_sectors * 512;
     laiocb->ctx = s;
     laiocb->ret = -EINPROGRESS;
+    laiocb->is_read = (type == QEMU_AIO_READ);
+    laiocb->qiov = qiov;
 
     iocbs = &laiocb->iocb;
 
@@ -185,10 +193,10 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
         goto out_dec_count;
     return &laiocb->common;
 
-out_free_aiocb:
-    qemu_aio_release(laiocb);
 out_dec_count:
     s->count--;
+out_free_aiocb:
+    qemu_aio_release(laiocb);
     return NULL;
 }
 
@@ -206,7 +214,7 @@ void *laio_init(void)
         goto out_close_efd;
 
     qemu_aio_set_fd_handler(s->efd, qemu_laio_completion_cb, NULL,
-        qemu_laio_flush_cb, NULL, s);
+        qemu_laio_flush_cb, s);
 
     return s;