2020-05-02 10:34 GMT+09:00, Eric Sandeen <sandeen@xxxxxxxxxxx>: > Doing copy_file_range() on exfat with a file opened for direct IO leads > to an -EFAULT: > > # xfs_io -f -d -c "truncate 32768" \ > -c "copy_range -d 16384 -l 16384 -f 0" /mnt/test/junk > copy_range: Bad address > > and the reason seems to be that we go through: > > default_file_splice_write > splice_from_pipe > __splice_from_pipe > write_pipe_buf > __kernel_write > new_sync_write > generic_file_write_iter > generic_file_direct_write > exfat_direct_IO > do_blockdev_direct_IO > iov_iter_get_pages > > and land in iterate_all_kinds(), which does "return -EFAULT" for our kvec > iter. > > Setting exfat's splice_write to iter_file_splice_write fixes this and lets > fsx (which originally detected the problem) run to success from the > xfstests > harness. > > Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxxx> Applied:) Thanks! > --- > > I know that's not a good changelog; I conferred with viro about whether > this > is correct, but I still don't have a great explanation, so feel free to fix > up > the changelog to be more informative if the change is otherwise correct... > > diff --git a/fs/exfat/file.c b/fs/exfat/file.c > index 4f76764165cf..c9db8eb0cfc3 100644 > --- a/fs/exfat/file.c > +++ b/fs/exfat/file.c > @@ -348,12 +348,13 @@ int exfat_setattr(struct dentry *dentry, struct iattr > *attr) > } > > const struct file_operations exfat_file_operations = { > - .llseek = generic_file_llseek, > - .read_iter = generic_file_read_iter, > - .write_iter = generic_file_write_iter, > - .mmap = generic_file_mmap, > - .fsync = generic_file_fsync, > - .splice_read = generic_file_splice_read, > + .llseek = generic_file_llseek, > + .read_iter = generic_file_read_iter, > + .write_iter = generic_file_write_iter, > + .mmap = generic_file_mmap, > + .fsync = generic_file_fsync, > + .splice_read = generic_file_splice_read, > + .splice_write = iter_file_splice_write, > }; > > const struct inode_operations exfat_file_inode_operations = { > > >