Linux 4.14 compat: vfs_read & vfs_write

The kernel_read & kernel_write functions have always wrapped the
vfs_read & vfs_write functions respectively.  However, they could
not be used by vn_rdwr() since the offset wasn't passed as a
pointer.  This prevented us from being able to properly update
the file offset.

Linux 4.14 unexported vfs_read & vfs_write but also changed the
signature of kernel_read & kernel_write to provide the needed
functionality.  Use these updated functions when available.

Reviewed-by: Pritam Baral <pritam@pritambaral.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #656 
Closes #667
This commit is contained in:
Brian Behlendorf
2017-11-15 17:19:23 -08:00
committed by GitHub
parent 35a44fcb8d
commit ed19bccfb6
3 changed files with 105 additions and 17 deletions
+41
View File
@@ -26,6 +26,7 @@
#define _SPL_FILE_COMPAT_H
#include <linux/fs.h>
#include <linux/uaccess.h>
#ifdef HAVE_FDTABLE_HEADER
#include <linux/fdtable.h>
#endif
@@ -70,6 +71,46 @@ spl_filp_fallocate(struct file *fp, int mode, loff_t offset, loff_t len)
return (error);
}
static inline ssize_t
spl_kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
{
#if defined(HAVE_KERNEL_WRITE_PPOS)
return (kernel_write(file, buf, count, pos));
#else
mm_segment_t saved_fs;
ssize_t ret;
saved_fs = get_fs();
set_fs(get_ds());
ret = vfs_write(file, (__force const char __user *)buf, count, pos);
set_fs(saved_fs);
return (ret);
#endif
}
static inline ssize_t
spl_kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
{
#if defined(HAVE_KERNEL_READ_PPOS)
return (kernel_read(file, buf, count, pos));
#else
mm_segment_t saved_fs;
ssize_t ret;
saved_fs = get_fs();
set_fs(get_ds());
ret = vfs_read(file, (void __user *)buf, count, pos);
set_fs(saved_fs);
return (ret);
#endif
}
#ifdef HAVE_2ARGS_VFS_FSYNC
#define spl_filp_fsync(fp, sync) vfs_fsync(fp, sync)
#else