@ -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 ;
}