quorum: Add quorum_aio_writev and its dependencies.
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>
This commit is contained in:
parent
cadebd7a2a
commit
13e7956e31
103
block/quorum.c
103
block/quorum.c
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user