diff mbox

[RFC,09/12] block: Add bdrv_co_readv() and bdrv_co_writev()

Message ID 1295688567-25496-10-git-send-email-stefanha@linux.vnet.ibm.com
State New
Headers show

Commit Message

Stefan Hajnoczi Jan. 22, 2011, 9:29 a.m. UTC
Add coroutine versions of the bdrv_aio_readv() and bdrv_aio_writev()
functions.  The coroutine version doesn't take a callback and simply
returns the error value.  Behind the scenes they are implemented using
bdrv_aio_readv() and bdrv_aio_writev().

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 block.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 block.h |    7 +++++++
 2 files changed, 58 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/block.c b/block.c
index ff2795b..ecb6538 100644
--- a/block.c
+++ b/block.c
@@ -2614,6 +2614,57 @@  void qemu_aio_release(void *p)
 }
 
 /**************************************************************/
+/* I/O for coroutines */
+
+typedef struct CoroutineIOCompletion {
+    Coroutine *coroutine;
+    int ret;
+} CoroutineIOCompletion;
+
+static void bdrv_co_complete(void *opaque, int ret)
+{
+    CoroutineIOCompletion *co = opaque;
+
+    co->ret = ret;
+    qemu_coroutine_enter(co->coroutine, NULL);
+}
+
+static int coroutine_fn bdrv_co_io(BlockDriverState *bs, int64_t sector_num,
+                                   QEMUIOVector *iov, int nb_sectors,
+                                   int is_write)
+{
+    CoroutineIOCompletion co = {
+        .coroutine = qemu_coroutine_self(),
+    };
+    BlockDriverAIOCB *acb;
+
+    if (is_write) {
+        acb = bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
+                              bdrv_co_complete, &co);
+    } else {
+        acb = bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
+                             bdrv_co_complete, &co);
+    }
+    if (!acb) {
+        return -EIO;
+    }
+    qemu_coroutine_yield(NULL);
+    return co.ret;
+}
+
+int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
+                               QEMUIOVector *iov, int nb_sectors)
+{
+    return bdrv_co_io(bs, sector_num, iov, nb_sectors, 0);
+}
+
+int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
+                                QEMUIOVector *iov, int nb_sectors)
+{
+    return bdrv_co_io(bs, sector_num, iov, nb_sectors, 1);
+}
+
+/**************************************************************/
 /* removable device support */
 
 /**
diff --git a/block.h b/block.h
index f923add..472e3d4 100644
--- a/block.h
+++ b/block.h
@@ -4,6 +4,7 @@ 
 #include "qemu-aio.h"
 #include "qemu-common.h"
 #include "qemu-option.h"
+#include "qemu-coroutine.h"
 #include "qobject.h"
 
 /* block.c */
@@ -120,6 +121,12 @@  BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
 				 BlockDriverCompletionFunc *cb, void *opaque);
 void bdrv_aio_cancel(BlockDriverAIOCB *acb);
 
+/* block I/O for coroutines */
+int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
+                               QEMUIOVector *iov, int nb_sectors);
+int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
+                                QEMUIOVector *iov, int nb_sectors);
+
 typedef struct BlockRequest {
     /* Fields to be filled by multiwrite caller */
     int64_t sector;