block: Introduce .bdrv_co_preadv/pwritev BlockDriver function

Many parts of the block layer are already byte granularity. The block
driver interface, however, was still missing an interface that allows
making use of this. This patch introduces a new BlockDriver interface,
which is based on coroutines, vectored, has flags and uses a byte
granularity. This is now the preferred interface for new drivers.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
This commit is contained in:
Kevin Wolf 2016-04-25 11:25:18 +02:00
parent cab3a3563c
commit 3fb06697ae
2 changed files with 26 additions and 6 deletions

View file

@ -803,8 +803,15 @@ static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
QEMUIOVector *qiov, int flags)
{
BlockDriver *drv = bs->drv;
int64_t sector_num = offset >> BDRV_SECTOR_BITS;
unsigned int nb_sectors = bytes >> BDRV_SECTOR_BITS;
int64_t sector_num;
unsigned int nb_sectors;
if (drv->bdrv_co_preadv) {
return drv->bdrv_co_preadv(bs, offset, bytes, qiov, flags);
}
sector_num = offset >> BDRV_SECTOR_BITS;
nb_sectors = bytes >> BDRV_SECTOR_BITS;
assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
@ -834,10 +841,18 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
QEMUIOVector *qiov, int flags)
{
BlockDriver *drv = bs->drv;
int64_t sector_num = offset >> BDRV_SECTOR_BITS;
unsigned int nb_sectors = bytes >> BDRV_SECTOR_BITS;
int64_t sector_num;
unsigned int nb_sectors;
int ret;
if (drv->bdrv_co_pwritev) {
ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov, flags);
goto emulate_flags;
}
sector_num = offset >> BDRV_SECTOR_BITS;
nb_sectors = bytes >> BDRV_SECTOR_BITS;
assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
assert((bytes >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS);
@ -857,13 +872,14 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
acb = bs->drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
bdrv_co_io_em_complete, &co);
if (acb == NULL) {
return -EIO;
ret = -EIO;
} else {
qemu_coroutine_yield();
return co.ret;
ret = co.ret;
}
}
emulate_flags:
if (ret == 0 && (flags & BDRV_REQ_FUA) &&
!(drv->supported_write_flags & BDRV_REQ_FUA))
{

View file

@ -153,10 +153,14 @@ struct BlockDriver {
int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags);
int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
int coroutine_fn (*bdrv_co_writev_flags)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int flags);
int coroutine_fn (*bdrv_co_pwritev)(BlockDriverState *bs,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags);
int supported_write_flags;