From 4e553943c8fe4924d194884b4719c5459210c686 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Tue, 26 Jan 2021 17:21:03 -0500 Subject: [PATCH 8/9] file-posix: Allow byte-aligned O_DIRECT with NFS RH-Author: Kevin Wolf Message-id: <20210126172103.136060-3-kwolf@redhat.com> Patchwork-id: 100785 O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 2/2] file-posix: Allow byte-aligned O_DIRECT with NFS Bugzilla: 1834281 RH-Acked-by: Markus Armbruster RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Max Reitz Since commit a6b257a08e3 ('file-posix: Handle undetectable alignment'), we assume that if we open a file with O_DIRECT and alignment probing returns 1, we just couldn't find out the real alignment requirement because some filesystems make the requirement only for allocated blocks. In this case, a safe default of 4k is used. This is too strict for NFS, which does actually allow byte-aligned requests even with O_DIRECT. Because we can't distinguish both cases with generic code, let's just look at the file system magic and disable s->needs_alignment for NFS. This way, O_DIRECT can still be used on NFS for images that are not aligned to 4k. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Message-Id: <20200716142601.111237-3-kwolf@redhat.com> Reviewed-by: Max Reitz Signed-off-by: Kevin Wolf (cherry picked from commit 5edc85571e7b7269dce408735eba7507f18ac666) Signed-off-by: Kevin Wolf Signed-off-by: Jon Maloy --- block/file-posix.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/block/file-posix.c b/block/file-posix.c index adafbfa1be..2d834fbdf6 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -61,10 +61,12 @@ #include #include #include +#include #include #include #include #include +#include #include #ifdef __s390__ #include @@ -298,6 +300,28 @@ static int probe_physical_blocksize(int fd, unsigned int *blk_size) #endif } +/* + * Returns true if no alignment restrictions are necessary even for files + * opened with O_DIRECT. + * + * raw_probe_alignment() probes the required alignment and assume that 1 means + * the probing failed, so it falls back to a safe default of 4k. This can be + * avoided if we know that byte alignment is okay for the file. + */ +static bool dio_byte_aligned(int fd) +{ +#ifdef __linux__ + struct statfs buf; + int ret; + + ret = fstatfs(fd, &buf); + if (ret == 0 && buf.f_type == NFS_SUPER_MAGIC) { + return true; + } +#endif + return false; +} + /* Check if read is allowed with given memory buffer and length. * * This function is used to check O_DIRECT memory buffer and request alignment. @@ -602,7 +626,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, s->has_discard = true; s->has_write_zeroes = true; - if ((bs->open_flags & BDRV_O_NOCACHE) != 0) { + if ((bs->open_flags & BDRV_O_NOCACHE) != 0 && !dio_byte_aligned(s->fd)) { s->needs_alignment = true; } -- 2.18.2