Blame SOURCES/kvm-file-posix-Allow-byte-aligned-O_DIRECT-with-NFS.patch

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