1diff --git a/config/kernel-vfs-rw-iterate.m4 b/config/kernel-vfs-rw-iterate.m4
2new file mode 100644
3index 0000000..f8dc422
4--- /dev/null
5+++ b/config/kernel-vfs-rw-iterate.m4
6@@ -0,0 +1,27 @@
7+dnl #
8+dnl # Linux 4.1.x API
9+dnl #
10+AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
11+ [AC_MSG_CHECKING([whether fops->read/write_iter() are available])
12+ ZFS_LINUX_TRY_COMPILE([
13+ #include <linux/fs.h>
14+
15+ ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to)
16+ { return 0; }
17+ ssize_t test_write(struct kiocb *kiocb, struct iov_iter *from)
18+ { return 0; }
19+
20+ static const struct file_operations
21+ fops __attribute__ ((unused)) = {
22+ .read_iter = test_read,
23+ .write_iter = test_write,
24+ };
25+ ],[
26+ ],[
27+ AC_MSG_RESULT(yes)
28+ AC_DEFINE(HAVE_VFS_RW_ITERATE, 1,
29+ [fops->read/write_iter() are available])
30+ ],[
31+ AC_MSG_RESULT(no)
32+ ])
33+])
34diff --git a/config/kernel.m4 b/config/kernel.m4
35index a9f2f58..fe42e17 100644
36--- a/config/kernel.m4
37+++ b/config/kernel.m4
38@@ -96,6 +96,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
39 ZFS_AC_KERNEL_5ARG_SGET
40 ZFS_AC_KERNEL_LSEEK_EXECUTE
41 ZFS_AC_KERNEL_VFS_ITERATE
42+ ZFS_AC_KERNEL_VFS_RW_ITERATE
43
44 AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
45 KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
46diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c
47index 66db113..5471140 100644
48--- a/module/zfs/zpl_file.c
49+++ b/module/zfs/zpl_file.c
50@@ -196,8 +196,7 @@ zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
51 static int
52 zpl_aio_fsync(struct kiocb *kiocb, int datasync)
53 {
54- return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos,
55- kiocb->ki_pos + kiocb->ki_nbytes, datasync));
56+ return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos, -1, datasync));
57 }
58 #else
59 #error "Unsupported fops->fsync() implementation"
60@@ -261,12 +260,11 @@ zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
61 }
62
63 static ssize_t
64-zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
65- unsigned long nr_segs, loff_t pos)
66+zpl_iter_read_common(struct kiocb *kiocb, const struct iovec *iovp,
67+ unsigned long nr_segs, size_t count)
68 {
69 cred_t *cr = CRED();
70 struct file *filp = kiocb->ki_filp;
71- size_t count = kiocb->ki_nbytes;
72 ssize_t read;
73 size_t alloc_size = sizeof (struct iovec) * nr_segs;
74 struct iovec *iov_tmp = kmem_alloc(alloc_size, KM_SLEEP);
75@@ -284,6 +282,22 @@ zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
76 return (read);
77 }
78
79+#if defined(HAVE_VFS_RW_ITERATE)
80+static ssize_t
81+zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to)
82+{
83+ return (zpl_iter_read_common(kiocb, to->iov, to->nr_segs,
84+ iov_iter_count(to)));
85+}
86+#else
87+static ssize_t
88+zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
89+ unsigned long nr_segs, loff_t pos)
90+{
91+ return (zpl_iter_read_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes));
92+}
93+#endif /* HAVE_VFS_RW_ITERATE */
94+
95 static inline ssize_t
96 zpl_write_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count,
97 unsigned long nr_segs, loff_t *ppos, uio_seg_t segment,
98@@ -344,12 +358,11 @@ zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
99 }
100
101 static ssize_t
102-zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
103- unsigned long nr_segs, loff_t pos)
104+zpl_iter_write_common(struct kiocb *kiocb, const struct iovec *iovp,
105+ unsigned long nr_segs, size_t count)
106 {
107 cred_t *cr = CRED();
108 struct file *filp = kiocb->ki_filp;
109- size_t count = kiocb->ki_nbytes;
110 ssize_t wrote;
111 size_t alloc_size = sizeof (struct iovec) * nr_segs;
112 struct iovec *iov_tmp = kmem_alloc(alloc_size, KM_SLEEP);
113@@ -367,6 +380,22 @@ zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
114 return (wrote);
115 }
116
117+#if defined(HAVE_VFS_RW_ITERATE)
118+static ssize_t
119+zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from)
120+{
121+ return (zpl_iter_write_common(kiocb, from->iov, from->nr_segs,
122+ iov_iter_count(from)));
123+}
124+#else
125+static ssize_t
126+zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
127+ unsigned long nr_segs, loff_t pos)
128+{
129+ return (zpl_iter_write_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes));
130+}
131+#endif /* HAVE_VFS_RW_ITERATE */
132+
133 static loff_t
134 zpl_llseek(struct file *filp, loff_t offset, int whence)
135 {
136@@ -778,8 +807,13 @@ const struct file_operations zpl_file_operations = {
137 .llseek = zpl_llseek,
138 .read = zpl_read,
139 .write = zpl_write,
140+#ifdef HAVE_VFS_RW_ITERATE
141+ .read_iter = zpl_iter_read,
142+ .write_iter = zpl_iter_write,
143+#else
144 .aio_read = zpl_aio_read,
145 .aio_write = zpl_aio_write,
146+#endif
147 .mmap = zpl_mmap,
148 .fsync = zpl_fsync,
149 .aio_fsync = zpl_aio_fsync,