diff options
author | Kevin Wolf <kwolf@redhat.com> | 2011-07-14 17:27:13 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2011-08-02 15:53:40 +0200 |
commit | da1fa91d6cca8a6d3da9c2b222fa485429db297c (patch) | |
tree | c77f342d36c65fb1773c1f9c563f2d5b531e6f4e /block.c | |
parent | 5e3840ce24040cbd1957008489cbc136c43ca391 (diff) |
block: Add bdrv_co_readv/writev
Add new block driver callbacks bdrv_co_readv/writev, which work on a
QEMUIOVector like bdrv_aio_*, but don't need a callback. The function may only
be called inside a coroutine, so a block driver implementing this interface can
yield instead of blocking during I/O.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r-- | block.c | 45 |
1 files changed, 45 insertions, 0 deletions
@@ -1110,6 +1110,51 @@ int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, return 0; } +int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) +{ + BlockDriver *drv = bs->drv; + + trace_bdrv_co_readv(bs, sector_num, nb_sectors); + + if (!drv) { + return -ENOMEDIUM; + } + if (bdrv_check_request(bs, sector_num, nb_sectors)) { + return -EIO; + } + + return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); +} + +int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) +{ + BlockDriver *drv = bs->drv; + + trace_bdrv_co_writev(bs, sector_num, nb_sectors); + + if (!bs->drv) { + return -ENOMEDIUM; + } + if (bs->read_only) { + return -EACCES; + } + if (bdrv_check_request(bs, sector_num, nb_sectors)) { + return -EIO; + } + + if (bs->dirty_bitmap) { + set_dirty_bitmap(bs, sector_num, nb_sectors, 1); + } + + if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { + bs->wr_highest_sector = sector_num + nb_sectors - 1; + } + + return drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); +} + /** * Truncate file to 'offset' bytes (needed only for file protocols) */ |