summaryrefslogtreecommitdiff
path: root/block/quorum.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-10-05 18:35:27 +0200
committerMax Reitz <mreitz@redhat.com>2016-10-24 17:56:06 +0200
commit1ba7e159787d7c96a8783584395b670c22bba4ef (patch)
tree76eb5d5528dad942dbae0dbcc66e4a60e1604091 /block/quorum.c
parent86ec252c198a62b3a1da3ac62277adf917d985cf (diff)
downloadqemu-1ba7e159787d7c96a8783584395b670c22bba4ef.tar.gz
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 <pbonzini@redhat.com> Message-id: 1475685327-22767-3-git-send-email-pbonzini@redhat.com Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Alberto Garcia <berto@igalia.com> Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block/quorum.c')
-rw-r--r--block/quorum.c79
1 files changed, 40 insertions, 39 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_aio_cb(void *opaque, int ret)
+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;
- bool rewrite = false;
- 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);
- }
+ assert(acb->is_read && s->read_pattern == QUORUM_READ_PATTERN_FIFO);
+
+ if (ret < 0) {
+ 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) {
+ 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;
- quorum_aio_finalize(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 {
+ 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;
}