[GEDI] [PATCH v3 04/17] block/io: use int64_t bytes in driver wrappers
Vladimir Sementsov-Ogievskiy
vsementsov at virtuozzo.com
Thu Apr 30 11:10:20 UTC 2020
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 <vsementsov at virtuozzo.com>
Reviewed-by: Eric Blake <eblake at 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
More information about the integration
mailing list