mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 03:09:34 +03:00
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 <behlendorf1@llnl.gov> Closes #3352
This commit is contained in:
parent
ec1c11d5ee
commit
57ae840077
27
config/kernel-vfs-rw-iterate.m4
Normal file
27
config/kernel-vfs-rw-iterate.m4
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
dnl #
|
||||||
|
dnl # Linux 4.1.x API
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
|
||||||
|
[AC_MSG_CHECKING([whether fops->read/write_iter() are available])
|
||||||
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to)
|
||||||
|
{ return 0; }
|
||||||
|
ssize_t test_write(struct kiocb *kiocb, struct iov_iter *from)
|
||||||
|
{ return 0; }
|
||||||
|
|
||||||
|
static const struct file_operations
|
||||||
|
fops __attribute__ ((unused)) = {
|
||||||
|
.read_iter = test_read,
|
||||||
|
.write_iter = test_write,
|
||||||
|
};
|
||||||
|
],[
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_VFS_RW_ITERATE, 1,
|
||||||
|
[fops->read/write_iter() are available])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
@ -96,6 +96,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||||||
ZFS_AC_KERNEL_5ARG_SGET
|
ZFS_AC_KERNEL_5ARG_SGET
|
||||||
ZFS_AC_KERNEL_LSEEK_EXECUTE
|
ZFS_AC_KERNEL_LSEEK_EXECUTE
|
||||||
ZFS_AC_KERNEL_VFS_ITERATE
|
ZFS_AC_KERNEL_VFS_ITERATE
|
||||||
|
ZFS_AC_KERNEL_VFS_RW_ITERATE
|
||||||
|
|
||||||
AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
|
AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
|
||||||
KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
|
KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
|
||||||
|
@ -196,8 +196,7 @@ zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
|
|||||||
static int
|
static int
|
||||||
zpl_aio_fsync(struct kiocb *kiocb, int datasync)
|
zpl_aio_fsync(struct kiocb *kiocb, int datasync)
|
||||||
{
|
{
|
||||||
return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos,
|
return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos, -1, datasync));
|
||||||
kiocb->ki_pos + kiocb->ki_nbytes, datasync));
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#error "Unsupported fops->fsync() implementation"
|
#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
|
static ssize_t
|
||||||
zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
|
zpl_iter_read_common(struct kiocb *kiocb, const struct iovec *iovp,
|
||||||
unsigned long nr_segs, loff_t pos)
|
unsigned long nr_segs, size_t count)
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
struct file *filp = kiocb->ki_filp;
|
struct file *filp = kiocb->ki_filp;
|
||||||
size_t count = kiocb->ki_nbytes;
|
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
size_t alloc_size = sizeof (struct iovec) * nr_segs;
|
size_t alloc_size = sizeof (struct iovec) * nr_segs;
|
||||||
struct iovec *iov_tmp = kmem_alloc(alloc_size, KM_SLEEP);
|
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);
|
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
|
static inline ssize_t
|
||||||
zpl_write_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count,
|
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,
|
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
|
static ssize_t
|
||||||
zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
|
zpl_iter_write_common(struct kiocb *kiocb, const struct iovec *iovp,
|
||||||
unsigned long nr_segs, loff_t pos)
|
unsigned long nr_segs, size_t count)
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
struct file *filp = kiocb->ki_filp;
|
struct file *filp = kiocb->ki_filp;
|
||||||
size_t count = kiocb->ki_nbytes;
|
|
||||||
ssize_t wrote;
|
ssize_t wrote;
|
||||||
size_t alloc_size = sizeof (struct iovec) * nr_segs;
|
size_t alloc_size = sizeof (struct iovec) * nr_segs;
|
||||||
struct iovec *iov_tmp = kmem_alloc(alloc_size, KM_SLEEP);
|
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);
|
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
|
static loff_t
|
||||||
zpl_llseek(struct file *filp, loff_t offset, int whence)
|
zpl_llseek(struct file *filp, loff_t offset, int whence)
|
||||||
{
|
{
|
||||||
@ -778,8 +807,13 @@ const struct file_operations zpl_file_operations = {
|
|||||||
.llseek = zpl_llseek,
|
.llseek = zpl_llseek,
|
||||||
.read = zpl_read,
|
.read = zpl_read,
|
||||||
.write = zpl_write,
|
.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_read = zpl_aio_read,
|
||||||
.aio_write = zpl_aio_write,
|
.aio_write = zpl_aio_write,
|
||||||
|
#endif
|
||||||
.mmap = zpl_mmap,
|
.mmap = zpl_mmap,
|
||||||
.fsync = zpl_fsync,
|
.fsync = zpl_fsync,
|
||||||
.aio_fsync = zpl_aio_fsync,
|
.aio_fsync = zpl_aio_fsync,
|
||||||
|
Loading…
Reference in New Issue
Block a user