qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 1/3] Add bdrv_aio_multiwrite


From: Kevin Wolf
Subject: [Qemu-devel] [PATCH 1/3] Add bdrv_aio_multiwrite
Date: Tue, 1 Sep 2009 15:51:50 +0200

Allows block drivers to handle multiple write requests at once. For drivers not
implementing bdrv_aio_multiwrite a trivial emulation is provided (just call
bdrv_aio_writev for each request).

Signed-off-by: Kevin Wolf <address@hidden>
---
 block.c     |   37 +++++++++++++++++++++++++++++++++++++
 block.h     |   15 +++++++++++++++
 block_int.h |    3 +++
 3 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 033957d..c154d78 100644
--- a/block.c
+++ b/block.c
@@ -1354,6 +1354,43 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, 
int64_t sector_num,
     return ret;
 }
 
+/*
+ * Submit multiple AIO write requests at once.
+ *
+ * On success, the function returns 0 and all requests in the reqs array have
+ * been submitted. In error case this function returns -1, and any of the
+ * requests may or may not be submitted yet. In particular, this means that the
+ * callback will be called for some of the requests, for others it won't. The
+ * caller must check the error field of the BlockRequest to wait for the right
+ * callbacks (if error != 0, no callback will be called).
+ *
+ * The implementation may modify the contents of the reqs array, e.g. to merge
+ * requests. However, the fields opaque and error are left unmodified as they
+ * are used to signal failure for a single request to the caller.
+ */
+int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
+{
+    BlockDriver *drv = bs->drv;
+    BlockDriverAIOCB *acb;
+    int i;
+    int res = 0;
+
+    if (drv->bdrv_aio_multiwrite != NULL) {
+        return drv->bdrv_aio_multiwrite(bs, reqs, num_reqs);
+    }
+
+    for (i = 0; i < num_reqs; i++) {
+        acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
+            reqs[i].nb_sectors, reqs[i].cb, reqs[i].opaque);
+        if (acb == NULL) {
+            reqs[i].error = EIO;
+            res = -1;
+        }
+    }
+
+    return res;
+}
+
 void bdrv_aio_cancel(BlockDriverAIOCB *acb)
 {
     acb->pool->cancel(acb);
diff --git a/block.h b/block.h
index 28bf357..ea69052 100644
--- a/block.h
+++ b/block.h
@@ -87,6 +87,21 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, 
int64_t sector_num,
                                   BlockDriverCompletionFunc *cb, void *opaque);
 void bdrv_aio_cancel(BlockDriverAIOCB *acb);
 
+typedef struct BlockRequest {
+    /* Fields to be filled by multiwrite caller */
+    int64_t sector;
+    int nb_sectors;
+    QEMUIOVector *qiov;
+    BlockDriverCompletionFunc *cb;
+    void *opaque;
+
+    /* Filled by multiwrite implementation */
+    int error;
+} BlockRequest;
+
+int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs,
+    int num_reqs);
+
 /* sg packet commands */
 int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf);
 BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
diff --git a/block_int.h b/block_int.h
index 0902fd4..027b1d8 100644
--- a/block_int.h
+++ b/block_int.h
@@ -70,6 +70,9 @@ struct BlockDriver {
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockDriverCompletionFunc *cb, void *opaque);
 
+    int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs,
+        int num_reqs);
+
     const char *protocol_name;
     int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
     int64_t (*bdrv_getlength)(BlockDriverState *bs);
-- 
1.6.0.6





reply via email to

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