|
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 |
|