Commit 1ba7e159 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Max Reitz
Browse files

quorum: do not allocate multiple iovecs for FIFO strategy



In FIFO mode there are no parallel reads, hence there is no need to
allocate separate buffers and clone the iovecs.

The two cases of quorum_aio_cb are now even more different, and
most of quorum_aio_finalize is only needed in one of them, so split
them in separate functions.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Message-id: 1475685327-22767-3-git-send-email-pbonzini@redhat.com
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Reviewed-by: default avatarAlberto Garcia <berto@igalia.com>
Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
parent 86ec252c
Loading
Loading
Loading
Loading
+40 −39
Original line number Diff line number Diff line
@@ -156,21 +156,7 @@ static AIOCBInfo quorum_aiocb_info = {

static void quorum_aio_finalize(QuorumAIOCB *acb)
{
    int i, ret = 0;

    if (acb->vote_ret) {
        ret = acb->vote_ret;
    }

    acb->common.cb(acb->common.opaque, ret);

    if (acb->is_read) {
        for (i = 0; i < acb->children_read; i++) {
            qemu_vfree(acb->qcrs[i].buf);
            qemu_iovec_destroy(&acb->qcrs[i].qiov);
        }
    }

    acb->common.cb(acb->common.opaque, acb->vote_ret);
    g_free(acb->qcrs);
    qemu_aio_unref(acb);
}
@@ -282,38 +268,52 @@ static void quorum_copy_qiov(QEMUIOVector *dest, QEMUIOVector *source)
    }
}

static void quorum_aio_cb(void *opaque, int ret)
static void quorum_report_bad_acb(QuorumChildRequest *sacb, int ret)
{
    QuorumChildRequest *sacb = opaque;
    QuorumAIOCB *acb = sacb->parent;
    BDRVQuorumState *s = acb->common.bs->opaque;
    bool rewrite = false;

    if (ret == 0) {
        acb->success_count++;
    } else {
        QuorumOpType type;
        type = acb->is_read ? QUORUM_OP_TYPE_READ : QUORUM_OP_TYPE_WRITE;
    QuorumOpType type = acb->is_read ? QUORUM_OP_TYPE_READ : QUORUM_OP_TYPE_WRITE;
    quorum_report_bad(type, acb->sector_num, acb->nb_sectors,
                      sacb->aiocb->bs->node_name, ret);
}

    if (acb->is_read && s->read_pattern == QUORUM_READ_PATTERN_FIFO) {
static void quorum_fifo_aio_cb(void *opaque, int ret)
{
    QuorumChildRequest *sacb = opaque;
    QuorumAIOCB *acb = sacb->parent;
    BDRVQuorumState *s = acb->common.bs->opaque;

    assert(acb->is_read && s->read_pattern == QUORUM_READ_PATTERN_FIFO);

    if (ret < 0) {
        quorum_report_bad_acb(sacb, ret);

        /* We try to read next child in FIFO order if we fail to read */
        if (ret < 0 && acb->children_read < s->num_children) {
        if (acb->children_read < s->num_children) {
            read_fifo_child(acb);
            return;
        }

        if (ret == 0) {
            quorum_copy_qiov(acb->qiov, &acb->qcrs[acb->children_read - 1].qiov);
    }

    acb->vote_ret = ret;

    /* FIXME: rewrite failed children if acb->children_read > 1? */
    quorum_aio_finalize(acb);
        return;
}

static void quorum_aio_cb(void *opaque, int ret)
{
    QuorumChildRequest *sacb = opaque;
    QuorumAIOCB *acb = sacb->parent;
    BDRVQuorumState *s = acb->common.bs->opaque;
    bool rewrite = false;
    int i;

    sacb->ret = ret;
    if (ret == 0) {
        acb->success_count++;
    } else {
        quorum_report_bad_acb(sacb, ret);
    }
    acb->count++;
    assert(acb->count <= s->num_children);
    assert(acb->success_count <= s->num_children);
@@ -324,6 +324,10 @@ static void quorum_aio_cb(void *opaque, int ret)
    /* Do the vote on read */
    if (acb->is_read) {
        rewrite = quorum_vote(acb);
        for (i = 0; i < s->num_children; i++) {
            qemu_vfree(acb->qcrs[i].buf);
            qemu_iovec_destroy(&acb->qcrs[i].qiov);
        }
    } else {
        quorum_has_too_much_io_failed(acb);
    }
@@ -672,12 +676,9 @@ static BlockAIOCB *read_fifo_child(QuorumAIOCB *acb)
    BDRVQuorumState *s = acb->common.bs->opaque;
    int n = acb->children_read++;

    acb->qcrs[n].buf = qemu_blockalign(s->children[n]->bs, acb->qiov->size);
    qemu_iovec_init(&acb->qcrs[n].qiov, acb->qiov->niov);
    qemu_iovec_clone(&acb->qcrs[n].qiov, acb->qiov, acb->qcrs[n].buf);
    acb->qcrs[n].aiocb = bdrv_aio_readv(s->children[n], acb->sector_num,
                                        &acb->qcrs[n].qiov, acb->nb_sectors,
                                        quorum_aio_cb, &acb->qcrs[n]);
                                        acb->qiov, acb->nb_sectors,
                                        quorum_fifo_aio_cb, &acb->qcrs[n]);

    return &acb->common;
}