[sheepdog] [PATCH v3 04/17] block/io: use int64_t bytes in driver wrappers
Alberto Garcia
berto at igalia.com
Mon May 11 18:30:53 CEST 2020
On Thu 30 Apr 2020 01:10:20 PM CEST, Vladimir Sementsov-Ogievskiy wrote:
> 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>
Reviewed-by: Alberto Garcia <berto at igalia.com>
Berto
More information about the sheepdog
mailing list