When BDRV_REQ_NO_FALLBACK is supported, the NBD driver supports a larger request size. Add code to try large zero requests with a NO_FALLBACK request prior to having to split a request into chunks according to max_pwrite_zeroes.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- block/io.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/block/io.c b/block/io.c index 3fae97da2d..9a6dabb595 100644 --- a/block/io.c +++ b/block/io.c @@ -1778,6 +1778,7 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int alignment = MAX(bs->bl.pwrite_zeroes_alignment, bs->bl.request_alignment); int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER); + bool auto_no_fallback; assert(alignment % bs->bl.request_alignment == 0); @@ -1785,6 +1786,16 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, return -ENOMEDIUM; } + if (!(flags & BDRV_REQ_NO_FALLBACK) && + (bs->supported_zero_flags & BDRV_REQ_NO_FALLBACK) && + bs->bl.max_pwrite_zeroes && bs->bl.max_pwrite_zeroes < bytes && + bs->bl.max_pwrite_zeroes < bs->bl.max_pwrite_zeroes_fast) + { + assert(drv->bdrv_co_pwrite_zeroes); + flags |= BDRV_REQ_NO_FALLBACK; + auto_no_fallback = true; + } + if ((flags & ~bs->supported_zero_flags) & BDRV_REQ_NO_FALLBACK) { return -ENOTSUP; } @@ -1829,6 +1840,13 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, if (drv->bdrv_co_pwrite_zeroes) { ret = drv->bdrv_co_pwrite_zeroes(bs, offset, num, flags & bs->supported_zero_flags); + if (ret == -ENOTSUP && auto_no_fallback) { + flags &= ~BDRV_REQ_NO_FALLBACK; + max_write_zeroes = + QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, + INT_MAX), alignment); + continue; + } if (ret != -ENOTSUP && (flags & BDRV_REQ_FUA) && !(bs->supported_zero_flags & BDRV_REQ_FUA)) { need_flush = true; -- 2.21.0