at 15.09-beta 149 lines 4.6 kB view raw
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,