diff options
Diffstat (limited to 'module/zfs/zpl_file.c')
-rw-r--r-- | module/zfs/zpl_file.c | 50 |
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, |