From 1ba7e159787d7c96a8783584395b670c22bba4ef Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 5 Oct 2016 18:35:27 +0200 Subject: [PATCH] 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: Paolo Bonzini Message-id: 1475685327-22767-3-git-send-email-pbonzini@redhat.com Reviewed-by: Max Reitz Reviewed-by: Alberto Garcia Signed-off-by: Max Reitz --- block/quorum.c | 83 +++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/block/quorum.c b/block/quorum.c index 435296eef6..d122299352 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -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_report_bad_acb(QuorumChildRequest *sacb, int ret) +{ + QuorumAIOCB *acb = sacb->parent; + 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); +} + +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 (acb->children_read < s->num_children) { + read_fifo_child(acb); + return; + } + } + + acb->vote_ret = ret; + + /* FIXME: rewrite failed children if acb->children_read > 1? */ + quorum_aio_finalize(acb); +} + 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 { - QuorumOpType type; - 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); + quorum_report_bad_acb(sacb, ret); } - - if (acb->is_read && s->read_pattern == QUORUM_READ_PATTERN_FIFO) { - /* We try to read next child in FIFO order if we fail to read */ - if (ret < 0 && 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; - quorum_aio_finalize(acb); - return; - } - - sacb->ret = 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; }