Blame SOURCES/0019-exfat-use-iter_file_splice_write.patch

Kmods SIG 9e3ffb
From 035779483072ff7854943dc0cbae82c4e0070d15 Mon Sep 17 00:00:00 2001
Kmods SIG 9e3ffb
From: Eric Sandeen <sandeen@sandeen.net>
Kmods SIG 9e3ffb
Date: Fri, 1 May 2020 20:34:25 -0500
Kmods SIG 9e3ffb
Subject: [Backport 035779483072] exfat: use iter_file_splice_write
Kmods SIG 9e3ffb
Kmods SIG 9e3ffb
Doing copy_file_range() on exfat with a file opened for direct IO leads
Kmods SIG 9e3ffb
to an -EFAULT:
Kmods SIG 9e3ffb
Kmods SIG 9e3ffb
# xfs_io -f -d -c "truncate 32768" \
Kmods SIG 9e3ffb
       -c "copy_range -d 16384 -l 16384 -f 0" /mnt/test/junk
Kmods SIG 9e3ffb
copy_range: Bad address
Kmods SIG 9e3ffb
Kmods SIG 9e3ffb
and the reason seems to be that we go through:
Kmods SIG 9e3ffb
Kmods SIG 9e3ffb
default_file_splice_write
Kmods SIG 9e3ffb
 splice_from_pipe
Kmods SIG 9e3ffb
  __splice_from_pipe
Kmods SIG 9e3ffb
   write_pipe_buf
Kmods SIG 9e3ffb
    __kernel_write
Kmods SIG 9e3ffb
     new_sync_write
Kmods SIG 9e3ffb
      generic_file_write_iter
Kmods SIG 9e3ffb
       generic_file_direct_write
Kmods SIG 9e3ffb
        exfat_direct_IO
Kmods SIG 9e3ffb
         do_blockdev_direct_IO
Kmods SIG 9e3ffb
          iov_iter_get_pages
Kmods SIG 9e3ffb
Kmods SIG 9e3ffb
and land in iterate_all_kinds(), which does "return -EFAULT" for our kvec
Kmods SIG 9e3ffb
iter.
Kmods SIG 9e3ffb
Kmods SIG 9e3ffb
Setting exfat's splice_write to iter_file_splice_write fixes this and lets
Kmods SIG 9e3ffb
fsx (which originally detected the problem) run to success from
Kmods SIG 9e3ffb
the xfstests harness.
Kmods SIG 9e3ffb
Kmods SIG 9e3ffb
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Kmods SIG 9e3ffb
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
Kmods SIG 9e3ffb
---
Kmods SIG 9e3ffb
 src/file.c | 13 +++++++------
Kmods SIG 9e3ffb
 1 file changed, 7 insertions(+), 6 deletions(-)
Kmods SIG 9e3ffb
Kmods SIG 9e3ffb
diff --git a/src/file.c b/src/file.c
Kmods SIG 9e3ffb
index 4f76764165cf6f63a99c5e192ab33685e8e987b7..c9db8eb0cfc3ee267d5e3b051974ceae8de861b5 100644
Kmods SIG 9e3ffb
--- a/src/file.c
Kmods SIG 9e3ffb
+++ b/src/file.c
Kmods SIG 9e3ffb
@@ -348,12 +348,13 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr)
Kmods SIG 9e3ffb
 }
Kmods SIG 9e3ffb
 
Kmods SIG 9e3ffb
 const struct file_operations exfat_file_operations = {
Kmods SIG 9e3ffb
-	.llseek      = generic_file_llseek,
Kmods SIG 9e3ffb
-	.read_iter   = generic_file_read_iter,
Kmods SIG 9e3ffb
-	.write_iter  = generic_file_write_iter,
Kmods SIG 9e3ffb
-	.mmap        = generic_file_mmap,
Kmods SIG 9e3ffb
-	.fsync       = generic_file_fsync,
Kmods SIG 9e3ffb
-	.splice_read = generic_file_splice_read,
Kmods SIG 9e3ffb
+	.llseek		= generic_file_llseek,
Kmods SIG 9e3ffb
+	.read_iter	= generic_file_read_iter,
Kmods SIG 9e3ffb
+	.write_iter	= generic_file_write_iter,
Kmods SIG 9e3ffb
+	.mmap		= generic_file_mmap,
Kmods SIG 9e3ffb
+	.fsync		= generic_file_fsync,
Kmods SIG 9e3ffb
+	.splice_read	= generic_file_splice_read,
Kmods SIG 9e3ffb
+	.splice_write	= iter_file_splice_write,
Kmods SIG 9e3ffb
 };
Kmods SIG 9e3ffb
 
Kmods SIG 9e3ffb
 const struct inode_operations exfat_file_inode_operations = {
Kmods SIG 9e3ffb
-- 
Kmods SIG 9e3ffb
2.31.1
Kmods SIG 9e3ffb