Patchwork [RFC,07/12] qorum: Add qorum_aio_writev and its dependencies.

login
register
mail settings
Submitter Benoit Canet
Date Aug. 2, 2012, 10:16 a.m.
Message ID <1343902604-13981-8-git-send-email-benoit@irqsave.net>
Download mbox | patch
Permalink /patch/174725/
State New
Headers show

Comments

Benoit Canet - Aug. 2, 2012, 10:16 a.m.
Signed-off-by: Benoit Canet <benoit@irqsave.net>
---
 block/qorum.c |  112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

Patch

diff --git a/block/qorum.c b/block/qorum.c
index 37f6514..3dae8e4 100644
--- a/block/qorum.c
+++ b/block/qorum.c
@@ -134,6 +134,116 @@  static int64_t qorum_getlength(BlockDriverState *bs)
     return ret;
 }
 
+static void qorum_aio_cancel(BlockDriverAIOCB *blockacb)
+{
+    QorumAIOCB *acb = container_of(blockacb, QorumAIOCB, common);
+    bool finished = false;
+
+    /* Wait for the request to finish */
+    acb->finished = &finished;
+    while (!finished) {
+        qemu_aio_wait();
+    }
+}
+
+static AIOPool qorum_aio_pool = {
+    .aiocb_size         = sizeof(QorumAIOCB),
+    .cancel             = qorum_aio_cancel,
+};
+
+static int qorum_check_ret(QorumAIOCB *acb)
+{
+    int i, j;
+
+    for (i = 0, j = 0; i <= 2; i++) {
+        if (acb->aios[0].ret) {
+            j++;
+        }
+    }
+
+    if (j > 1) {
+        return -EIO;
+    }
+
+    return 0;
+}
+
+static void qorum_aio_bh(void *opaque)
+{
+    QorumAIOCB *acb = opaque;
+
+    qemu_bh_delete(acb->bh);
+    acb->common.cb(acb->common.opaque, qorum_check_ret(acb));
+    if (acb->finished) {
+        *acb->finished = true;
+    }
+    qemu_aio_release(acb);
+}
+
+static QorumAIOCB *qorum_aio_get(BlockDriverState *bs,
+                                 QEMUIOVector *qiov,
+                                 bool is_write,
+                                 int64_t sector_num,
+                                 int nb_sectors,
+                                 BlockDriverCompletionFunc *cb,
+                                 void *opaque)
+{
+    QorumAIOCB *acb = qemu_aio_get(&qorum_aio_pool, bs, cb, opaque);
+    int i;
+
+    acb->qiov = qiov;
+    acb->bh = NULL;
+    acb->count = 0;
+    acb->is_write = is_write;
+    acb->sector_num = sector_num;
+    acb->nb_sectors = nb_sectors;
+    acb->vote = NULL;
+    acb->vote_ret = 0;
+
+    for (i = 0; i <= 2; i++) {
+        acb->aios[i].buf = NULL;
+        acb->aios[i].ret = 0;
+        acb->aios[i].parent = acb;
+    }
+
+    return acb;
+}
+
+static void qorum_aio_cb(void *opaque, int ret)
+{
+    QorumSingleAIOCB *sacb = opaque;
+    QorumAIOCB *acb = sacb->parent;
+
+    sacb->ret = ret;
+    acb->count++;
+    assert(acb->count <= 3);
+    if (acb->count == 3) {
+        acb->bh = qemu_bh_new(qorum_aio_bh, acb);
+        qemu_bh_schedule(acb->bh);
+    }
+}
+
+static BlockDriverAIOCB *qorum_aio_writev(BlockDriverState *bs,
+                                          int64_t sector_num,
+                                          QEMUIOVector *qiov,
+                                          int nb_sectors,
+                                          BlockDriverCompletionFunc *cb,
+                                          void *opaque)
+{
+    BDRVQorumState *s = bs->opaque;
+    QorumAIOCB *acb = qorum_aio_get(bs, qiov, true, sector_num, nb_sectors,
+                                    cb, opaque);
+    int i;
+
+    for (i = 0; i <= 2; i++) {
+        acb->aios[i].aiocb = bdrv_aio_writev(s->bs[i], sector_num, qiov,
+                                             nb_sectors, &qorum_aio_cb,
+                                             &acb->aios[i]);
+    }
+
+    return &acb->common;
+}
+
 static BlockDriver bdrv_qorum = {
     .format_name        = "qorum",
     .protocol_name      = "qorum",
@@ -144,6 +254,8 @@  static BlockDriver bdrv_qorum = {
 
     .bdrv_file_open     = qorum_open,
     .bdrv_close         = qorum_close,
+
+    .bdrv_aio_writev    = qorum_aio_writev,
 };
 
 static void bdrv_qorum_init(void)