summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorMatus Kral <[email protected]>2015-05-12 01:26:18 +0200
committerBrian Behlendorf <[email protected]>2015-06-18 12:06:59 -0700
commit57ae840077e6c061bc57fb4860491f50b604d360 (patch)
tree4e5a171862d5bdc2216bd19cce93e673063be8b7 /module/zfs
parentec1c11d5ee1a90ab4d5f544143bcf5a6c2455800 (diff)
Linux 4.1 compat: use read_iter() / write_iter()
Linux 3.15 commit torvalds/linux@293bc98 introduced two new methods. The ->read_iter() and ->write_iter() methods were designed to replace the ->aio_read() and ->aio_write() interfaces. Both interfaces were preserved for several kernel releases in order to migrate all existing consumers to the new interfaces. But as of Linux 4.1 the legacy interface has been retired and the ZFS code must be updated to use the new interfaces. Signed-off-by: Brian Behlendorf <[email protected]> Closes #3352
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/zpl_file.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c
index 66db11306..547114012 100644
--- a/module/zfs/zpl_file.c
+++ b/module/zfs/zpl_file.c
@@ -196,8 +196,7 @@ zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
static int
zpl_aio_fsync(struct kiocb *kiocb, int datasync)
{
- return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos,
- kiocb->ki_pos + kiocb->ki_nbytes, datasync));
+ return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos, -1, datasync));
}
#else
#error "Unsupported fops->fsync() implementation"
@@ -261,12 +260,11 @@ zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
}
static ssize_t
-zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
- unsigned long nr_segs, loff_t pos)
+zpl_iter_read_common(struct kiocb *kiocb, const struct iovec *iovp,
+ unsigned long nr_segs, size_t count)
{
cred_t *cr = CRED();
struct file *filp = kiocb->ki_filp;
- size_t count = kiocb->ki_nbytes;
ssize_t read;
size_t alloc_size = sizeof (struct iovec) * nr_segs;
struct iovec *iov_tmp = kmem_alloc(alloc_size, KM_SLEEP);
@@ -284,6 +282,22 @@ zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
return (read);
}
+#if defined(HAVE_VFS_RW_ITERATE)
+static ssize_t
+zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to)
+{
+ return (zpl_iter_read_common(kiocb, to->iov, to->nr_segs,
+ iov_iter_count(to)));
+}
+#else
+static ssize_t
+zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
+ unsigned long nr_segs, loff_t pos)
+{
+ return (zpl_iter_read_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes));
+}
+#endif /* HAVE_VFS_RW_ITERATE */
+
static inline ssize_t
zpl_write_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count,
unsigned long nr_segs, loff_t *ppos, uio_seg_t segment,
@@ -344,12 +358,11 @@ zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
}
static ssize_t
-zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
- unsigned long nr_segs, loff_t pos)
+zpl_iter_write_common(struct kiocb *kiocb, const struct iovec *iovp,
+ unsigned long nr_segs, size_t count)
{
cred_t *cr = CRED();
struct file *filp = kiocb->ki_filp;
- size_t count = kiocb->ki_nbytes;
ssize_t wrote;
size_t alloc_size = sizeof (struct iovec) * nr_segs;
struct iovec *iov_tmp = kmem_alloc(alloc_size, KM_SLEEP);
@@ -367,6 +380,22 @@ zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
return (wrote);
}
+#if defined(HAVE_VFS_RW_ITERATE)
+static ssize_t
+zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from)
+{
+ return (zpl_iter_write_common(kiocb, from->iov, from->nr_segs,
+ iov_iter_count(from)));
+}
+#else
+static ssize_t
+zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
+ unsigned long nr_segs, loff_t pos)
+{
+ return (zpl_iter_write_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes));
+}
+#endif /* HAVE_VFS_RW_ITERATE */
+
static loff_t
zpl_llseek(struct file *filp, loff_t offset, int whence)
{
@@ -778,8 +807,13 @@ const struct file_operations zpl_file_operations = {
.llseek = zpl_llseek,
.read = zpl_read,
.write = zpl_write,
+#ifdef HAVE_VFS_RW_ITERATE
+ .read_iter = zpl_iter_read,
+ .write_iter = zpl_iter_write,
+#else
.aio_read = zpl_aio_read,
.aio_write = zpl_aio_write,
+#endif
.mmap = zpl_mmap,
.fsync = zpl_fsync,
.aio_fsync = zpl_aio_fsync,