Workaround for linux 4.14

pull/193/head
Jan Houben 7 years ago
parent 878ae99e27
commit 6d0b763c0b
No known key found for this signature in database
GPG Key ID: B7C6B271DEB42D74
  1. 3
      build.sh
  2. 2
      src/kernels/linux-zen.sh
  3. 2
      src/kernels/linux.sh
  4. 6
      src/spl/PKGBUILD.sh
  5. 178
      src/spl/linux4.14.patch

@ -157,6 +157,9 @@ generate_package_files() {
run_cmd_no_output "source ${script_dir}/src/spl/PKGBUILD.sh" run_cmd_no_output "source ${script_dir}/src/spl/PKGBUILD.sh"
msg2 "Creating spl.install" msg2 "Creating spl.install"
run_cmd_no_output "source ${script_dir}/src/spl/spl.install.sh" run_cmd_no_output "source ${script_dir}/src/spl/spl.install.sh"
msg2 "Copying linux4.14.patch"
run_cmd_no_output "cp ${script_dir}/src/spl/linux4.14.patch ${spl_pkgbuild_path}/linux4.14.patch"
msg2 "Creating zfs PKGBUILD" msg2 "Creating zfs PKGBUILD"
run_cmd_no_output "source ${script_dir}/src/zfs/PKGBUILD.sh" run_cmd_no_output "source ${script_dir}/src/zfs/PKGBUILD.sh"

@ -3,7 +3,7 @@ mode_name="zen"
mode_desc="Select and use the packages for the linux-zen kernel" mode_desc="Select and use the packages for the linux-zen kernel"
# Kernel versions for default ZFS packages # Kernel versions for default ZFS packages
pkgrel="1" pkgrel="2"
kernel_version="4.14.3-1" kernel_version="4.14.3-1"
# Kernel version for GIT packages # Kernel version for GIT packages

@ -3,7 +3,7 @@ mode_name="std"
mode_desc="Select and use the packages for the default linux kernel" mode_desc="Select and use the packages for the default linux kernel"
# Kernel versions for default ZFS packages # Kernel versions for default ZFS packages
pkgrel="1" pkgrel="2"
kernel_version="4.14.3-1" kernel_version="4.14.3-1"
# Kernel version for GIT packages # Kernel version for GIT packages

@ -9,8 +9,8 @@ pkgrel=${spl_pkgrel}
makedepends=(${linux_headers_depends} ${spl_makedepends}) makedepends=(${linux_headers_depends} ${spl_makedepends})
arch=("x86_64") arch=("x86_64")
url="http://zfsonlinux.org/" url="http://zfsonlinux.org/"
source=("${spl_src_target}") source=("${spl_src_target}" "linux4.14.patch")
sha256sums=("${spl_src_hash}") sha256sums=("${spl_src_hash}" "ed304df2b990f095496582465f40e509cc918d581420901b205975bbf1926072")
license=("GPL") license=("GPL")
depends=("${spl_utils_pkgname}" "kmod" ${linux_depends}) depends=("${spl_utils_pkgname}" "kmod" ${linux_depends})
@ -56,6 +56,8 @@ EOF
if [[ ${archzfs_package_group} =~ -git$ ]]; then if [[ ${archzfs_package_group} =~ -git$ ]]; then
sed -i "/^build()/i pkgver() {\n cd \"${spl_workdir}\"\n echo \$(git describe --long | sed 's/^spl-//;s/\\\([^-]*-g\\\)/r\\\1/;s/-/./g').${kernel_version_full_pkgver}\n}" ${spl_pkgbuild_path}/PKGBUILD sed -i "/^build()/i pkgver() {\n cd \"${spl_workdir}\"\n echo \$(git describe --long | sed 's/^spl-//;s/\\\([^-]*-g\\\)/r\\\1/;s/-/./g').${kernel_version_full_pkgver}\n}" ${spl_pkgbuild_path}/PKGBUILD
else
sed -i "/^build()/i prepare() {\n cd \"${spl_workdir}\"\n patch -Np1 -i \${srcdir}/linux4.14.patch\n}" ${spl_pkgbuild_path}/PKGBUILD
fi fi
pkgbuild_cleanup "${spl_pkgbuild_path}/PKGBUILD" pkgbuild_cleanup "${spl_pkgbuild_path}/PKGBUILD"

@ -0,0 +1,178 @@
diff --git a/config/spl-build.m4 b/config/spl-build.m4
index 8e9dc99f..7b66f2c8 100644
--- a/config/spl-build.m4
+++ b/config/spl-build.m4
@@ -52,6 +52,8 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
SPL_AC_KMEM_CACHE_CREATE_USERCOPY
SPL_AC_WAIT_QUEUE_ENTRY_T
SPL_AC_WAIT_QUEUE_HEAD_ENTRY
+ SPL_AC_KERNEL_WRITE
+ SPL_AC_KERNEL_READ
])
AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
@@ -1594,3 +1596,61 @@ AC_DEFUN([SPL_AC_WAIT_QUEUE_HEAD_ENTRY], [
AC_MSG_RESULT(no)
])
])
+
+dnl #
+dnl # 4.14 API change
+dnl # kernel_write() which was introduced in 3.9 was updated to take
+dnl # the offset as a pointer which is needed by vn_rdwr().
+dnl #
+AC_DEFUN([SPL_AC_KERNEL_WRITE], [
+ AC_MSG_CHECKING([whether kernel_write() takes loff_t pointer])
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+ SPL_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ ],[
+ struct file *file = NULL;
+ const void *buf = NULL;
+ size_t count = 0;
+ loff_t *pos = NULL;
+ ssize_t ret;
+
+ ret = kernel_write(file, buf, count, pos);
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KERNEL_WRITE_PPOS, 1,
+ [kernel_write() take loff_t pointer])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ EXTRA_KCFLAGS="$tmp_flags"
+])
+
+dnl #
+dnl # 4.14 API change
+dnl # kernel_read() which has existed for forever was updated to take
+dnl # the offset as a pointer which is needed by vn_rdwr().
+dnl #
+AC_DEFUN([SPL_AC_KERNEL_READ], [
+ AC_MSG_CHECKING([whether kernel_read() takes loff_t pointer])
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+ SPL_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ ],[
+ struct file *file = NULL;
+ void *buf = NULL;
+ size_t count = 0;
+ loff_t *pos = NULL;
+ ssize_t ret;
+
+ ret = kernel_read(file, buf, count, pos);
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KERNEL_READ_PPOS, 1,
+ [kernel_read() take loff_t pointer])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ EXTRA_KCFLAGS="$tmp_flags"
+])
diff --git a/include/linux/file_compat.h b/include/linux/file_compat.h
index 7d61ba5f..55ba2cc7 100644
--- a/include/linux/file_compat.h
+++ b/include/linux/file_compat.h
@@ -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
diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c
index 0e4c386a..19b3b76c 100644
--- a/module/spl/spl-vnode.c
+++ b/module/spl/spl-vnode.c
@@ -211,35 +211,22 @@ int
vn_rdwr(uio_rw_t uio, vnode_t *vp, void *addr, ssize_t len, offset_t off,
uio_seg_t seg, int ioflag, rlim64_t x2, void *x3, ssize_t *residp)
{
- loff_t offset;
- mm_segment_t saved_fs;
- struct file *fp;
+ struct file *fp = vp->v_file;
+ loff_t offset = off;
int rc;
ASSERT(uio == UIO_WRITE || uio == UIO_READ);
- ASSERT(vp);
- ASSERT(vp->v_file);
ASSERT(seg == UIO_SYSSPACE);
ASSERT((ioflag & ~FAPPEND) == 0);
- fp = vp->v_file;
-
- offset = off;
if (ioflag & FAPPEND)
offset = fp->f_pos;
- /* Writable user data segment must be briefly increased for this
- * process so we can use the user space read call paths to write
- * in to memory allocated by the kernel. */
- saved_fs = get_fs();
- set_fs(get_ds());
-
if (uio & UIO_WRITE)
- rc = vfs_write(fp, addr, len, &offset);
+ rc = spl_kernel_write(fp, addr, len, &offset);
else
- rc = vfs_read(fp, addr, len, &offset);
+ rc = spl_kernel_read(fp, addr, len, &offset);
- set_fs(saved_fs);
fp->f_pos = offset;
if (rc < 0)
Loading…
Cancel
Save