We are generally moving to int64_t for both offset and bytes parameters on all io paths.
Main motivation is realization of 64-bit write_zeroes operation for fast zeroing large disk chunks, up to the whole disk. We chose signed type, to be consistent with off_t (which is signed) and with possibility for signed return type (where negative value means error). So, convert driver wrappers parameters which are already 64bit to signed type. Patch-correctness audit by Eric Blake: bdrv_driver_preadv Remains 64 bits, the question is whether any caller could pass in something larger than 63 bits. Callers are: bdrv_co_do_copy_on_readv() - passes 'int64_t pnum', but sets pnum in a fragmenting loop, MAX_BOUNCE_BUFFER when copy-on-read is needed, or max_transfer bounded by BDRV_REQUEST_MAX_BYTES otherwise bdrv_aligned_preadv() - passes 'unsigned int bytes' further limited by fragmenting loop on max_transfer <= INT_MAX Input is bounded to < 2G, internal use of 'bytes' is: drv->bdrv_co_preadv_part(uint64_t) - safe qemu_iovec_init_slice(size_t) - potential truncation on 32-bit platform [*] drv->bdrv_co_preadv(uint64_t) - safe drv->bdrv_aio_preadv(uint64_t) - safe drv->bdrv_co_readv(int) after assertion of <2G - safe bdrv_driver_pwritev Remains 64 bits, the question is whether any caller could pass in something larger than 63. Callers are: bdrv_co_do_copy_on_readv() - passes 'int64_t pnum', but set in a fragmenting loop bounded by MAX_BOUNCE_BUFFER bdrv_co_do_pwrite_zeroes() - passes 'int num' bdrv_aligned_pwritev() - passes 'unsigned int bytes' further limited by fragmenting loop on max_transfer <= INT_MAX Input is bounded to < 2G, internal use of 'bytes' is: drv->bdrv_co_pwritev_part(uint64_t) - safe qemu_iovec_init_slice(size_t) - potential truncation on 32-bit platform [*] drv->bdrv_co_pwritev(uint64_t) - safe drv->bdrv_aio_pwritev(uint64_t) - safe drv->bdrv_co_writev(int) after assertion of <2G - safe bdrv_driver_pwritev_compressed bdrv_aligned_pwritev() - passes 'unsigned int bytes' Input is bounded to < 4G, internal use of 'bytes' is: drv->bdrv_co_pwritev_compressed_part(uint64_t) - safe drv->bdrv_co_pwritev_compressed(uint64_t) - safe qemu_iovec_init_slice(size_t) - potential truncation on 32-bit platform [*] [*]: QEMUIOVector is in-RAM data, so size_t seems a valid type for it's operation. To avoid truncations we should require max_transfer to be not greater than SIZE_MAX, limiting RAM-occupying operations and QEMUIOVector usage. Still, 64bit discard and write_zeroes (which doesn't use QEMUIOVector) should work even on 32bit machines, not being limited by max_transfer. For now, we safe anyway, as all input goes through bdrv_aligned_pwritev() and bdrv_aligned_preadv(), which are limiting max_transfer to INT_MAX. Series: 64bit-block-status Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> Reviewed-by: Eric Blake <ebl...@redhat.com> --- block/io.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/io.c b/block/io.c index 7a7d4e578d..eeba3b828c 100644 --- a/block/io.c +++ b/block/io.c @@ -906,7 +906,7 @@ static void bdrv_co_io_em_complete(void *opaque, int ret) } static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs, - uint64_t offset, uint64_t bytes, + int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset, int flags) { @@ -975,7 +975,7 @@ out: } static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, - uint64_t offset, uint64_t bytes, + int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset, int flags) { @@ -1055,8 +1055,8 @@ emulate_flags: } static int coroutine_fn -bdrv_driver_pwritev_compressed(BlockDriverState *bs, uint64_t offset, - uint64_t bytes, QEMUIOVector *qiov, +bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset, + int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset) { BlockDriver *drv = bs->drv; -- 2.21.0