diff --git a/block.c b/block.c index e8e08ad6680dac637f81e9e6bbf3a37d3697f7e4..d79a52ca7499547669ada8442e33aa2014fb6ac4 100644 --- a/block.c +++ b/block.c @@ -5859,6 +5859,28 @@ int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs) return bs->total_sectors; } +/* + * This wrapper is written by hand because this function is in the hot I/O path, + * via blk_get_geometry. + */ +int64_t coroutine_mixed_fn bdrv_nb_sectors(BlockDriverState *bs) +{ + BlockDriver *drv = bs->drv; + IO_CODE(); + + if (!drv) + return -ENOMEDIUM; + + if (bs->bl.has_variable_length) { + int ret = bdrv_refresh_total_sectors(bs, bs->total_sectors); + if (ret < 0) { + return ret; + } + } + + return bs->total_sectors; +} + /** * Return length in bytes on success, -errno on error. * The length is always a multiple of BDRV_SECTOR_SIZE. diff --git a/block/block-backend.c b/block/block-backend.c index cf58d4d1b7b42fa026dd0ee3ecd36f5696c7863a..55efc735b442e7a162ae452446407837c309ad2b 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1629,6 +1629,23 @@ int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk) } } +/* + * This wrapper is written by hand because this function is in the hot I/O path, + * via blk_get_geometry. + */ +int64_t coroutine_mixed_fn blk_nb_sectors(BlockBackend *blk) +{ + BlockDriverState *bs = blk_bs(blk); + + IO_CODE(); + + if (!bs) { + return -ENOMEDIUM; + } else { + return bdrv_nb_sectors(bs); + } +} + /* return 0 as number of sectors if no device present or error */ void coroutine_fn blk_co_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) @@ -1637,6 +1654,16 @@ void coroutine_fn blk_co_get_geometry(BlockBackend *blk, *nb_sectors_ptr = ret < 0 ? 0 : ret; } +/* + * This wrapper is written by hand because this function is in the hot I/O path. + */ +void coroutine_mixed_fn blk_get_geometry(BlockBackend *blk, + uint64_t *nb_sectors_ptr) +{ + int64_t ret = blk_nb_sectors(blk); + *nb_sectors_ptr = ret < 0 ? 0 : ret; +} + BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, QEMUIOVector *qiov, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque) diff --git a/include/block/block-io.h b/include/block/block-io.h index 9e2248a295a61641e33f2fde6146aa4e55c4372b..5dab88521d0255f52d3e89ba59ef6c2b3f0e2239 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -79,7 +79,7 @@ bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, PreallocMode prealloc, BdrvRequestFlags flags, Error **errp); int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_nb_sectors(BlockDriverState *bs); -int64_t co_wrapper_mixed_bdrv_rdlock bdrv_nb_sectors(BlockDriverState *bs); +int64_t coroutine_mixed_fn bdrv_nb_sectors(BlockDriverState *bs); int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_getlength(BlockDriverState *bs); int64_t co_wrapper_mixed_bdrv_rdlock bdrv_getlength(BlockDriverState *bs); diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h index c672b772472016fbbd2bf55bed8819b823ebe348..bb25493ba1a9aaaf2740d8e321fbf096e4287b02 100644 --- a/include/sysemu/block-backend-io.h +++ b/include/sysemu/block-backend-io.h @@ -72,11 +72,10 @@ int64_t co_wrapper_mixed blk_getlength(BlockBackend *blk); void coroutine_fn blk_co_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr); -void co_wrapper_mixed blk_get_geometry(BlockBackend *blk, - uint64_t *nb_sectors_ptr); +void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr); int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk); -int64_t co_wrapper_mixed blk_nb_sectors(BlockBackend *blk); +int64_t blk_nb_sectors(BlockBackend *blk); void *blk_try_blockalign(BlockBackend *blk, size_t size); void *blk_blockalign(BlockBackend *blk, size_t size);