22.08.2019 21:31, Andrey Shinkevich wrote: > Revert the commit 118f99442d 'block/io.c: fix for the allocation failure' > and make better error handling for the file systems that do not support > fallocate() for the unaligned byte range. Allow falling back to pwrite > in case fallocate() returns EINVAL. > > Suggested-by: Kevin Wolf <kw...@redhat.com> > Suggested-by: Eric Blake <ebl...@redhat.com> > Signed-off-by: Andrey Shinkevich <andrey.shinkev...@virtuozzo.com> > --- > Discussed in email thread with the message ID > <1554474244-553661-1-git-send-email-andrey.shinkev...@virtuozzo.com> > > block/file-posix.c | 7 +++++++ > block/io.c | 2 +- > 2 files changed, 8 insertions(+), 1 deletion(-) > > diff --git a/block/file-posix.c b/block/file-posix.c > index fbeb006..2c254ff 100644 > --- a/block/file-posix.c > +++ b/block/file-posix.c > @@ -1588,6 +1588,13 @@ static int handle_aiocb_write_zeroes(void *opaque) > if (s->has_write_zeroes) { > int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE, > aiocb->aio_offset, aiocb->aio_nbytes); > + if (ret == -EINVAL) { > + /* > + * Allow falling back to pwrite for file systems that > + * do not support fallocate() for unaligned byte range. > + */ > + return -ENOTSUP; > + } > if (ret == 0 || ret != -ENOTSUP) { > return ret; > }
Hmm stop, you've done exactly what Den was afraid of: the next line s->has_write_zeroes = false; will disable write_zeroes forever. Something like --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1588,10 +1588,12 @@ static int handle_aiocb_write_zeroes(void *opaque) if (s->has_write_zeroes) { int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE, aiocb->aio_offset, aiocb->aio_nbytes); - if (ret == 0 || ret != -ENOTSUP) { + if (ret == 0 || (ret != -ENOTSUP && ret != -EINVAL)) { return ret; } - s->has_write_zeroes = false; + if (ret == -ENOTSUP) { + s->has_write_zeroes = false; + } } #endif will work better. So, handle ENOTSUP as "disable write_zeros forever", and EINVAL as "don't disable, but fallback to writing zeros". And we need same handling for following do_fallocate() calls too (otherwise they again fails with EINVAL which will break the whole thing). > diff --git a/block/io.c b/block/io.c > index 56bbf19..58f08cd 100644 > --- a/block/io.c > +++ b/block/io.c > @@ -1558,7 +1558,7 @@ static int coroutine_fn > bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, > assert(!bs->supported_zero_flags); > } > > - if (ret < 0 && !(flags & BDRV_REQ_NO_FALLBACK)) { > + if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) { > /* Fall back to bounce buffer if write zeroes is unsupported */ > BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE; > > -- Best regards, Vladimir