[Top][All Lists]
[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