diff --git a/build.sh b/build.sh index bc9c43d..9129276 100755 --- a/build.sh +++ b/build.sh @@ -157,6 +157,9 @@ generate_package_files() { run_cmd_no_output "source ${script_dir}/src/spl/PKGBUILD.sh" msg2 "Creating spl.install" 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" run_cmd_no_output "source ${script_dir}/src/zfs/PKGBUILD.sh" diff --git a/src/kernels/linux-zen.sh b/src/kernels/linux-zen.sh index 626baf9..18a2884 100644 --- a/src/kernels/linux-zen.sh +++ b/src/kernels/linux-zen.sh @@ -3,7 +3,7 @@ mode_name="zen" mode_desc="Select and use the packages for the linux-zen kernel" # Kernel versions for default ZFS packages -pkgrel="1" +pkgrel="2" kernel_version="4.14.3-1" # Kernel version for GIT packages diff --git a/src/kernels/linux.sh b/src/kernels/linux.sh index 3ca0554..9bf58a9 100644 --- a/src/kernels/linux.sh +++ b/src/kernels/linux.sh @@ -3,7 +3,7 @@ mode_name="std" mode_desc="Select and use the packages for the default linux kernel" # Kernel versions for default ZFS packages -pkgrel="1" +pkgrel="2" kernel_version="4.14.3-1" # Kernel version for GIT packages diff --git a/src/spl/PKGBUILD.sh b/src/spl/PKGBUILD.sh index fb5b4be..36eff61 100755 --- a/src/spl/PKGBUILD.sh +++ b/src/spl/PKGBUILD.sh @@ -9,8 +9,8 @@ pkgrel=${spl_pkgrel} makedepends=(${linux_headers_depends} ${spl_makedepends}) arch=("x86_64") url="http://zfsonlinux.org/" -source=("${spl_src_target}") -sha256sums=("${spl_src_hash}") +source=("${spl_src_target}" "linux4.14.patch") +sha256sums=("${spl_src_hash}" "ed304df2b990f095496582465f40e509cc918d581420901b205975bbf1926072") license=("GPL") depends=("${spl_utils_pkgname}" "kmod" ${linux_depends}) @@ -56,6 +56,8 @@ EOF 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 +else + sed -i "/^build()/i prepare() {\n cd \"${spl_workdir}\"\n patch -Np1 -i \${srcdir}/linux4.14.patch\n}" ${spl_pkgbuild_path}/PKGBUILD fi pkgbuild_cleanup "${spl_pkgbuild_path}/PKGBUILD" diff --git a/src/spl/linux4.14.patch b/src/spl/linux4.14.patch new file mode 100644 index 0000000..b619fdd --- /dev/null +++ b/src/spl/linux4.14.patch @@ -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 ++ ],[ ++ 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 ++ ],[ ++ 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 ++#include + #ifdef HAVE_FDTABLE_HEADER + #include + #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)