Skip to content

Commit

Permalink
quorum: Add quorum_aio_writev and its dependencies.
Browse files Browse the repository at this point in the history
Writes are mirrored num_children times on num_children devices.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
benoit-canet authored and kevmw committed Feb 21, 2014
1 parent cadebd7 commit 13e7956
Showing 1 changed file with 103 additions and 0 deletions.
103 changes: 103 additions & 0 deletions block/quorum.c
Expand Up @@ -69,11 +69,114 @@ struct QuorumAIOCB {
int vote_ret;
};

static void quorum_aio_cancel(BlockDriverAIOCB *blockacb)
{
QuorumAIOCB *acb = container_of(blockacb, QuorumAIOCB, common);
BDRVQuorumState *s = acb->common.bs->opaque;
int i;

/* cancel all callbacks */
for (i = 0; i < s->num_children; i++) {
bdrv_aio_cancel(acb->qcrs[i].aiocb);
}

g_free(acb->qcrs);
qemu_aio_release(acb);
}

static AIOCBInfo quorum_aiocb_info = {
.aiocb_size = sizeof(QuorumAIOCB),
.cancel = quorum_aio_cancel,
};

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

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

g_free(acb->qcrs);
qemu_aio_release(acb);
}

static QuorumAIOCB *quorum_aio_get(BDRVQuorumState *s,
BlockDriverState *bs,
QEMUIOVector *qiov,
uint64_t sector_num,
int nb_sectors,
BlockDriverCompletionFunc *cb,
void *opaque)
{
QuorumAIOCB *acb = qemu_aio_get(&quorum_aiocb_info, bs, cb, opaque);
int i;

acb->common.bs->opaque = s;
acb->sector_num = sector_num;
acb->nb_sectors = nb_sectors;
acb->qiov = qiov;
acb->qcrs = g_new0(QuorumChildRequest, s->num_children);
acb->count = 0;
acb->success_count = 0;
acb->is_read = false;
acb->vote_ret = 0;

for (i = 0; i < s->num_children; i++) {
acb->qcrs[i].buf = NULL;
acb->qcrs[i].ret = 0;
acb->qcrs[i].parent = acb;
}

return acb;
}

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

sacb->ret = ret;
acb->count++;
if (ret == 0) {
acb->success_count++;
}
assert(acb->count <= s->num_children);
assert(acb->success_count <= s->num_children);
if (acb->count < s->num_children) {
return;
}

quorum_aio_finalize(acb);
}

static BlockDriverAIOCB *quorum_aio_writev(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
int nb_sectors,
BlockDriverCompletionFunc *cb,
void *opaque)
{
BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = quorum_aio_get(s, bs, qiov, sector_num, nb_sectors,
cb, opaque);
int i;

for (i = 0; i < s->num_children; i++) {
acb->qcrs[i].aiocb = bdrv_aio_writev(s->bs[i], sector_num, qiov,
nb_sectors, &quorum_aio_cb,
&acb->qcrs[i]);
}

return &acb->common;
}

static BlockDriver bdrv_quorum = {
.format_name = "quorum",
.protocol_name = "quorum",

.instance_size = sizeof(BDRVQuorumState),

.bdrv_aio_writev = quorum_aio_writev,
};

static void bdrv_quorum_init(void)
Expand Down

0 comments on commit 13e7956

Please sign in to comment.