qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/6] virtio-blk: use generic vectored I/O APIs


From: Christoph Hellwig
Subject: [Qemu-devel] [PATCH 3/6] virtio-blk: use generic vectored I/O APIs
Date: Sat, 14 Mar 2009 20:28:49 +0100
User-agent: Mutt/1.3.28i

Use the generic bdrv_aio_readv/bdrv_aio_writev APIs instead of linearizing
buffers directly.  This enables using the future native preadv/pwritev
support.


Signed-off-by: Christoph Hellwig <address@hidden>

Index: qemu/hw/virtio-blk.c
===================================================================
--- qemu.orig/hw/virtio-blk.c   2009-03-10 16:14:37.000000000 +0100
+++ qemu/hw/virtio-blk.c        2009-03-11 03:03:43.000000000 +0100
@@ -36,7 +36,6 @@ typedef struct VirtIOBlockReq
     struct virtio_blk_inhdr *in;
     struct virtio_blk_outhdr *out;
     size_t size;
-    uint8_t *buffer;
     struct VirtIOBlockReq *next;
 } VirtIOBlockReq;
 
@@ -48,7 +47,6 @@ static void virtio_blk_req_complete(Virt
     virtqueue_push(s->vq, &req->elem, req->size + sizeof(*req->in));
     virtio_notify(&s->vdev, s->vq);
 
-    qemu_free(req->buffer);
     qemu_free(req);
 }
 
@@ -76,24 +74,7 @@ static void virtio_blk_rw_complete(void 
 {
     VirtIOBlockReq *req = opaque;
 
-    /* Copy read data to the guest */
-    if (!ret && !(req->out->type & VIRTIO_BLK_T_OUT)) {
-        size_t offset = 0;
-        int i;
-
-        for (i = 0; i < req->elem.in_num - 1; i++) {
-            size_t len;
-
-            /* Be pretty defensive wrt malicious guests */
-            len = MIN(req->elem.in_sg[i].iov_len,
-                      req->size - offset);
-
-            memcpy(req->elem.in_sg[i].iov_base,
-                   req->buffer + offset,
-                   len);
-            offset += len;
-        }
-    } else if (ret && (req->out->type & VIRTIO_BLK_T_OUT)) {
+    if (ret && (req->out->type & VIRTIO_BLK_T_OUT)) {
         if (virtio_blk_handle_write_error(req, -ret))
             return;
     }
@@ -122,39 +103,18 @@ static VirtIOBlockReq *virtio_blk_get_re
     return req;
 }
 
-static int virtio_blk_handle_write(VirtIOBlockReq *req)
+static void virtio_blk_handle_write(VirtIOBlockReq *req)
 {
-    if (!req->buffer) {
-        size_t offset = 0;
-        int i;
-
-        for (i = 1; i < req->elem.out_num; i++)
-            req->size += req->elem.out_sg[i].iov_len;
-
-        req->buffer = qemu_memalign(512, req->size);
-        if (req->buffer == NULL) {
-            qemu_free(req);
-            return -1;
-        }
-
-        /* We copy the data from the SG list to avoid splitting up the request.
-           This helps performance a lot until we can pass full sg lists as AIO
-           operations */
-        for (i = 1; i < req->elem.out_num; i++) {
-            size_t len;
-
-            len = MIN(req->elem.out_sg[i].iov_len,
-                    req->size - offset);
-            memcpy(req->buffer + offset,
-                    req->elem.out_sg[i].iov_base,
-                    len);
-            offset += len;
-        }
-    }
+    bdrv_aio_writev(req->dev->bs, req->out->sector, &req->elem.out_sg[0],
+                    req->elem.out_num, req->size / 512,
+                    virtio_blk_rw_complete, req);
+}
 
-    bdrv_aio_write(req->dev->bs, req->out->sector, req->buffer, req->size / 
512,
-            virtio_blk_rw_complete, req);
-    return 0;
+static void virtio_blk_handle_read(VirtIOBlockReq *req)
+{
+    bdrv_aio_readv(req->dev->bs, req->out->sector, &req->elem.in_sg[0],
+                   req->elem.in_num, req->size / 512,
+                   virtio_blk_rw_complete, req);
 }
 
 static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
@@ -187,23 +147,13 @@ static void virtio_blk_handle_output(Vir
             virtio_notify(vdev, vq);
             qemu_free(req);
         } else if (req->out->type & VIRTIO_BLK_T_OUT) {
-            if (virtio_blk_handle_write(req) < 0)
-                break;
+            for (i = 1; i < req->elem.out_num; i++)
+                req->size += req->elem.out_sg[i].iov_len;
+            virtio_blk_handle_write(req);
         } else {
             for (i = 0; i < req->elem.in_num - 1; i++)
                 req->size += req->elem.in_sg[i].iov_len;
-
-            req->buffer = qemu_memalign(512, req->size);
-            if (req->buffer == NULL) {
-                qemu_free(req);
-                break;
-            }
-
-            bdrv_aio_read(s->bs, req->out->sector,
-                          req->buffer,
-                          req->size / 512,
-                          virtio_blk_rw_complete,
-                          req);
+            virtio_blk_handle_read(req);
         }
     }
     /*




reply via email to

[Prev in Thread] Current Thread [Next in Thread]