From: Brian Behlendorf <behlendorf1@llnl.gov>
Date: Fri, 12 Jul 2019 09:31:20 -0700
Subject: [PATCH] Linux 5.0 compat: SIMD compatibility
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
Restore the SIMD optimization for 4.19.38 LTS, 4.14.120 LTS,
and 5.0 and newer kernels. This is accomplished by leveraging
Closes #8754
Closes #8793
Closes #8965
-(cherry picked from commit e5db31349484e5e859c7a942eb15b98d68ce5b4d)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
cmd/ztest/ztest.c | 3 +
+++ /dev/null
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Brian Behlendorf <behlendorf1@llnl.gov>
-Date: Wed, 17 Jul 2019 09:14:36 -0700
-Subject: [PATCH] Fix CONFIG_X86_DEBUG_FPU build failure
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When CONFIG_X86_DEBUG_FPU is defined the alternatives_patched symbol
-is pulled in as a dependency which results in a build failure. To
-prevent this undefine CONFIG_X86_DEBUG_FPU to disable the WARN_ON_FPU()
-macro and rely on WARN_ON_ONCE debugging checks which were previously
-added.
-
-Reviewed-by: Tony Hutter <hutter2@llnl.gov>
-Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Closes #9041
-Closes #9049
-(cherry picked from commit 095b5412b31c07cad5cec74a4eb5ace011c92b27)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
----
- include/linux/simd_x86.h | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/include/linux/simd_x86.h b/include/linux/simd_x86.h
-index 641f43955..edd456098 100644
---- a/include/linux/simd_x86.h
-+++ b/include/linux/simd_x86.h
-@@ -84,6 +84,15 @@
-
- #if defined(_KERNEL)
-
-+/*
-+ * Disable the WARN_ON_FPU() macro to prevent additional dependencies
-+ * when providing the kfpu_* functions. Relevant warnings are included
-+ * as appropriate and are unconditionally enabled.
-+ */
-+#if defined(CONFIG_X86_DEBUG_FPU) && !defined(KERNEL_EXPORTS_X86_FPU)
-+#undef CONFIG_X86_DEBUG_FPU
-+#endif
-+
- #if defined(HAVE_KERNEL_FPU_API_HEADER)
- #include <asm/fpu/api.h>
- #include <asm/fpu/internal.h>
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Brian Behlendorf <behlendorf1@llnl.gov>
+Date: Tue, 1 Oct 2019 12:50:34 -0700
+Subject: [PATCH] Perform KABI checks in parallel
+
+Reduce the time required for ./configure to perform the needed
+KABI checks by allowing kbuild to compile multiple test cases in
+parallel. This was accomplished by splitting each test's source
+code from the logic handling whether that code could be compiled
+or not.
+
+By introducing this split it's possible to minimize the number of
+times kbuild needs to be invoked. As importantly, it means all of
+the tests can be built in parallel. This does require a little extra
+care since we expect some tests to fail, so the --keep-going (-k)
+option must be provided otherwise some tests may not get compiled.
+Furthermore, since a failure during the kbuild modpost phase will
+result in an early exit; the final linking phase is limited to tests
+which passed the initial compilation and produced an object file.
+
+Once everything has been built the configure script proceeds as
+previously. The only significant difference is that it now merely
+needs to test for the existence of a .ko file to determine the
+result of a given test. This vastly speeds up the entire process.
+
+New test cases should use ZFS_LINUX_TEST_SRC to declare their test
+source code and ZFS_LINUX_TEST_RESULT to check the result. All of
+the existing kernel-*.m4 files have been updated accordingly, see
+config/kernel-current-time.m4 for a basic example. The legacy
+ZFS_LINUX_TRY_COMPILE macro has been kept to handle special cases
+but it's use is not encouraged.
+
+ master (secs) patched (secs)
+ ------------- ----------------
+autogen.sh 61 68
+configure 137 24 (~17% of current run time)
+make -j $(nproc) 44 44
+make rpms 287 150
+
+Reviewed-by: Tony Hutter <hutter2@llnl.gov>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes #8547
+Closes #9132
+Closes #9341
+(cherry picked from commit 608f8749a1055e6769899788e11bd51fd396f9e5)
+Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+---
+ .gitignore | 1 +
+ Makefile.am | 6 +-
+ config/iconv.m4 | 3 +-
+ config/kernel-access-ok-type.m4 | 18 +-
+ config/kernel-acl.m4 | 253 ++++--
+ config/kernel-aio-fsync.m4 | 14 +-
+ config/kernel-automount.m4 | 13 +-
+ config/kernel-bdev-logical-size.m4 | 17 +-
+ config/kernel-bdev-physical-size.m4 | 17 +-
+ config/kernel-bdi.m4 | 78 +-
+ config/kernel-bio-bvec-iter.m4 | 13 +-
+ config/kernel-bio-end-io-t-args.m4 | 34 +-
+ config/kernel-bio-failfast.m4 | 39 +-
+ config/kernel-bio-op.m4 | 74 +-
+ config/kernel-bio-rw-barrier.m4 | 15 +-
+ config/kernel-bio-rw-discard.m4 | 15 +-
+ config/kernel-bio_set_dev.m4 | 51 +-
+ config/kernel-blk-queue-bdi.m4 | 12 +-
+ config/kernel-blk-queue-discard.m4 | 41 +-
+ config/kernel-blk-queue-flags.m4 | 40 +-
+ config/kernel-blk-queue-flush.m4 | 64 +-
+ config/kernel-blk-queue-max-hw-sectors.m4 | 19 +-
+ config/kernel-blk-queue-max-segments.m4 | 21 +-
+ config/kernel-blk-queue-unplug.m4 | 48 +-
+ config/kernel-blkdev-get-by-path.m4 | 15 +-
+ config/kernel-blkdev-reread-part.m4 | 12 +-
+ config/kernel-block-device-operations.m4 | 46 +-
+ config/kernel-clear-inode.m4 | 13 +-
+ config/kernel-commit-metadata.m4 | 15 +-
+ config/kernel-config-defined.m4 | 183 ++++
+ config/kernel-create-nameidata.m4 | 15 +-
+ config/kernel-ctl-table-name.m4 | 12 +-
+ config/kernel-current-time.m4 | 13 +-
+ config/kernel-current_bio_tail.m4 | 30 +-
+ config/kernel-d-make-root.m4 | 17 -
+ config/kernel-d-obtain-alias.m4 | 18 -
+ config/kernel-d-prune-aliases.m4 | 19 -
+ config/kernel-declare-event-class.m4 | 8 +-
+ config/kernel-dentry-operations.m4 | 174 +++-
+ config/kernel-dirty-inode.m4 | 15 +-
+ config/kernel-discard-granularity.m4 | 15 +-
+ config/kernel-elevator-change.m4 | 21 +-
+ config/kernel-encode-fh-inode.m4 | 15 +-
+ config/kernel-evict-inode.m4 | 13 +-
+ config/kernel-fallocate-pax.m4 | 19 -
+ config/kernel-fallocate.m4 | 50 +-
+ config/kernel-file-dentry.m4 | 12 +-
+ config/kernel-file-inode.m4 | 12 +-
+ config/kernel-fmode-t.m4 | 15 +-
+ config/kernel-follow-down-one.m4 | 12 +-
+ config/kernel-fpu.m4 | 99 ++-
+ config/kernel-fst-mount.m4 | 13 +-
+ config/kernel-fsync.m4 | 83 +-
+ config/kernel-generic_io_acct.m4 | 63 +-
+ config/kernel-generic_readlink.m4 | 15 +-
+ config/kernel-get-disk-and-module.m4 | 13 +-
+ config/kernel-get-disk-ro.m4 | 18 +-
+ config/kernel-get-link.m4 | 126 +--
+ config/kernel-global_page_state.m4 | 72 +-
+ config/kernel-group-info.m4 | 15 +-
+ config/kernel-in-compat-syscall.m4 | 12 +-
+ config/kernel-inode-getattr.m4 | 56 +-
+ config/kernel-inode-lock.m4 | 15 +-
+ config/kernel-inode-set-flags.m4 | 12 +-
+ config/kernel-inode-set-iversion.m4 | 12 +-
+ config/kernel-inode-times.m4 | 15 +-
+ config/kernel-insert-inode-locked.m4 | 15 +-
+ config/kernel-invalidate-bdev-args.m4 | 14 +-
+ config/kernel-is_owner_or_cap.m4 | 31 +-
+ config/kernel-kmap-atomic-args.m4 | 14 +-
+ config/kernel-kmem-cache.m4 | 62 +-
+ config/kernel-kstrtoul.m4 | 14 +-
+ config/kernel-ktime_get_coarse_real_ts64.m4 | 15 +-
+ config/kernel-kuid-helpers.m4 | 12 +-
+ config/kernel-kuidgid.m4 | 26 +-
+ config/kernel-lookup-bdev.m4 | 32 +-
+ config/kernel-lookup-nameidata.m4 | 15 +-
+ config/kernel-lseek-execute.m4 | 16 +-
+ config/kernel-make-request-fn.m4 | 77 ++
+ config/kernel-misc-minor.m4 | 2 +-
+ config/kernel-mk-request-fn.m4 | 65 --
+ config/kernel-mkdir-umode-t.m4 | 13 +-
+ config/kernel-mod-param.m4 | 13 +-
+ config/kernel-objtool.m4 | 47 +-
+ config/kernel-open-bdev-exclusive.m4 | 15 +-
+ config/kernel-pde-data.m4 | 14 +-
+ config/kernel-put-link.m4 | 57 +-
+ config/kernel-rename.m4 | 16 +-
+ config/kernel-rw.m4 | 40 +-
+ config/kernel-rwsem.m4 | 65 +-
+ config/kernel-sched.m4 | 53 +-
+ config/kernel-security-inode-init.m4 | 38 +-
+ config/kernel-set-nlink.m4 | 15 +-
+ config/kernel-setattr-prepare.m4 | 16 +-
+ config/kernel-sget-args.m4 | 13 +-
+ config/kernel-show-options.m4 | 21 +-
+ config/kernel-shrink.m4 | 219 +++--
+ config/kernel-submit_bio.m4 | 12 +-
+ config/kernel-super-userns.m4 | 14 +-
+ config/kernel-timer.m4 | 52 +-
+ config/kernel-tmpfile.m4 | 16 +-
+ config/kernel-totalhigh_pages.m4 | 14 +-
+ config/kernel-totalram-pages-func.m4 | 15 +-
+ config/kernel-truncate-range.m4 | 13 +-
+ config/kernel-truncate-setsize.m4 | 15 +-
+ config/kernel-userns-capabilities.m4 | 48 +-
+ ...urange-sleep.m4 => kernel-usleep_range.m4} | 19 +-
+ config/kernel-vfs-direct_IO.m4 | 145 ++--
+ config/kernel-vfs-fsync.m4 | 12 +-
+ config/kernel-vfs-getattr.m4 | 54 +-
+ config/kernel-vfs-iterate.m4 | 84 +-
+ config/kernel-vfs-rw-iterate.m4 | 76 +-
+ config/kernel-wait.m4 | 73 +-
+ config/kernel-xattr-handler.m4 | 442 +++++-----
+ config/kernel-zlib.m4 | 57 +-
+ config/kernel.m4 | 783 +++++++++++-------
+ config/zfs-build.m4 | 11 +
+ config/zfs-meta.m4 | 18 +
+ 118 files changed, 3245 insertions(+), 2127 deletions(-)
+ create mode 100644 config/kernel-config-defined.m4
+ delete mode 100644 config/kernel-d-make-root.m4
+ delete mode 100644 config/kernel-d-obtain-alias.m4
+ delete mode 100644 config/kernel-d-prune-aliases.m4
+ delete mode 100644 config/kernel-fallocate-pax.m4
+ create mode 100644 config/kernel-make-request-fn.m4
+ delete mode 100644 config/kernel-mk-request-fn.m4
+ rename config/{kernel-urange-sleep.m4 => kernel-usleep_range.m4} (60%)
+
+diff --git a/.gitignore b/.gitignore
+index ae9e22dfa..19377a7b1 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -36,6 +36,7 @@ Makefile.in
+ # Top level generated files specific to this top level dir
+ #
+ /bin
++/build
+ /configure
+ /config.log
+ /config.status
+diff --git a/Makefile.am b/Makefile.am
+index 9afe22954..5ee7c20be 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -40,7 +40,7 @@ gitrev:
+ BUILT_SOURCES = gitrev
+
+ distclean-local::
+- -$(RM) -R autom4te*.cache
++ -$(RM) -R autom4te*.cache build
+ -find . \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
+ -o -name .pc -o -name .hg -o -name .git \) -prune -o \
+ \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+@@ -87,8 +87,8 @@ commitcheck:
+ fi
+
+ cstyle:
+- @find ${top_srcdir} -name '*.[hc]' ! -name 'zfs_config.*' \
+- ! -name '*.mod.c' -type f \
++ @find ${top_srcdir} -name build -prune -o -name '*.[hc]' \
++ ! -name 'zfs_config.*' ! -name '*.mod.c' -type f \
+ -exec ${top_srcdir}/scripts/cstyle.pl -cpP {} \+
+
+ shellcheck:
+diff --git a/config/iconv.m4 b/config/iconv.m4
+index a285e9daa..fc915fde6 100644
+--- a/config/iconv.m4
++++ b/config/iconv.m4
+@@ -269,8 +269,7 @@ size_t iconv();
+ [am_cv_proto_iconv_arg1="const"])
+ am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
+ am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
+- AC_MSG_RESULT([
+- $am_cv_proto_iconv])
++ AC_MSG_RESULT([$am_cv_proto_iconv])
+ else
+ dnl When compiling GNU libiconv on a system that does not have iconv yet,
+ dnl pick the POSIX compliant declaration without 'const'.
+diff --git a/config/kernel-access-ok-type.m4 b/config/kernel-access-ok-type.m4
+index 3b2878a55..dc9433458 100644
+--- a/config/kernel-access-ok-type.m4
++++ b/config/kernel-access-ok-type.m4
+@@ -4,17 +4,23 @@ dnl #
+ dnl # - access_ok(type, addr, size)
+ dnl # + access_ok(addr, size)
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_ACCESS_OK_TYPE], [
+- AC_MSG_CHECKING([whether access_ok() has 'type' parameter])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE], [
++ ZFS_LINUX_TEST_SRC([access_ok_type], [
+ #include <linux/uaccess.h>
+ ],[
+- const void __user __attribute__((unused)) *addr = (void *) 0xdeadbeef;
++ const void __user __attribute__((unused)) *addr =
++ (void *) 0xdeadbeef;
+ unsigned long __attribute__((unused)) size = 1;
+ int error __attribute__((unused)) = access_ok(0, addr, size);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_ACCESS_OK_TYPE], [
++ AC_MSG_CHECKING([whether access_ok() has 'type' parameter])
++ ZFS_LINUX_TEST_RESULT([access_ok_type], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_ACCESS_OK_TYPE, 1, [kernel has access_ok with 'type' parameter])
++ AC_DEFINE(HAVE_ACCESS_OK_TYPE, 1,
++ [kernel has access_ok with 'type' parameter])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-acl.m4 b/config/kernel-acl.m4
+index 02cc020e5..68a72872d 100644
+--- a/config/kernel-acl.m4
++++ b/config/kernel-acl.m4
+@@ -3,32 +3,26 @@ dnl # Check if posix_acl_release can be used from a ZFS_META_LICENSED
+ dnl # module. The is_owner_or_cap macro was replaced by
+ dnl # inode_owner_or_capable
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_RELEASE], [
+- AC_MSG_CHECKING([whether posix_acl_release() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_RELEASE], [
++ ZFS_LINUX_TEST_SRC([posix_acl_release], [
+ #include <linux/cred.h>
+ #include <linux/fs.h>
+ #include <linux/posix_acl.h>
+- ],[
+- struct posix_acl* tmp = posix_acl_alloc(1, 0);
++ ], [
++ struct posix_acl *tmp = posix_acl_alloc(1, 0);
+ posix_acl_release(tmp);
+- ],[
++ ], [], [$ZFS_META_LICENSE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_RELEASE], [
++ AC_MSG_CHECKING([whether posix_acl_release() is available])
++ ZFS_LINUX_TEST_RESULT([posix_acl_release], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_POSIX_ACL_RELEASE, 1,
+ [posix_acl_release() is available])
+
+ AC_MSG_CHECKING([whether posix_acl_release() is GPL-only])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
+- #include <linux/cred.h>
+- #include <linux/fs.h>
+- #include <linux/posix_acl.h>
+-
+- MODULE_LICENSE("$ZFS_META_LICENSE");
+- ],[
+- struct posix_acl* tmp = posix_acl_alloc(1, 0);
+- posix_acl_release(tmp);
+- ],[
++ ZFS_LINUX_TEST_RESULT([posix_acl_release_license], [
+ AC_MSG_RESULT(no)
+ ],[
+ AC_MSG_RESULT(yes)
+@@ -46,24 +40,25 @@ dnl # set_cached_acl() and forget_cached_acl() changed from inline to
+ dnl # EXPORT_SYMBOL. In the former case, they may not be usable because of
+ dnl # posix_acl_release. In the latter case, we can always use them.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE], [
+- AC_MSG_CHECKING([whether set_cached_acl() is usable])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_CACHED_ACL_USABLE], [
++ ZFS_LINUX_TEST_SRC([set_cached_acl], [
+ #include <linux/cred.h>
+ #include <linux/fs.h>
+ #include <linux/posix_acl.h>
+-
+- MODULE_LICENSE("$ZFS_META_LICENSE");
+- ],[
++ ], [
+ struct inode *ip = NULL;
+ struct posix_acl *acl = posix_acl_alloc(1, 0);
+ set_cached_acl(ip, ACL_TYPE_ACCESS, acl);
+ forget_cached_acl(ip, ACL_TYPE_ACCESS);
+- ],[
++ ], [], [$ZFS_META_LICENSE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE], [
++ AC_MSG_CHECKING([whether set_cached_acl() is usable])
++ ZFS_LINUX_TEST_RESULT([set_cached_acl_license], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SET_CACHED_ACL_USABLE, 1,
+- [posix_acl_release() is usable])
++ [set_cached_acl() is usable])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -77,14 +72,25 @@ dnl #
+ dnl # 3.14 API change,
+ dnl # posix_acl_chmod() is changed to __posix_acl_chmod()
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
+- AC_MSG_CHECKING([whether posix_acl_chmod exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_CHMOD], [
++ ZFS_LINUX_TEST_SRC([posix_acl_chmod], [
+ #include <linux/fs.h>
+ #include <linux/posix_acl.h>
+ ],[
+ posix_acl_chmod(NULL, 0, 0)
++ ])
++
++ ZFS_LINUX_TEST_SRC([__posix_acl_chmod], [
++ #include <linux/fs.h>
++ #include <linux/posix_acl.h>
+ ],[
++ __posix_acl_chmod(NULL, 0, 0)
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
++ AC_MSG_CHECKING([whether posix_acl_chmod exists])
++ ZFS_LINUX_TEST_RESULT([posix_acl_chmod], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_POSIX_ACL_CHMOD, 1, [posix_acl_chmod() exists])
+ ],[
+@@ -92,14 +98,10 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
+ ])
+
+ AC_MSG_CHECKING([whether __posix_acl_chmod exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- #include <linux/posix_acl.h>
+- ],[
+- __posix_acl_chmod(NULL, 0, 0)
+- ],[
++ ZFS_LINUX_TEST_RESULT([__posix_acl_chmod], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE___POSIX_ACL_CHMOD, 1, [__posix_acl_chmod() exists])
++ AC_DEFINE(HAVE___POSIX_ACL_CHMOD, 1,
++ [__posix_acl_chmod() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -109,18 +111,22 @@ dnl #
+ dnl # 3.1 API change,
+ dnl # posix_acl_equiv_mode now wants an umode_t* instead of a mode_t*
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
+- AC_MSG_CHECKING([whether posix_acl_equiv_mode() wants umode_t])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
++ ZFS_LINUX_TEST_SRC([posix_acl_equiv_mode], [
+ #include <linux/fs.h>
+ #include <linux/posix_acl.h>
+ ],[
+ umode_t tmp;
+ posix_acl_equiv_mode(NULL,&tmp);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
++ AC_MSG_CHECKING([whether posix_acl_equiv_mode() wants umode_t])
++ ZFS_LINUX_TEST_RESULT([posix_acl_equiv_mode], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T, 1,
+- [ posix_acl_equiv_mode wants umode_t*])
++ [posix_acl_equiv_mode wants umode_t*])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -130,9 +136,8 @@ dnl #
+ dnl # 4.8 API change,
+ dnl # The function posix_acl_valid now must be passed a namespace.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [
+- AC_MSG_CHECKING([whether posix_acl_valid() wants user namespace])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS], [
++ ZFS_LINUX_TEST_SRC([posix_acl_valid_with_ns], [
+ #include <linux/fs.h>
+ #include <linux/posix_acl.h>
+ ],[
+@@ -141,7 +146,12 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [
+ int error;
+
+ error = posix_acl_valid(user_ns, acl);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [
++ AC_MSG_CHECKING([whether posix_acl_valid() wants user namespace])
++ ZFS_LINUX_TEST_RESULT([posix_acl_valid_with_ns], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_POSIX_ACL_VALID_WITH_NS, 1,
+ [posix_acl_valid() wants user namespace])
+@@ -155,9 +165,8 @@ dnl # 2.6.27 API change,
+ dnl # Check if inode_operations contains the function permission
+ dnl # and expects the nameidata structure to have been removed.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION], [
+- AC_MSG_CHECKING([whether iops->permission() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION], [
++ ZFS_LINUX_TEST_SRC([inode_operations_permission], [
+ #include <linux/fs.h>
+
+ int permission_fn(struct inode *inode, int mask) { return 0; }
+@@ -166,8 +175,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION], [
+ iops __attribute__ ((unused)) = {
+ .permission = permission_fn,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION], [
++ AC_MSG_CHECKING([whether iops->permission() exists])
++ ZFS_LINUX_TEST_RESULT([inode_operations_permission], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
+ ],[
+@@ -180,9 +193,8 @@ dnl # 2.6.26 API change,
+ dnl # Check if inode_operations contains the function permission
+ dnl # and expects the nameidata structure to be passed.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
+- AC_MSG_CHECKING([whether iops->permission() wants nameidata])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
++ ZFS_LINUX_TEST_SRC([inode_operations_permission_with_nameidata], [
+ #include <linux/fs.h>
+ #include <linux/sched.h>
+
+@@ -193,8 +205,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
+ iops __attribute__ ((unused)) = {
+ .permission = permission_fn,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
++ AC_MSG_CHECKING([whether iops->permission() wants nameidata])
++ ZFS_LINUX_TEST_RESULT([inode_operations_permission_with_nameidata], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
+ AC_DEFINE(HAVE_PERMISSION_WITH_NAMEIDATA, 1,
+@@ -208,9 +224,8 @@ dnl #
+ dnl # 2.6.32 API change,
+ dnl # Check if inode_operations contains the function check_acl
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL], [
+- AC_MSG_CHECKING([whether iops->check_acl() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL], [
++ ZFS_LINUX_TEST_SRC([inode_operations_check_acl], [
+ #include <linux/fs.h>
+
+ int check_acl_fn(struct inode *inode, int mask) { return 0; }
+@@ -219,8 +234,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL], [
+ iops __attribute__ ((unused)) = {
+ .check_acl = check_acl_fn,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL], [
++ AC_MSG_CHECKING([whether iops->check_acl() exists])
++ ZFS_LINUX_TEST_RESULT([inode_operations_check_acl], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
+ ],[
+@@ -232,9 +251,8 @@ dnl #
+ dnl # 2.6.38 API change,
+ dnl # The function check_acl gained a new parameter: flags
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
+- AC_MSG_CHECKING([whether iops->check_acl() wants flags])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
++ ZFS_LINUX_TEST_SRC([inode_operations_check_acl_with_flags], [
+ #include <linux/fs.h>
+
+ int check_acl_fn(struct inode *inode, int mask,
+@@ -244,8 +262,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
+ iops __attribute__ ((unused)) = {
+ .check_acl = check_acl_fn,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
++ AC_MSG_CHECKING([whether iops->check_acl() wants flags])
++ ZFS_LINUX_TEST_RESULT([inode_operations_check_acl_with_flags], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
+ AC_DEFINE(HAVE_CHECK_ACL_WITH_FLAGS, 1,
+@@ -259,9 +281,8 @@ dnl #
+ dnl # 3.1 API change,
+ dnl # Check if inode_operations contains the function get_acl
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
+- AC_MSG_CHECKING([whether iops->get_acl() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
++ ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
+ #include <linux/fs.h>
+
+ struct posix_acl *get_acl_fn(struct inode *inode, int type)
+@@ -271,8 +292,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
+ iops __attribute__ ((unused)) = {
+ .get_acl = get_acl_fn,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
++ AC_MSG_CHECKING([whether iops->get_acl() exists])
++ ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
+ ],[
+@@ -284,20 +309,23 @@ dnl #
+ dnl # 3.14 API change,
+ dnl # Check if inode_operations contains the function set_acl
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
+- AC_MSG_CHECKING([whether iops->set_acl() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
++ ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
+ #include <linux/fs.h>
+
+- int set_acl_fn(struct inode *inode, struct posix_acl *acl, int type)
+- { return 0; }
++ int set_acl_fn(struct inode *inode, struct posix_acl *acl,
++ int type) { return 0; }
+
+ static const struct inode_operations
+ iops __attribute__ ((unused)) = {
+ .set_acl = set_acl_fn,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
++ AC_MSG_CHECKING([whether iops->set_acl() exists])
++ ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
+ ],[
+@@ -311,16 +339,79 @@ dnl # The kernel get_acl will now check cache before calling i_op->get_acl and
+ dnl # do set_cached_acl after that, so i_op->get_acl don't need to do that
+ dnl # anymore.
+ dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_ACL_HANDLE_CACHE], [
++ ZFS_LINUX_TEST_SRC([get_acl_handle_cache], [
++ #include <linux/fs.h>
++ ],[
++ void *sentinel __attribute__ ((unused)) =
++ uncached_acl_sentinel(NULL);
++ ])
++])
++
+ AC_DEFUN([ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE], [
+ AC_MSG_CHECKING([whether uncached_acl_sentinel() exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
++ ZFS_LINUX_TEST_RESULT([get_acl_handle_cache], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_KERNEL_GET_ACL_HANDLE_CACHE, 1,
++ [uncached_acl_sentinel() exists])
+ ],[
+- void *sentinel __attribute__ ((unused)) = uncached_acl_sentinel(NULL);
++ AC_MSG_RESULT(no)
++ ])
++])
++
++dnl #
++dnl # 4.16 kernel: check if struct posix_acl acl.a_refcount is a refcount_t.
++dnl # It's an atomic_t on older kernels.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL_HAS_REFCOUNT], [
++ ZFS_LINUX_TEST_SRC([acl_refcount], [
++ #include <linux/backing-dev.h>
++ #include <linux/refcount.h>
++ #include <linux/posix_acl.h>
+ ],[
++ struct posix_acl acl;
++ refcount_t *r __attribute__ ((unused)) = &acl.a_refcount;
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_ACL_HAS_REFCOUNT], [
++ AC_MSG_CHECKING([whether posix_acl has refcount_t])
++ ZFS_LINUX_TEST_RESULT([acl_refcount], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_KERNEL_GET_ACL_HANDLE_CACHE, 1, [uncached_acl_sentinel() exists])
++ AC_DEFINE(HAVE_ACL_REFCOUNT, 1, [posix_acl has refcount_t])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL], [
++ ZFS_AC_KERNEL_SRC_POSIX_ACL_RELEASE
++ ZFS_AC_KERNEL_SRC_SET_CACHED_ACL_USABLE
++ ZFS_AC_KERNEL_SRC_POSIX_ACL_CHMOD
++ ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
++ ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS
++ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION
++ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
++ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL
++ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
++ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL
++ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL
++ ZFS_AC_KERNEL_SRC_GET_ACL_HANDLE_CACHE
++ ZFS_AC_KERNEL_SRC_ACL_HAS_REFCOUNT
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_ACL], [
++ ZFS_AC_KERNEL_POSIX_ACL_RELEASE
++ ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE
++ ZFS_AC_KERNEL_POSIX_ACL_CHMOD
++ ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
++ ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS
++ ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION
++ ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
++ ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
++ ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
++ ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
++ ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
++ ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE
++ ZFS_AC_KERNEL_ACL_HAS_REFCOUNT
++])
+diff --git a/config/kernel-aio-fsync.m4 b/config/kernel-aio-fsync.m4
+index 41b7a98a6..b4dbf29ba 100644
+--- a/config/kernel-aio-fsync.m4
++++ b/config/kernel-aio-fsync.m4
+@@ -1,21 +1,23 @@
+ dnl #
+ dnl # Linux 4.9-rc5+ ABI, removal of the .aio_fsync field
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_AIO_FSYNC], [
+- AC_MSG_CHECKING([whether fops->aio_fsync() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_AIO_FSYNC], [
++ ZFS_LINUX_TEST_SRC([aio_fsync], [
+ #include <linux/fs.h>
+
+ static const struct file_operations
+ fops __attribute__ ((unused)) = {
+ .aio_fsync = NULL,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_AIO_FSYNC], [
++ AC_MSG_CHECKING([whether fops->aio_fsync() exists])
++ ZFS_LINUX_TEST_RESULT([aio_fsync], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_FILE_AIO_FSYNC, 1, [fops->aio_fsync() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
+-
+diff --git a/config/kernel-automount.m4 b/config/kernel-automount.m4
+index 1ee4c168d..93e14fa8d 100644
+--- a/config/kernel-automount.m4
++++ b/config/kernel-automount.m4
+@@ -5,16 +5,19 @@ dnl # solution to handling automounts. Prior to this cifs/nfs clients
+ dnl # which required automount support would abuse the follow_link()
+ dnl # operation on directories for this purpose.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
+- AC_MSG_CHECKING([whether dops->d_automount() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
++ ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [
+ #include <linux/dcache.h>
+ struct vfsmount *d_automount(struct path *p) { return NULL; }
+ struct dentry_operations dops __attribute__ ((unused)) = {
+ .d_automount = d_automount,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
++ AC_MSG_CHECKING([whether dops->d_automount() exists])
++ ZFS_LINUX_TEST_RESULT([dentry_operations_d_automount], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_AUTOMOUNT, 1, [dops->automount() exists])
+ ],[
+diff --git a/config/kernel-bdev-logical-size.m4 b/config/kernel-bdev-logical-size.m4
+index a6194577a..0de9afd88 100644
+--- a/config/kernel-bdev-logical-size.m4
++++ b/config/kernel-bdev-logical-size.m4
+@@ -5,21 +5,22 @@ dnl # it has been true for a while that there was no strict 1:1 mapping
+ dnl # between physical sector size and logical block size this change makes
+ dnl # it explicit.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE], [
+- AC_MSG_CHECKING([whether bdev_logical_block_size() is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_LOGICAL_BLOCK_SIZE], [
++ ZFS_LINUX_TEST_SRC([bdev_logical_block_size], [
+ #include <linux/blkdev.h>
+ ],[
+ struct block_device *bdev = NULL;
+ bdev_logical_block_size(bdev);
+- ],[
++ ], [$NO_UNUSED_BUT_SET_VARIABLE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE], [
++ AC_MSG_CHECKING([whether bdev_logical_block_size() is available])
++ ZFS_LINUX_TEST_RESULT([bdev_logical_block_size], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BDEV_LOGICAL_BLOCK_SIZE, 1,
+- [bdev_logical_block_size() is available])
++ [bdev_logical_block_size() is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-bdev-physical-size.m4 b/config/kernel-bdev-physical-size.m4
+index 77746ee91..94d8172d3 100644
+--- a/config/kernel-bdev-physical-size.m4
++++ b/config/kernel-bdev-physical-size.m4
+@@ -19,21 +19,22 @@ dnl #
+ dnl # Unfortunately, this interface isn't entirely reliable because
+ dnl # drives are sometimes known to misreport this value.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BDEV_PHYSICAL_BLOCK_SIZE], [
+- AC_MSG_CHECKING([whether bdev_physical_block_size() is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_PHYSICAL_BLOCK_SIZE], [
++ ZFS_LINUX_TEST_SRC([bdev_physical_block_size], [
+ #include <linux/blkdev.h>
+ ],[
+ struct block_device *bdev = NULL;
+ bdev_physical_block_size(bdev);
+- ],[
++ ], [$NO_UNUSED_BUT_SET_VARIABLE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BDEV_PHYSICAL_BLOCK_SIZE], [
++ AC_MSG_CHECKING([whether bdev_physical_block_size() is available])
++ ZFS_LINUX_TEST_RESULT([bdev_physical_block_size], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BDEV_PHYSICAL_BLOCK_SIZE, 1,
+- [bdev_physical_block_size() is available])
++ [bdev_physical_block_size() is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-bdi.m4 b/config/kernel-bdi.m4
+index cb7479ee9..51516332a 100644
+--- a/config/kernel-bdi.m4
++++ b/config/kernel-bdi.m4
+@@ -1,55 +1,81 @@
+ dnl #
+-dnl # 2.6.32 - 2.6.33, bdi_setup_and_register() is not exported.
+-dnl # 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments.
+-dnl # 4.0 - 4.11, bdi_setup_and_register() takes 2 arguments.
+-dnl # 4.12 - x.y, super_setup_bdi_name() new interface.
++dnl # Check available BDI interfaces.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BDI], [
+- AC_MSG_CHECKING([whether super_setup_bdi_name() exists])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BDI], [
++ ZFS_LINUX_TEST_SRC([super_setup_bdi_name], [
+ #include <linux/fs.h>
+ struct super_block sb;
+ ], [
+ char *name = "bdi";
+ atomic_long_t zfs_bdi_seq;
+ int error __attribute__((unused)) =
+- super_setup_bdi_name(&sb, "%.28s-%ld", name, atomic_long_inc_return(&zfs_bdi_seq));
+- ], [super_setup_bdi_name], [fs/super.c], [
++ super_setup_bdi_name(&sb, "%.28s-%ld", name,
++ atomic_long_inc_return(&zfs_bdi_seq));
++ ])
++
++ ZFS_LINUX_TEST_SRC([bdi_setup_and_register], [
++ #include <linux/backing-dev.h>
++ struct backing_dev_info bdi;
++ ], [
++ char *name = "bdi";
++ int error __attribute__((unused)) =
++ bdi_setup_and_register(&bdi, name);
++ ])
++
++ ZFS_LINUX_TEST_SRC([bdi_setup_and_register_3args], [
++ #include <linux/backing-dev.h>
++ struct backing_dev_info bdi;
++ ], [
++ char *name = "bdi";
++ unsigned int cap = BDI_CAP_MAP_COPY;
++ int error __attribute__((unused)) =
++ bdi_setup_and_register(&bdi, name, cap);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BDI], [
++ dnl #
++ dnl # 4.12, super_setup_bdi_name() introduced.
++ dnl #
++ AC_MSG_CHECKING([whether super_setup_bdi_name() exists])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([super_setup_bdi_name],
++ [super_setup_bdi_name], [fs/super.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SUPER_SETUP_BDI_NAME, 1,
+ [super_setup_bdi_name() exits])
+ ], [
+ AC_MSG_RESULT(no)
++
++ dnl #
++ dnl # 4.0 - 4.11, bdi_setup_and_register() takes 2 arguments.
++ dnl #
+ AC_MSG_CHECKING(
+ [whether bdi_setup_and_register() wants 2 args])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
+- #include <linux/backing-dev.h>
+- struct backing_dev_info bdi;
+- ], [
+- char *name = "bdi";
+- int error __attribute__((unused)) =
+- bdi_setup_and_register(&bdi, name);
+- ], [bdi_setup_and_register], [mm/backing-dev.c], [
++ ZFS_LINUX_TEST_RESULT_SYMBOL([bdi_setup_and_register],
++ [bdi_setup_and_register], [mm/backing-dev.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_2ARGS_BDI_SETUP_AND_REGISTER, 1,
+ [bdi_setup_and_register() wants 2 args])
+ ], [
+ AC_MSG_RESULT(no)
++
++ dnl #
++ dnl # 2.6.34 - 3.19, bdi_setup_and_register()
++ dnl # takes 3 arguments.
++ dnl #
+ AC_MSG_CHECKING(
+ [whether bdi_setup_and_register() wants 3 args])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
+- #include <linux/backing-dev.h>
+- struct backing_dev_info bdi;
+- ], [
+- char *name = "bdi";
+- unsigned int cap = BDI_CAP_MAP_COPY;
+- int error __attribute__((unused)) =
+- bdi_setup_and_register(&bdi, name, cap);
+- ], [bdi_setup_and_register], [mm/backing-dev.c], [
++ ZFS_LINUX_TEST_RESULT_SYMBOL(
++ [bdi_setup_and_register_3args],
++ [bdi_setup_and_register], [mm/backing-dev.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_3ARGS_BDI_SETUP_AND_REGISTER, 1,
+ [bdi_setup_and_register() wants 3 args])
+ ], [
++ dnl #
++ dnl # 2.6.32 - 2.6.33, bdi_setup_and_register()
++ dnl # is not exported.
++ dnl #
+ AC_MSG_RESULT(no)
+ ])
+ ])
+diff --git a/config/kernel-bio-bvec-iter.m4 b/config/kernel-bio-bvec-iter.m4
+index 64c989386..f9a99cee6 100644
+--- a/config/kernel-bio-bvec-iter.m4
++++ b/config/kernel-bio-bvec-iter.m4
+@@ -3,18 +3,21 @@ dnl # 3.14 API change,
+ dnl # Immutable biovecs. A number of fields of struct bio are moved to
+ dnl # struct bvec_iter.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BIO_BVEC_ITER], [
+- AC_MSG_CHECKING([whether bio has bi_iter])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_BVEC_ITER], [
++ ZFS_LINUX_TEST_SRC([bio_bvec_iter], [
+ #include <linux/bio.h>
+ ],[
+ struct bio bio;
+ bio.bi_iter.bi_sector = 0;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BIO_BVEC_ITER], [
++ AC_MSG_CHECKING([whether bio has bi_iter])
++ ZFS_LINUX_TEST_RESULT([bio_bvec_iter], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BIO_BVEC_ITER, 1, [bio has bi_iter])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
+-
+diff --git a/config/kernel-bio-end-io-t-args.m4 b/config/kernel-bio-end-io-t-args.m4
+index 3c420cc0c..80a1fbeda 100644
+--- a/config/kernel-bio-end-io-t-args.m4
++++ b/config/kernel-bio-end-io-t-args.m4
+@@ -5,20 +5,21 @@ dnl # bio->bi_error. This also replaces bio->bi_flags value BIO_UPTODATE.
+ dnl # Introduced by torvalds/linux@4246a0b63bd8f56a1469b12eafeb875b1041a451
+ dnl # ("block: add a bi_error field to struct bio").
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BIO_END_IO_T_ARGS], [
+- AC_MSG_CHECKING([whether bio_end_io_t wants 1 arg])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS], [
++ ZFS_LINUX_TEST_SRC([bio_end_io_t_args], [
+ #include <linux/bio.h>
+-
+ void wanted_end_io(struct bio *bio) { return; }
+-
+ bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io;
+- ],[
+- ],[
++ ], [])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BIO_END_IO_T_ARGS], [
++ AC_MSG_CHECKING([whether bio_end_io_t wants 1 arg])
++ ZFS_LINUX_TEST_RESULT([bio_end_io_t_args], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_1ARG_BIO_END_IO_T, 1,
+- [bio_end_io_t wants 1 arg])
+- ],[
++ [bio_end_io_t wants 1 arg])
++ ], [
+ AC_MSG_RESULT(no)
+ ])
+ ])
+@@ -28,16 +29,19 @@ dnl # 4.13 API change
+ dnl # The bio->bi_error field was replaced with bio->bi_status which is an
+ dnl # enum which describes all possible error types.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_STATUS], [
+- AC_MSG_CHECKING([whether bio->bi_status exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_BI_STATUS], [
++ ZFS_LINUX_TEST_SRC([bio_bi_status], [
+ #include <linux/bio.h>
+- ],[
++ ], [
+ struct bio bio __attribute__ ((unused));
+ blk_status_t status __attribute__ ((unused)) = BLK_STS_OK;
+-
+ bio.bi_status = status;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_STATUS], [
++ AC_MSG_CHECKING([whether bio->bi_status exists])
++ ZFS_LINUX_TEST_RESULT([bio_bi_status], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BIO_BI_STATUS, 1, [bio->bi_status exists])
+ ],[
+diff --git a/config/kernel-bio-failfast.m4 b/config/kernel-bio-failfast.m4
+index cfbec0523..0c636f08c 100644
+--- a/config/kernel-bio-failfast.m4
++++ b/config/kernel-bio-failfast.m4
+@@ -3,37 +3,54 @@ dnl # Preferred interface for setting FAILFAST on a bio:
+ dnl # 2.6.28-2.6.35: BIO_RW_FAILFAST_{DEV|TRANSPORT|DRIVER}
+ dnl # >= 2.6.36: REQ_FAILFAST_{DEV|TRANSPORT|DRIVER}
+ dnl #
+-
+-AC_DEFUN([ZFS_AC_KERNEL_BIO_FAILFAST_DTD], [
+- AC_MSG_CHECKING([whether BIO_RW_FAILFAST_* are defined])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_FAILFAST_DTD], [
++ ZFS_LINUX_TEST_SRC([bio_failfast_dtd], [
+ #include <linux/bio.h>
+ ],[
+ int flags __attribute__ ((unused));
+ flags = ((1 << BIO_RW_FAILFAST_DEV) |
+ (1 << BIO_RW_FAILFAST_TRANSPORT) |
+ (1 << BIO_RW_FAILFAST_DRIVER));
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BIO_FAILFAST_DTD], [
++ AC_MSG_CHECKING([whether BIO_RW_FAILFAST_* are defined])
++ ZFS_LINUX_TEST_RESULT([bio_failfast_dtd], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BIO_RW_FAILFAST_DTD, 1,
+- [BIO_RW_FAILFAST_* are defined])
++ [BIO_RW_FAILFAST_* are defined])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
+
+-AC_DEFUN([ZFS_AC_KERNEL_REQ_FAILFAST_MASK], [
+- AC_MSG_CHECKING([whether REQ_FAILFAST_MASK is defined])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_REQ_FAILFAST_MASK], [
++ ZFS_LINUX_TEST_SRC([bio_failfast_mask], [
+ #include <linux/bio.h>
+ ],[
+ int flags __attribute__ ((unused));
+ flags = REQ_FAILFAST_MASK;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_REQ_FAILFAST_MASK], [
++ AC_MSG_CHECKING([whether REQ_FAILFAST_MASK is defined])
++ ZFS_LINUX_TEST_RESULT([bio_failfast_mask], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_REQ_FAILFAST_MASK, 1,
+- [REQ_FAILFAST_MASK is defined])
++ [REQ_FAILFAST_MASK is defined])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_FAILFAST], [
++ ZFS_AC_KERNEL_SRC_BIO_FAILFAST_DTD
++ ZFS_AC_KERNEL_SRC_REQ_FAILFAST_MASK
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BIO_FAILFAST], [
++ ZFS_AC_KERNEL_BIO_FAILFAST_DTD
++ ZFS_AC_KERNEL_REQ_FAILFAST_MASK
++])
+diff --git a/config/kernel-bio-op.m4 b/config/kernel-bio-op.m4
+index 8299e490c..1f2d23791 100644
+--- a/config/kernel-bio-op.m4
++++ b/config/kernel-bio-op.m4
+@@ -5,13 +5,43 @@ dnl # The bio_op() helper was introduced as a replacement for explicitly
+ dnl # checking the bio->bi_rw flags. The following checks are used to
+ dnl # detect if a specific operation is supported.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_DISCARD], [
+- AC_MSG_CHECKING([whether REQ_OP_DISCARD is defined])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_OPS], [
++ ZFS_LINUX_TEST_SRC([req_op_discard], [
+ #include <linux/blk_types.h>
+ ],[
+ int op __attribute__ ((unused)) = REQ_OP_DISCARD;
++ ])
++
++ ZFS_LINUX_TEST_SRC([req_op_secure_erase], [
++ #include <linux/blk_types.h>
+ ],[
++ int op __attribute__ ((unused)) = REQ_OP_SECURE_ERASE;
++ ])
++
++ ZFS_LINUX_TEST_SRC([req_op_flush], [
++ #include <linux/blk_types.h>
++ ],[
++ int op __attribute__ ((unused)) = REQ_OP_FLUSH;
++ ])
++
++ ZFS_LINUX_TEST_SRC([bio_bi_opf], [
++ #include <linux/bio.h>
++ ],[
++ struct bio bio __attribute__ ((unused));
++ bio.bi_opf = 0;
++ ])
++
++ ZFS_LINUX_TEST_SRC([bio_set_op_attrs], [
++ #include <linux/bio.h>
++ ],[
++ struct bio *bio __attribute__ ((unused)) = NULL;
++ bio_set_op_attrs(bio, 0, 0);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_DISCARD], [
++ AC_MSG_CHECKING([whether REQ_OP_DISCARD is defined])
++ ZFS_LINUX_TEST_RESULT([req_op_discard], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_REQ_OP_DISCARD, 1,
+ [REQ_OP_DISCARD is defined])
+@@ -22,11 +52,7 @@ AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_DISCARD], [
+
+ AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE], [
+ AC_MSG_CHECKING([whether REQ_OP_SECURE_ERASE is defined])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/blk_types.h>
+- ],[
+- int op __attribute__ ((unused)) = REQ_OP_SECURE_ERASE;
+- ],[
++ ZFS_LINUX_TEST_RESULT([req_op_secure_erase], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_REQ_OP_SECURE_ERASE, 1,
+ [REQ_OP_SECURE_ERASE is defined])
+@@ -38,14 +64,9 @@ AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE], [
+
+ AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_FLUSH], [
+ AC_MSG_CHECKING([whether REQ_OP_FLUSH is defined])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/blk_types.h>
+- ],[
+- int op __attribute__ ((unused)) = REQ_OP_FLUSH;
+- ],[
++ ZFS_LINUX_TEST_RESULT([req_op_flush], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_REQ_OP_FLUSH, 1,
+- [REQ_OP_FLUSH is defined])
++ AC_DEFINE(HAVE_REQ_OP_FLUSH, 1, [REQ_OP_FLUSH is defined])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -53,12 +74,7 @@ AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_FLUSH], [
+
+ AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_OPF], [
+ AC_MSG_CHECKING([whether bio->bi_opf is defined])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/bio.h>
+- ],[
+- struct bio bio __attribute__ ((unused));
+- bio.bi_opf = 0;
+- ],[
++ ZFS_LINUX_TEST_RESULT([bio_bi_opf], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BIO_BI_OPF, 1, [bio->bi_opf is defined])
+ ],[
+@@ -68,13 +84,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_OPF], [
+
+ AC_DEFUN([ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS], [
+ AC_MSG_CHECKING([whether bio_set_op_attrs is available])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/bio.h>
+- ],[
+- struct bio *bio __attribute__ ((unused)) = NULL;
+-
+- bio_set_op_attrs(bio, 0, 0);
+- ],[
++ ZFS_LINUX_TEST_RESULT([bio_set_op_attrs], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BIO_SET_OP_ATTRS, 1,
+ [bio_set_op_attrs is available])
+@@ -82,3 +92,11 @@ AC_DEFUN([ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS], [
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_BIO_OPS], [
++ ZFS_AC_KERNEL_REQ_OP_DISCARD
++ ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE
++ ZFS_AC_KERNEL_REQ_OP_FLUSH
++ ZFS_AC_KERNEL_BIO_BI_OPF
++ ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS
++])
+diff --git a/config/kernel-bio-rw-barrier.m4 b/config/kernel-bio-rw-barrier.m4
+index bcf0f7ea0..f667d4884 100644
+--- a/config/kernel-bio-rw-barrier.m4
++++ b/config/kernel-bio-rw-barrier.m4
+@@ -3,20 +3,25 @@ dnl # Interface for issuing a discard bio:
+ dnl # 2.6.28-2.6.35: BIO_RW_BARRIER
+ dnl # 2.6.36-3.x: REQ_BARRIER
+ dnl #
+-
++dnl #
+ dnl # Since REQ_BARRIER is a preprocessor definition, there is no need for an
+ dnl # autotools check for it. Also, REQ_BARRIER existed in the request layer
+ dnl # until torvalds/linux@7b6d91daee5cac6402186ff224c3af39d79f4a0e unified the
+ dnl # request layer and bio layer flags, so it would be wrong to assume that
+ dnl # the APIs are mutually exclusive contrary to the typical case.
+-AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_BARRIER], [
+- AC_MSG_CHECKING([whether BIO_RW_BARRIER is defined])
+- ZFS_LINUX_TRY_COMPILE([
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_RW_BARRIER], [
++ ZFS_LINUX_TEST_SRC([bio_rw_barrier], [
+ #include <linux/bio.h>
+ ],[
+ int flags __attribute__ ((unused));
+ flags = BIO_RW_BARRIER;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_BARRIER], [
++ AC_MSG_CHECKING([whether BIO_RW_BARRIER is defined])
++ ZFS_LINUX_TEST_RESULT([bio_rw_barrier], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BIO_RW_BARRIER, 1, [BIO_RW_BARRIER is defined])
+ ],[
+diff --git a/config/kernel-bio-rw-discard.m4 b/config/kernel-bio-rw-discard.m4
+index 0554b9a9d..34a89279c 100644
+--- a/config/kernel-bio-rw-discard.m4
++++ b/config/kernel-bio-rw-discard.m4
+@@ -3,20 +3,25 @@ dnl # Interface for issuing a discard bio:
+ dnl # 2.6.28-2.6.35: BIO_RW_DISCARD
+ dnl # 2.6.36-3.x: REQ_DISCARD
+ dnl #
+-
++dnl #
+ dnl # Since REQ_DISCARD is a preprocessor definition, there is no need for an
+ dnl # autotools check for it. Also, REQ_DISCARD existed in the request layer
+ dnl # until torvalds/linux@7b6d91daee5cac6402186ff224c3af39d79f4a0e unified the
+ dnl # request layer and bio layer flags, so it would be wrong to assume that
+ dnl # the APIs are mutually exclusive contrary to the typical case.
+-AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_DISCARD], [
+- AC_MSG_CHECKING([whether BIO_RW_DISCARD is defined])
+- ZFS_LINUX_TRY_COMPILE([
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_RW_DISCARD], [
++ ZFS_LINUX_TEST_SRC([bio_rw_discard], [
+ #include <linux/bio.h>
+ ],[
+ int flags __attribute__ ((unused));
+ flags = BIO_RW_DISCARD;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_DISCARD], [
++ AC_MSG_CHECKING([whether BIO_RW_DISCARD is defined])
++ ZFS_LINUX_TEST_RESULT([bio_rw_discard], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BIO_RW_DISCARD, 1, [BIO_RW_DISCARD is defined])
+ ],[
+diff --git a/config/kernel-bio_set_dev.m4 b/config/kernel-bio_set_dev.m4
+index 71d47a893..b8e13f35a 100644
+--- a/config/kernel-bio_set_dev.m4
++++ b/config/kernel-bio_set_dev.m4
+@@ -3,51 +3,38 @@ dnl # Linux 4.14 API,
+ dnl #
+ dnl # The bio_set_dev() helper macro was introduced as part of the transition
+ dnl # to have struct gendisk in struct bio.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV_MACRO], [
+- AC_MSG_CHECKING([whether bio_set_dev() exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/bio.h>
+- #include <linux/fs.h>
+- ],[
+- struct block_device *bdev = NULL;
+- struct bio *bio = NULL;
+- bio_set_dev(bio, bdev);
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_BIO_SET_DEV, 1, [bio_set_dev() exists])
+- ],[
+- AC_MSG_RESULT(no)
+- ])
+-])
+-
+ dnl #
+ dnl # Linux 5.0 API,
+ dnl #
+ dnl # The bio_set_dev() helper macro was updated to internally depend on
+ dnl # bio_associate_blkg() symbol which is exported GPL-only.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV_GPL_ONLY], [
+- AC_MSG_CHECKING([whether bio_set_dev() is GPL-only])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SET_DEV], [
++ ZFS_LINUX_TEST_SRC([bio_set_dev], [
+ #include <linux/bio.h>
+ #include <linux/fs.h>
+- MODULE_LICENSE("$ZFS_META_LICENSE");
+ ],[
+ struct block_device *bdev = NULL;
+ struct bio *bio = NULL;
+ bio_set_dev(bio, bdev);
+- ],[
+- AC_MSG_RESULT(no)
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_BIO_SET_DEV_GPL_ONLY, 1,
+- [bio_set_dev() GPL-only])
+- ])
++ ], [], [$ZFS_META_LICENSE])
+ ])
+
+ AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV], [
+- ZFS_AC_KERNEL_BIO_SET_DEV_MACRO
+- ZFS_AC_KERNEL_BIO_SET_DEV_GPL_ONLY
++ AC_MSG_CHECKING([whether bio_set_dev() is available])
++ ZFS_LINUX_TEST_RESULT([bio_set_dev], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_BIO_SET_DEV, 1, [bio_set_dev() is available])
++
++ AC_MSG_CHECKING([whether bio_set_dev() is GPL-only])
++ ZFS_LINUX_TEST_RESULT([bio_set_dev_license], [
++ AC_MSG_RESULT(no)
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_BIO_SET_DEV_GPL_ONLY, 1,
++ [bio_set_dev() GPL-only])
++ ])
++ ],[
++ AC_MSG_RESULT(no)
++ ])
+ ])
+diff --git a/config/kernel-blk-queue-bdi.m4 b/config/kernel-blk-queue-bdi.m4
+index 816471166..28241c494 100644
+--- a/config/kernel-blk-queue-bdi.m4
++++ b/config/kernel-blk-queue-bdi.m4
+@@ -2,15 +2,19 @@ dnl #
+ dnl # 2.6.32 - 4.11, statically allocated bdi in request_queue
+ dnl # 4.12 - x.y, dynamically allocated bdi in request_queue
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [
+- AC_MSG_CHECKING([whether blk_queue bdi is dynamic])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI], [
++ ZFS_LINUX_TEST_SRC([blk_queue_bdi], [
+ #include <linux/blkdev.h>
+ ],[
+ struct request_queue q;
+ struct backing_dev_info bdi;
+ q.backing_dev_info = &bdi;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [
++ AC_MSG_CHECKING([whether blk_queue bdi is dynamic])
++ ZFS_LINUX_TEST_RESULT([blk_queue_bdi], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_BDI_DYNAMIC, 1,
+ [blk queue backing_dev_info is dynamic])
+diff --git a/config/kernel-blk-queue-discard.m4 b/config/kernel-blk-queue-discard.m4
+index addbba814..85a29356d 100644
+--- a/config/kernel-blk-queue-discard.m4
++++ b/config/kernel-blk-queue-discard.m4
+@@ -2,16 +2,19 @@ dnl #
+ dnl # 2.6.32 - 4.x API,
+ dnl # blk_queue_discard()
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISCARD], [
+- AC_MSG_CHECKING([whether blk_queue_discard() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [
++ ZFS_LINUX_TEST_SRC([blk_queue_discard], [
+ #include <linux/blkdev.h>
+ ],[
+ struct request_queue *q __attribute__ ((unused)) = NULL;
+ int value __attribute__ ((unused));
+-
+ value = blk_queue_discard(q);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISCARD], [
++ AC_MSG_CHECKING([whether blk_queue_discard() is available])
++ ZFS_LINUX_TEST_RESULT([blk_queue_discard], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_DISCARD, 1,
+ [blk_queue_discard() is available])
+@@ -30,16 +33,27 @@ dnl #
+ dnl # 2.6.x - 2.6.35 API,
+ dnl # Unsupported by kernel
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
+- AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE], [
++ ZFS_LINUX_TEST_SRC([blk_queue_secure_erase], [
+ #include <linux/blkdev.h>
+ ],[
+ struct request_queue *q __attribute__ ((unused)) = NULL;
+ int value __attribute__ ((unused));
+-
+ value = blk_queue_secure_erase(q);
++ ])
++
++ ZFS_LINUX_TEST_SRC([blk_queue_secdiscard], [
++ #include <linux/blkdev.h>
+ ],[
++ struct request_queue *q __attribute__ ((unused)) = NULL;
++ int value __attribute__ ((unused));
++ value = blk_queue_secdiscard(q);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
++ AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
++ ZFS_LINUX_TEST_RESULT([blk_queue_secure_erase], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_SECURE_ERASE, 1,
+ [blk_queue_secure_erase() is available])
+@@ -47,14 +61,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
+ AC_MSG_RESULT(no)
+
+ AC_MSG_CHECKING([whether blk_queue_secdiscard() is available])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/blkdev.h>
+- ],[
+- struct request_queue *q __attribute__ ((unused)) = NULL;
+- int value __attribute__ ((unused));
+-
+- value = blk_queue_secdiscard(q);
+- ],[
++ ZFS_LINUX_TEST_RESULT([blk_queue_secdiscard], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_SECDISCARD, 1,
+ [blk_queue_secdiscard() is available])
+diff --git a/config/kernel-blk-queue-flags.m4 b/config/kernel-blk-queue-flags.m4
+index b570245c7..9d4dfc159 100644
+--- a/config/kernel-blk-queue-flags.m4
++++ b/config/kernel-blk-queue-flags.m4
+@@ -3,36 +3,54 @@ dnl # API change
+ dnl # https://github.com/torvalds/linux/commit/8814ce8
+ dnl # Introduction of blk_queue_flag_set and blk_queue_flag_clear
+ dnl #
+-
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET], [
+- AC_MSG_CHECKING([whether blk_queue_flag_set() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET], [
++ ZFS_LINUX_TEST_SRC([blk_queue_flag_set], [
+ #include <linux/kernel.h>
+ #include <linux/blkdev.h>
+ ],[
+ struct request_queue *q = NULL;
+ blk_queue_flag_set(0, q);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET], [
++ AC_MSG_CHECKING([whether blk_queue_flag_set() exists])
++ ZFS_LINUX_TEST_RESULT([blk_queue_flag_set], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_BLK_QUEUE_FLAG_SET, 1, [blk_queue_flag_set() exists])
++ AC_DEFINE(HAVE_BLK_QUEUE_FLAG_SET, 1,
++ [blk_queue_flag_set() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
+
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR], [
+- AC_MSG_CHECKING([whether blk_queue_flag_clear() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_CLEAR], [
++ ZFS_LINUX_TEST_SRC([blk_queue_flag_clear], [
+ #include <linux/kernel.h>
+ #include <linux/blkdev.h>
+ ],[
+ struct request_queue *q = NULL;
+ blk_queue_flag_clear(0, q);
+- ],[
++ ])
++])
+
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR], [
++ AC_MSG_CHECKING([whether blk_queue_flag_clear() exists])
++ ZFS_LINUX_TEST_RESULT([blk_queue_flag_clear], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_BLK_QUEUE_FLAG_CLEAR, 1, [blk_queue_flag_clear() exists])
++ AC_DEFINE(HAVE_BLK_QUEUE_FLAG_CLEAR, 1,
++ [blk_queue_flag_clear() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAGS], [
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_CLEAR
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAGS], [
++ ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET
++ ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR
++])
+diff --git a/config/kernel-blk-queue-flush.m4 b/config/kernel-blk-queue-flush.m4
+index 1baab83a4..b546d9400 100644
+--- a/config/kernel-blk-queue-flush.m4
++++ b/config/kernel-blk-queue-flush.m4
+@@ -9,35 +9,37 @@ dnl # there we implement our own compatibility function, otherwise
+ dnl # we use the function. The hope is that long term this function
+ dnl # will be opened up.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
+- AC_MSG_CHECKING([whether blk_queue_flush() is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLUSH], [
++ ZFS_LINUX_TEST_SRC([blk_queue_flush], [
+ #include <linux/blkdev.h>
+- ],[
++ ], [
+ struct request_queue *q = NULL;
+ (void) blk_queue_flush(q, REQ_FLUSH);
+- ],[
++ ], [$NO_UNUSED_BUT_SET_VARIABLE], [$ZFS_META_LICENSE])
++
++ ZFS_LINUX_TEST_SRC([blk_queue_write_cache], [
++ #include <linux/kernel.h>
++ #include <linux/blkdev.h>
++ ], [
++ struct request_queue *q = NULL;
++ blk_queue_write_cache(q, true, true);
++ ], [$NO_UNUSED_BUT_SET_VARIABLE], [$ZFS_META_LICENSE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
++ AC_MSG_CHECKING([whether blk_queue_flush() is available])
++ ZFS_LINUX_TEST_RESULT([blk_queue_flush], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1,
+- [blk_queue_flush() is available])
++ [blk_queue_flush() is available])
+
+ AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
+- #include <linux/blkdev.h>
+-
+- MODULE_LICENSE("$ZFS_META_LICENSE");
+- ],[
+- struct request_queue *q = NULL;
+- (void) blk_queue_flush(q, REQ_FLUSH);
+- ],[
++ ZFS_LINUX_TEST_RESULT([blk_queue_flush_license], [
+ AC_MSG_RESULT(no)
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
+- [blk_queue_flush() is GPL-only])
++ [blk_queue_flush() is GPL-only])
+ ])
+ ],[
+ AC_MSG_RESULT(no)
+@@ -48,38 +50,20 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
+ dnl # Replace blk_queue_flush with blk_queue_write_cache
+ dnl #
+ AC_MSG_CHECKING([whether blk_queue_write_cache() exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/kernel.h>
+- #include <linux/blkdev.h>
+-
+- ],[
+- struct request_queue *q = NULL;
+- blk_queue_write_cache(q, true, true);
+- ],[
++ ZFS_LINUX_TEST_RESULT([blk_queue_write_cache], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE, 1,
+- [blk_queue_write_cache() exists])
++ [blk_queue_write_cache() exists])
+
+ AC_MSG_CHECKING([whether blk_queue_write_cache() is GPL-only])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/kernel.h>
+- #include <linux/module.h>
+- #include <linux/blkdev.h>
+-
+- MODULE_LICENSE("$ZFS_META_LICENSE");
+- ],[
+- struct request_queue *q = NULL;
+- blk_queue_write_cache(q, true, true);
+- ],[
++ ZFS_LINUX_TEST_RESULT([blk_queue_write_cache_license], [
+ AC_MSG_RESULT(no)
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY, 1,
+- [blk_queue_write_cache() is GPL-only])
++ [blk_queue_write_cache() is GPL-only])
+ ])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+-
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-blk-queue-max-hw-sectors.m4 b/config/kernel-blk-queue-max-hw-sectors.m4
+index 2f5515dc6..7387f84de 100644
+--- a/config/kernel-blk-queue-max-hw-sectors.m4
++++ b/config/kernel-blk-queue-max-hw-sectors.m4
+@@ -2,21 +2,22 @@ dnl #
+ dnl # 2.6.34 API change
+ dnl # blk_queue_max_hw_sectors() replaces blk_queue_max_sectors().
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS], [
+- AC_MSG_CHECKING([whether blk_queue_max_hw_sectors() is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_HW_SECTORS], [
++ ZFS_LINUX_TEST_SRC([blk_queue_max_hw_sectors], [
+ #include <linux/blkdev.h>
+- ],[
++ ], [
+ struct request_queue *q = NULL;
+ (void) blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
+- ],[
++ ], [$NO_UNUSED_BUT_SET_VARIABLE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS], [
++ AC_MSG_CHECKING([whether blk_queue_max_hw_sectors() is available])
++ ZFS_LINUX_TEST_RESULT([blk_queue_max_hw_sectors], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_MAX_HW_SECTORS, 1,
+- [blk_queue_max_hw_sectors() is available])
++ [blk_queue_max_hw_sectors() is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-blk-queue-max-segments.m4 b/config/kernel-blk-queue-max-segments.m4
+index b2a40423a..1e4092df9 100644
+--- a/config/kernel-blk-queue-max-segments.m4
++++ b/config/kernel-blk-queue-max-segments.m4
+@@ -3,21 +3,22 @@ dnl # 2.6.34 API change
+ dnl # blk_queue_max_segments() consolidates blk_queue_max_hw_segments()
+ dnl # and blk_queue_max_phys_segments().
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
+- AC_MSG_CHECKING([whether blk_queue_max_segments() is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_SEGMENTS], [
++ ZFS_LINUX_TEST_SRC([blk_queue_max_segments], [
+ #include <linux/blkdev.h>
+- ],[
++ ], [
+ struct request_queue *q = NULL;
+ (void) blk_queue_max_segments(q, BLK_MAX_SEGMENTS);
+- ],[
++ ], [$NO_UNUSED_BUT_SET_VARIABLE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
++ AC_MSG_CHECKING([whether blk_queue_max_segments() is available])
++ ZFS_LINUX_TEST_RESULT([blk_queue_max_segments], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_MAX_SEGMENTS, 1,
+- [blk_queue_max_segments() is available])
+- ],[
++ [blk_queue_max_segments() is available])
++ ], [
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-blk-queue-unplug.m4 b/config/kernel-blk-queue-unplug.m4
+index 075fbccd1..f5d1814b8 100644
+--- a/config/kernel-blk-queue-unplug.m4
++++ b/config/kernel-blk-queue-unplug.m4
+@@ -2,43 +2,53 @@ dnl #
+ dnl # 2.6.32-2.6.35 API - The BIO_RW_UNPLUG enum can be used as a hint
+ dnl # to unplug the queue.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG], [
+- AC_MSG_CHECKING([whether the BIO_RW_UNPLUG enum is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_RW_UNPLUG], [
++ ZFS_LINUX_TEST_SRC([blk_queue_bio_rw_unplug], [
+ #include <linux/blkdev.h>
+ ],[
+- extern enum bio_rw_flags rw;
++ enum bio_rw_flags rw __attribute__ ((unused)) = BIO_RW_UNPLUG;
++ ])
++])
+
+- rw = BIO_RW_UNPLUG;
+- ],[
++AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_UNPLUG], [
++ AC_MSG_CHECKING([whether the BIO_RW_UNPLUG enum is available])
++ ZFS_LINUX_TEST_RESULT([blk_queue_bio_rw_unplug], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG, 1,
+- [BIO_RW_UNPLUG is available])
++ [BIO_RW_UNPLUG is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+
+-AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BLK_PLUG], [
+- AC_MSG_CHECKING([whether struct blk_plug is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_PLUG], [
++ ZFS_LINUX_TEST_SRC([blk_plug], [
+ #include <linux/blkdev.h>
+ ],[
+- struct blk_plug plug;
++ struct blk_plug plug __attribute__ ((unused));
+
+ blk_start_plug(&plug);
+ blk_finish_plug(&plug);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_PLUG], [
++ AC_MSG_CHECKING([whether struct blk_plug is available])
++ ZFS_LINUX_TEST_RESULT([blk_plug], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_HAVE_BLK_PLUG, 1,
+- [struct blk_plug is available])
++ [struct blk_plug is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG], [
++ ZFS_AC_KERNEL_SRC_BIO_RW_UNPLUG
++ ZFS_AC_KERNEL_SRC_BLK_PLUG
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_PLUG], [
++ ZFS_AC_KERNEL_BIO_RW_UNPLUG
++ ZFS_AC_KERNEL_BLK_PLUG
+ ])
+diff --git a/config/kernel-blkdev-get-by-path.m4 b/config/kernel-blkdev-get-by-path.m4
+index 40ecc06b6..fb0cea6af 100644
+--- a/config/kernel-blkdev-get-by-path.m4
++++ b/config/kernel-blkdev-get-by-path.m4
+@@ -3,16 +3,21 @@ dnl # 2.6.38 API change
+ dnl # open_bdev_exclusive() changed to blkdev_get_by_path()
+ dnl # close_bdev_exclusive() changed to blkdev_put()
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH],
+- [AC_MSG_CHECKING([whether blkdev_get_by_path() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH], [
++ ZFS_LINUX_TEST_SRC([blkdev_get_by_path], [
+ #include <linux/fs.h>
+ ], [
+ blkdev_get_by_path(NULL, 0, NULL);
+- ], [blkdev_get_by_path], [fs/block_dev.c], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
++ AC_MSG_CHECKING([whether blkdev_get_by_path() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([blkdev_get_by_path],
++ [blkdev_get_by_path], [fs/block_dev.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLKDEV_GET_BY_PATH, 1,
+- [blkdev_get_by_path() is available])
++ [blkdev_get_by_path() is available])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-blkdev-reread-part.m4 b/config/kernel-blkdev-reread-part.m4
+index 5664769a3..1bf1e7c3a 100644
+--- a/config/kernel-blkdev-reread-part.m4
++++ b/config/kernel-blkdev-reread-part.m4
+@@ -2,16 +2,20 @@ dnl #
+ dnl # 4.1 API, exported blkdev_reread_part() symbol, backported to the
+ dnl # 3.10.0 CentOS 7.x enterprise kernels.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_REREAD_PART], [
+- AC_MSG_CHECKING([whether blkdev_reread_part() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART], [
++ ZFS_LINUX_TEST_SRC([blkdev_reread_part], [
+ #include <linux/fs.h>
+ ], [
+ struct block_device *bdev = NULL;
+ int error;
+
+ error = blkdev_reread_part(bdev);
+- ], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_REREAD_PART], [
++ AC_MSG_CHECKING([whether blkdev_reread_part() is available])
++ ZFS_LINUX_TEST_RESULT([blkdev_reread_part], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLKDEV_REREAD_PART, 1,
+ [blkdev_reread_part() is available])
+diff --git a/config/kernel-block-device-operations.m4 b/config/kernel-block-device-operations.m4
+index 5f2811c15..c3d5eec52 100644
+--- a/config/kernel-block-device-operations.m4
++++ b/config/kernel-block-device-operations.m4
+@@ -1,11 +1,8 @@
+ dnl #
+ dnl # 2.6.38 API change
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
+- AC_MSG_CHECKING([whether bops->check_events() exists])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
++ ZFS_LINUX_TEST_SRC([block_device_operations_check_events], [
+ #include <linux/blkdev.h>
+
+ unsigned int blk_check_events(struct gendisk *disk,
+@@ -15,25 +12,25 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
+ bops __attribute__ ((unused)) = {
+ .check_events = blk_check_events,
+ };
+- ],[
+- ],[
++ ], [], [$NO_UNUSED_BUT_SET_VARIABLE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
++ AC_MSG_CHECKING([whether bops->check_events() exists])
++ ZFS_LINUX_TEST_RESULT([block_device_operations_check_events], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS, 1,
+ [bops->check_events() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+
+ dnl #
+ dnl # 3.10.x API change
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
+- AC_MSG_CHECKING([whether bops->release() is void])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
++ ZFS_LINUX_TEST_SRC([block_device_operations_release_void], [
+ #include <linux/blkdev.h>
+
+ void blk_release(struct gendisk *g, fmode_t mode) { return; }
+@@ -45,13 +42,26 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
+ .ioctl = NULL,
+ .compat_ioctl = NULL,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT(void)
++ ], [], [$NO_UNUSED_BUT_SET_VARIABLE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
++ AC_MSG_CHECKING([whether bops->release() is void])
++ ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [
++ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID, 1,
+ [bops->release() returns void])
+ ],[
+- AC_MSG_RESULT(int)
++ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [
++ ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
++ ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS], [
++ ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
++ ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
+ ])
+diff --git a/config/kernel-clear-inode.m4 b/config/kernel-clear-inode.m4
+index 8d880fcd8..3f454d7ec 100644
+--- a/config/kernel-clear-inode.m4
++++ b/config/kernel-clear-inode.m4
+@@ -19,13 +19,18 @@ dnl # Therefore, to ensure we have the correct API we only allow the
+ dnl # clear_inode() compatibility code to be defined iff the evict_inode()
+ dnl # functionality is also detected.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CLEAR_INODE],
+- [AC_MSG_CHECKING([whether clear_inode() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CLEAR_INODE], [
++ ZFS_LINUX_TEST_SRC([clear_inode], [
+ #include <linux/fs.h>
+ ], [
+ clear_inode(NULL);
+- ], [clear_inode], [fs/inode.c], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CLEAR_INODE], [
++ AC_MSG_CHECKING([whether clear_inode() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([clear_inode],
++ [clear_inode], [fs/inode.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CLEAR_INODE, 1, [clear_inode() is available])
+ ], [
+diff --git a/config/kernel-commit-metadata.m4 b/config/kernel-commit-metadata.m4
+index b66a16fd2..9bc3b6622 100644
+--- a/config/kernel-commit-metadata.m4
++++ b/config/kernel-commit-metadata.m4
+@@ -4,19 +4,22 @@ dnl # Added eops->commit_metadata() callback to allow the underlying
+ dnl # filesystem to determine the most efficient way to commit the inode.
+ dnl # Prior to this the nfs server would issue an explicit fsync().
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_COMMIT_METADATA], [
+- AC_MSG_CHECKING([whether eops->commit_metadata() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_COMMIT_METADATA], [
++ ZFS_LINUX_TEST_SRC([export_operations_commit_metadata], [
+ #include <linux/exportfs.h>
+ int commit_metadata(struct inode *inode) { return 0; }
+ static struct export_operations eops __attribute__ ((unused))={
+ .commit_metadata = commit_metadata,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_COMMIT_METADATA], [
++ AC_MSG_CHECKING([whether eops->commit_metadata() exists])
++ ZFS_LINUX_TEST_RESULT([export_operations_commit_metadata], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_COMMIT_METADATA, 1,
+- [eops->commit_metadata() exists])
++ [eops->commit_metadata() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-config-defined.m4 b/config/kernel-config-defined.m4
+new file mode 100644
+index 000000000..0ee4231cc
+--- /dev/null
++++ b/config/kernel-config-defined.m4
+@@ -0,0 +1,183 @@
++dnl #
++dnl # Certain kernel build options are not supported. These must be
++dnl # detected at configure time and cause a build failure. Otherwise
++dnl # modules may be successfully built that behave incorrectly.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEFINED], [
++ AS_IF([test "x$cross_compiling" != xyes], [
++ AC_RUN_IFELSE([
++ AC_LANG_PROGRAM([
++ #include "$LINUX/include/linux/license.h"
++ ], [
++ return !license_is_gpl_compatible(
++ "$ZFS_META_LICENSE");
++ ])
++ ], [
++ AC_DEFINE([ZFS_IS_GPL_COMPATIBLE], [1],
++ [Define to 1 if GPL-only symbols can be used])
++ ], [
++ ])
++ ])
++
++ ZFS_AC_KERNEL_SRC_CONFIG_THREAD_SIZE
++ ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC
++ ZFS_AC_KERNEL_SRC_CONFIG_TRIM_UNUSED_KSYMS
++ ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_INFLATE
++ ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE
++
++ AC_MSG_CHECKING([for kernel config option compatibility])
++ ZFS_LINUX_TEST_COMPILE_ALL([config])
++ AC_MSG_RESULT([done])
++
++ ZFS_AC_KERNEL_CONFIG_THREAD_SIZE
++ ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC
++ ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS
++ ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE
++ ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE
++])
++
++dnl #
++dnl # Check configured THREAD_SIZE
++dnl #
++dnl # The stack size will vary by architecture, but as of Linux 3.15 on x86_64
++dnl # the default thread stack size was increased to 16K from 8K. Therefore,
++dnl # on newer kernels and some architectures stack usage optimizations can be
++dnl # conditionally applied to improve performance without negatively impacting
++dnl # stability.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_THREAD_SIZE], [
++ ZFS_LINUX_TEST_SRC([config_thread_size], [
++ #include <linux/module.h>
++ ],[
++ #if (THREAD_SIZE < 16384)
++ #error "THREAD_SIZE is less than 16K"
++ #endif
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CONFIG_THREAD_SIZE], [
++ AC_MSG_CHECKING([whether kernel was built with 16K or larger stacks])
++ ZFS_LINUX_TEST_RESULT([config_thread_size], [
++ AC_MSG_RESULT([yes])
++ AC_DEFINE(HAVE_LARGE_STACKS, 1, [kernel has large stacks])
++ ],[
++ AC_MSG_RESULT([no])
++ ])
++])
++
++dnl #
++dnl # Check CONFIG_DEBUG_LOCK_ALLOC
++dnl #
++dnl # This is typically only set for debug kernels because it comes with
++dnl # a performance penalty. However, when it is set it maps the non-GPL
++dnl # symbol mutex_lock() to the GPL-only mutex_lock_nested() symbol.
++dnl # This will cause a failure at link time which we'd rather know about
++dnl # at compile time.
++dnl #
++dnl # Since we plan to pursue making mutex_lock_nested() a non-GPL symbol
++dnl # with the upstream community we add a check to detect this case.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC], [
++ ZFS_LINUX_TEST_SRC([config_debug_lock_alloc], [
++ #include <linux/mutex.h>
++ ],[
++ struct mutex lock;
++
++ mutex_init(&lock);
++ mutex_lock(&lock);
++ mutex_unlock(&lock);
++ ], [], [$ZFS_META_LICENSE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [
++ AC_MSG_CHECKING([whether mutex_lock() is GPL-only])
++ ZFS_LINUX_TEST_RESULT([config_debug_lock_alloc], [
++ AC_MSG_RESULT(no)
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_MSG_ERROR([
++ *** Kernel built with CONFIG_DEBUG_LOCK_ALLOC which is incompatible
++ *** with the CDDL license and will prevent the module linking stage
++ *** from succeeding. You must rebuild your kernel without this
++ *** option enabled.])
++ ])
++])
++
++dnl #
++dnl # Check CONFIG_TRIM_UNUSED_KSYMS
++dnl #
++dnl # Verify the kernel has CONFIG_TRIM_UNUSED_KSYMS disabled.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_TRIM_UNUSED_KSYMS], [
++ ZFS_LINUX_TEST_SRC([config_trim_unusued_ksyms], [
++ #if defined(CONFIG_TRIM_UNUSED_KSYMS)
++ #error CONFIG_TRIM_UNUSED_KSYMS not defined
++ #endif
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS], [
++ AC_MSG_CHECKING([whether CONFIG_TRIM_UNUSED_KSYM is disabled])
++ ZFS_LINUX_TEST_RESULT([config_trim_unusued_ksyms], [
++ AC_MSG_RESULT([yes])
++ ],[
++ AC_MSG_RESULT([no])
++ AS_IF([test "x$enable_linux_builtin" != xyes], [
++ AC_MSG_ERROR([
++ *** This kernel has unused symbols trimming enabled, please disable.
++ *** Rebuild the kernel with CONFIG_TRIM_UNUSED_KSYMS=n set.])
++ ])
++ ])
++])
++
++dnl #
++dnl # Check CONFIG_ZLIB_INFLATE
++dnl #
++dnl # Verify the kernel has CONFIG_ZLIB_INFLATE support enabled.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_INFLATE], [
++ ZFS_LINUX_TEST_SRC([config_zlib_inflate], [
++ #if !defined(CONFIG_ZLIB_INFLATE) && \
++ !defined(CONFIG_ZLIB_INFLATE_MODULE)
++ #error CONFIG_ZLIB_INFLATE not defined
++ #endif
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE], [
++ AC_MSG_CHECKING([whether CONFIG_ZLIB_INFLATE is defined])
++ ZFS_LINUX_TEST_RESULT([config_zlib_inflate], [
++ AC_MSG_RESULT([yes])
++ ],[
++ AC_MSG_RESULT([no])
++ AC_MSG_ERROR([
++ *** This kernel does not include the required zlib inflate support.
++ *** Rebuild the kernel with CONFIG_ZLIB_INFLATE=y|m set.])
++ ])
++])
++
++dnl #
++dnl # Check CONFIG_ZLIB_DEFLATE
++dnl #
++dnl # Verify the kernel has CONFIG_ZLIB_DEFLATE support enabled.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE], [
++ ZFS_LINUX_TEST_SRC([config_zlib_deflate], [
++ #if !defined(CONFIG_ZLIB_DEFLATE) && \
++ !defined(CONFIG_ZLIB_DEFLATE_MODULE)
++ #error CONFIG_ZLIB_DEFLATE not defined
++ #endif
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE], [
++ AC_MSG_CHECKING([whether CONFIG_ZLIB_DEFLATE is defined])
++ ZFS_LINUX_TEST_RESULT([config_zlib_deflate], [
++ AC_MSG_RESULT([yes])
++ ],[
++ AC_MSG_RESULT([no])
++ AC_MSG_ERROR([
++ *** This kernel does not include the required zlib deflate support.
++ *** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set.])
++ ])
++])
+diff --git a/config/kernel-create-nameidata.m4 b/config/kernel-create-nameidata.m4
+index d4c155c57..c43ca5b85 100644
+--- a/config/kernel-create-nameidata.m4
++++ b/config/kernel-create-nameidata.m4
+@@ -1,9 +1,8 @@
+ dnl #
+ dnl # 3.6 API change
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CREATE_NAMEIDATA], [
+- AC_MSG_CHECKING([whether iops->create() passes nameidata])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_NAMEIDATA], [
++ ZFS_LINUX_TEST_SRC([create_nameidata], [
+ #include <linux/fs.h>
+ #include <linux/sched.h>
+
+@@ -19,11 +18,15 @@ AC_DEFUN([ZFS_AC_KERNEL_CREATE_NAMEIDATA], [
+ iops __attribute__ ((unused)) = {
+ .create = inode_create,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CREATE_NAMEIDATA], [
++ AC_MSG_CHECKING([whether iops->create() passes nameidata])
++ ZFS_LINUX_TEST_RESULT([create_nameidata], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CREATE_NAMEIDATA, 1,
+- [iops->create() passes nameidata])
++ [iops->create() passes nameidata])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-ctl-table-name.m4 b/config/kernel-ctl-table-name.m4
+index 3ce499968..16f2ad544 100644
+--- a/config/kernel-ctl-table-name.m4
++++ b/config/kernel-ctl-table-name.m4
+@@ -2,14 +2,18 @@ dnl #
+ dnl # 2.6.33 API change,
+ dnl # Removed .ctl_name from struct ctl_table.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CTL_NAME], [
+- AC_MSG_CHECKING([whether struct ctl_table has ctl_name])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CTL_NAME], [
++ ZFS_LINUX_TEST_SRC([ctl_name], [
+ #include <linux/sysctl.h>
+ ],[
+ struct ctl_table ctl __attribute__ ((unused));
+ ctl.ctl_name = 0;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CTL_NAME], [
++ AC_MSG_CHECKING([whether struct ctl_table has ctl_name])
++ ZFS_LINUX_TEST_RESULT([ctl_name], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CTL_NAME, 1, [struct ctl_table has ctl_name])
+ ],[
+diff --git a/config/kernel-current-time.m4 b/config/kernel-current-time.m4
+index c7d5c9b52..3ceb5f63e 100644
+--- a/config/kernel-current-time.m4
++++ b/config/kernel-current-time.m4
+@@ -2,14 +2,19 @@ dnl #
+ dnl # 4.9, current_time() added
+ dnl # 4.18, return type changed from timespec to timespec64
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CURRENT_TIME],
+- [AC_MSG_CHECKING([whether current_time() exists])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_TIME], [
++ ZFS_LINUX_TEST_SRC([current_time], [
+ #include <linux/fs.h>
+ ], [
+ struct inode ip __attribute__ ((unused));
+ ip.i_atime = current_time(&ip);
+- ], [current_time], [fs/inode.c], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CURRENT_TIME], [
++ AC_MSG_CHECKING([whether current_time() exists])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([current_time],
++ [current_time], [fs/inode.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CURRENT_TIME, 1, [current_time() exists])
+ ], [
+diff --git a/config/kernel-current_bio_tail.m4 b/config/kernel-current_bio_tail.m4
+index b72f21e8a..9dfc3e6e0 100644
+--- a/config/kernel-current_bio_tail.m4
++++ b/config/kernel-current_bio_tail.m4
+@@ -4,30 +4,36 @@ dnl # current->bio_tail and current->bio_list were struct bio pointers prior to
+ dnl # Linux 2.6.34. They were refactored into a struct bio_list pointer called
+ dnl # current->bio_list in Linux 2.6.34.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CURRENT_BIO_TAIL], [
+- AC_MSG_CHECKING([whether current->bio_tail exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_BIO_TAIL], [
++ ZFS_LINUX_TEST_SRC([current_bio_tail], [
+ #include <linux/sched.h>
+- ],[
++ ], [
+ current->bio_tail = (struct bio **) NULL;
+- ],[
++ ])
++
++ ZFS_LINUX_TEST_SRC([current_bio_list], [
++ #include <linux/sched.h>
++ ], [
++ current->bio_list = (struct bio_list *) NULL;
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CURRENT_BIO_TAIL], [
++ AC_MSG_CHECKING([whether current->bio_tail exists])
++ ZFS_LINUX_TEST_RESULT([current_bio_tail], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CURRENT_BIO_TAIL, 1,
+ [current->bio_tail exists])
+ ],[
+ AC_MSG_RESULT(no)
++
+ AC_MSG_CHECKING([whether current->bio_list exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/sched.h>
+- ],[
+- current->bio_list = (struct bio_list *) NULL;
+- ],[
++ ZFS_LINUX_TEST_RESULT([current_bio_list], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CURRENT_BIO_LIST, 1,
+ [current->bio_list exists])
+ ],[
+- AC_MSG_ERROR(no - Please file a bug report at
+- https://github.com/zfsonlinux/zfs/issues/new)
++ ZFS_LINUX_TEST_ERROR([bio_list])
+ ])
+ ])
+ ])
+diff --git a/config/kernel-d-make-root.m4 b/config/kernel-d-make-root.m4
+deleted file mode 100644
+index 9c2b73dcb..000000000
+--- a/config/kernel-d-make-root.m4
++++ /dev/null
+@@ -1,17 +0,0 @@
+-dnl #
+-dnl # 3.4.0 API change
+-dnl # Added d_make_root() to replace previous d_alloc_root() function.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_D_MAKE_ROOT],
+- [AC_MSG_CHECKING([whether d_make_root() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
+- #include <linux/dcache.h>
+- ], [
+- d_make_root(NULL);
+- ], [d_make_root], [fs/dcache.c], [
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_D_MAKE_ROOT, 1, [d_make_root() is available])
+- ], [
+- AC_MSG_RESULT(no)
+- ])
+-])
+diff --git a/config/kernel-d-obtain-alias.m4 b/config/kernel-d-obtain-alias.m4
+deleted file mode 100644
+index 2b4b11ecc..000000000
+--- a/config/kernel-d-obtain-alias.m4
++++ /dev/null
+@@ -1,18 +0,0 @@
+-dnl #
+-dnl # 2.6.28 API change
+-dnl # Added d_obtain_alias() helper function.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_D_OBTAIN_ALIAS],
+- [AC_MSG_CHECKING([whether d_obtain_alias() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
+- #include <linux/dcache.h>
+- ], [
+- d_obtain_alias(NULL);
+- ], [d_obtain_alias], [fs/dcache.c], [
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_D_OBTAIN_ALIAS, 1,
+- [d_obtain_alias() is available])
+- ], [
+- AC_MSG_RESULT(no)
+- ])
+-])
+diff --git a/config/kernel-d-prune-aliases.m4 b/config/kernel-d-prune-aliases.m4
+deleted file mode 100644
+index d9c521b1d..000000000
+--- a/config/kernel-d-prune-aliases.m4
++++ /dev/null
+@@ -1,19 +0,0 @@
+-dnl #
+-dnl # 2.6.12 API change
+-dnl # d_prune_aliases() helper function available.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_D_PRUNE_ALIASES],
+- [AC_MSG_CHECKING([whether d_prune_aliases() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
+- #include <linux/dcache.h>
+- ], [
+- struct inode *ip = NULL;
+- d_prune_aliases(ip);
+- ], [d_prune_aliases], [fs/dcache.c], [
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_D_PRUNE_ALIASES, 1,
+- [d_prune_aliases() is available])
+- ], [
+- AC_MSG_RESULT(no)
+- ])
+-])
+diff --git a/config/kernel-declare-event-class.m4 b/config/kernel-declare-event-class.m4
+index 7867d7517..6c78ee858 100644
+--- a/config/kernel-declare-event-class.m4
++++ b/config/kernel-declare-event-class.m4
+@@ -2,13 +2,10 @@ dnl #
+ dnl # Ensure the DECLARE_EVENT_CLASS macro is available to non-GPL modules.
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_DECLARE_EVENT_CLASS], [
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-I\$(src)"
+-
+ AC_MSG_CHECKING([whether DECLARE_EVENT_CLASS() is available])
+ ZFS_LINUX_TRY_COMPILE_HEADER([
+ #include <linux/module.h>
+- MODULE_LICENSE(ZFS_META_LICENSE);
++ MODULE_LICENSE("$ZFS_META_LICENSE");
+
+ #define CREATE_TRACE_POINTS
+ #include "conftest.h"
+@@ -18,7 +15,7 @@ AC_DEFUN([ZFS_AC_KERNEL_DECLARE_EVENT_CLASS], [
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_DECLARE_EVENT_CLASS, 1,
+- [DECLARE_EVENT_CLASS() is available])
++ [DECLARE_EVENT_CLASS() is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ],[
+@@ -55,5 +52,4 @@ AC_DEFUN([ZFS_AC_KERNEL_DECLARE_EVENT_CLASS], [
+ #define TRACE_INCLUDE_FILE conftest
+ #include <trace/define_trace.h>
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-dentry-operations.m4 b/config/kernel-dentry-operations.m4
+index 61f5a27af..f943dad4c 100644
+--- a/config/kernel-dentry-operations.m4
++++ b/config/kernel-dentry-operations.m4
+@@ -1,9 +1,103 @@
++dnl #
++dnl # 3.4.0 API change
++dnl # Added d_make_root() to replace previous d_alloc_root() function.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_D_MAKE_ROOT], [
++ ZFS_LINUX_TEST_SRC([d_make_root], [
++ #include <linux/dcache.h>
++ ], [
++ d_make_root(NULL);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_D_MAKE_ROOT], [
++ AC_MSG_CHECKING([whether d_make_root() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([d_make_root],
++ [d_make_root], [fs/dcache.c], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_D_MAKE_ROOT, 1, [d_make_root() is available])
++ ], [
++ AC_MSG_RESULT(no)
++ ])
++])
++
++dnl #
++dnl # 2.6.28 API change
++dnl # Added d_obtain_alias() helper function.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS], [
++ ZFS_LINUX_TEST_SRC([d_obtain_alias], [
++ #include <linux/dcache.h>
++ ], [
++ d_obtain_alias(NULL);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_D_OBTAIN_ALIAS], [
++ AC_MSG_CHECKING([whether d_obtain_alias() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([d_obtain_alias],
++ [d_obtain_alias], [fs/dcache.c], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_D_OBTAIN_ALIAS, 1,
++ [d_obtain_alias() is available])
++ ], [
++ AC_MSG_RESULT(no)
++ ])
++])
++
++dnl #
++dnl # 2.6.12 API change
++dnl # d_prune_aliases() helper function available.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_D_PRUNE_ALIASES], [
++ ZFS_LINUX_TEST_SRC([d_prune_aliases], [
++ #include <linux/dcache.h>
++ ], [
++ struct inode *ip = NULL;
++ d_prune_aliases(ip);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_D_PRUNE_ALIASES], [
++ AC_MSG_CHECKING([whether d_prune_aliases() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([d_prune_aliases],
++ [d_prune_aliases], [fs/dcache.c], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_D_PRUNE_ALIASES, 1,
++ [d_prune_aliases() is available])
++ ], [
++ AC_MSG_RESULT(no)
++ ])
++])
++
++dnl #
++dnl # 2.6.38 API change
++dnl # Added d_set_d_op() helper function.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_D_SET_D_OP], [
++ ZFS_LINUX_TEST_SRC([d_set_d_op], [
++ #include <linux/dcache.h>
++ ], [
++ d_set_d_op(NULL, NULL);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP], [
++ AC_MSG_CHECKING([whether d_set_d_op() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([d_set_d_op],
++ [d_set_d_op], [fs/dcache.c], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_D_SET_D_OP, 1, [d_set_d_op() is available])
++ ], [
++ AC_MSG_RESULT(no)
++ ])
++])
++
+ dnl #
+ dnl # 3.6 API change
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA], [
+- AC_MSG_CHECKING([whether dops->d_revalidate() takes struct nameidata])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_D_REVALIDATE_NAMEIDATA], [
++ ZFS_LINUX_TEST_SRC([dentry_operations_revalidate], [
+ #include <linux/dcache.h>
+ #include <linux/sched.h>
+
+@@ -14,11 +108,15 @@ AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA], [
+ dops __attribute__ ((unused)) = {
+ .d_revalidate = revalidate,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA], [
++ AC_MSG_CHECKING([whether dops->d_revalidate() takes struct nameidata])
++ ZFS_LINUX_TEST_RESULT([dentry_operations_revalidate], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_D_REVALIDATE_NAMEIDATA, 1,
+- [dops->d_revalidate() operation takes nameidata])
++ [dops->d_revalidate() operation takes nameidata])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -28,9 +126,8 @@ dnl #
+ dnl # 2.6.30 API change
+ dnl # The 'struct dentry_operations' was constified in the dentry structure.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS], [
+- AC_MSG_CHECKING([whether dentry uses const struct dentry_operations])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CONST_DENTRY_OPERATIONS], [
++ ZFS_LINUX_TEST_SRC([dentry_operations_const], [
+ #include <linux/dcache.h>
+
+ const struct dentry_operations test_d_op = {
+@@ -38,32 +135,17 @@ AC_DEFUN([ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS], [
+ };
+ ],[
+ struct dentry d __attribute__ ((unused));
+-
+ d.d_op = &test_d_op;
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_CONST_DENTRY_OPERATIONS, 1,
+- [dentry uses const struct dentry_operations])
+- ],[
+- AC_MSG_RESULT(no)
+ ])
+ ])
+
+-dnl #
+-dnl # 2.6.38 API change
+-dnl # Added d_set_d_op() helper function.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP],
+- [AC_MSG_CHECKING([whether d_set_d_op() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
+- #include <linux/dcache.h>
+- ], [
+- d_set_d_op(NULL, NULL);
+- ], [d_set_d_op], [fs/dcache.c], [
++AC_DEFUN([ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS], [
++ AC_MSG_CHECKING([whether dentry uses const struct dentry_operations])
++ ZFS_LINUX_TEST_RESULT([dentry_operations_const], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_D_SET_D_OP, 1,
+- [d_set_d_op() is available])
+- ], [
++ AC_DEFINE(HAVE_CONST_DENTRY_OPERATIONS, 1,
++ [dentry uses const struct dentry_operations])
++ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
+@@ -72,17 +154,41 @@ dnl #
+ dnl # 2.6.38 API chage
+ dnl # Added sb->s_d_op default dentry_operations member
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_S_D_OP],
+- [AC_MSG_CHECKING([whether super_block has s_d_op])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_S_D_OP], [
++ ZFS_LINUX_TEST_SRC([super_block_s_d_op], [
+ #include <linux/fs.h>
+ ],[
+ struct super_block sb __attribute__ ((unused));
+ sb.s_d_op = NULL;
+- ], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_S_D_OP], [
++ AC_MSG_CHECKING([whether super_block has s_d_op])
++ ZFS_LINUX_TEST_RESULT([super_block_s_d_op], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_S_D_OP, 1, [struct super_block has s_d_op])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY], [
++ ZFS_AC_KERNEL_SRC_D_MAKE_ROOT
++ ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS
++ ZFS_AC_KERNEL_SRC_D_PRUNE_ALIASES
++ ZFS_AC_KERNEL_SRC_D_SET_D_OP
++ ZFS_AC_KERNEL_SRC_D_REVALIDATE_NAMEIDATA
++ ZFS_AC_KERNEL_SRC_CONST_DENTRY_OPERATIONS
++ ZFS_AC_KERNEL_SRC_S_D_OP
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_DENTRY], [
++ ZFS_AC_KERNEL_D_MAKE_ROOT
++ ZFS_AC_KERNEL_D_OBTAIN_ALIAS
++ ZFS_AC_KERNEL_D_PRUNE_ALIASES
++ ZFS_AC_KERNEL_D_SET_D_OP
++ ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA
++ ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS
++ ZFS_AC_KERNEL_S_D_OP
++])
+diff --git a/config/kernel-dirty-inode.m4 b/config/kernel-dirty-inode.m4
+index ffd87bb14..dc7667fa4 100644
+--- a/config/kernel-dirty-inode.m4
++++ b/config/kernel-dirty-inode.m4
+@@ -4,9 +4,8 @@ dnl # The sops->dirty_inode() callbacks were updated to take a flags
+ dnl # argument. This allows the greater control over whether the
+ dnl # filesystem needs to push out a transaction or not.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS], [
+- AC_MSG_CHECKING([whether sops->dirty_inode() wants flags])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_DIRTY_INODE], [
++ ZFS_LINUX_TEST_SRC([dirty_inode_with_flags], [
+ #include <linux/fs.h>
+
+ void dirty_inode(struct inode *a, int b) { return; }
+@@ -15,11 +14,15 @@ AC_DEFUN([ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS], [
+ sops __attribute__ ((unused)) = {
+ .dirty_inode = dirty_inode,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_DIRTY_INODE], [
++ AC_MSG_CHECKING([whether sops->dirty_inode() wants flags])
++ ZFS_LINUX_TEST_RESULT([dirty_inode_with_flags], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_DIRTY_INODE_WITH_FLAGS, 1,
+- [sops->dirty_inode() wants flags])
++ [sops->dirty_inode() wants flags])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+diff --git a/config/kernel-discard-granularity.m4 b/config/kernel-discard-granularity.m4
+index 2c677c909..c830d9aa9 100644
+--- a/config/kernel-discard-granularity.m4
++++ b/config/kernel-discard-granularity.m4
+@@ -2,18 +2,21 @@ dnl #
+ dnl # 2.6.33 API change
+ dnl # Discard granularity and alignment restrictions may now be set.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_DISCARD_GRANULARITY], [
+- AC_MSG_CHECKING([whether ql->discard_granularity is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_DISCARD_GRANULARITY], [
++ ZFS_LINUX_TEST_SRC([discard_granularity], [
+ #include <linux/blkdev.h>
+ ],[
+ struct queue_limits ql __attribute__ ((unused));
+-
+ ql.discard_granularity = 0;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_DISCARD_GRANULARITY], [
++ AC_MSG_CHECKING([whether ql->discard_granularity is available])
++ ZFS_LINUX_TEST_RESULT([discard_granularity], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_DISCARD_GRANULARITY, 1,
+- [ql->discard_granularity is available])
++ [ql->discard_granularity is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-elevator-change.m4 b/config/kernel-elevator-change.m4
+index eba252579..3aa732040 100644
+--- a/config/kernel-elevator-change.m4
++++ b/config/kernel-elevator-change.m4
+@@ -2,24 +2,25 @@ dnl #
+ dnl # 2.6.36 API, exported elevator_change() symbol
+ dnl # 4.12 API, removed elevator_change() symbol
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_ELEVATOR_CHANGE], [
+- AC_MSG_CHECKING([whether elevator_change() is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_ELEVATOR_CHANGE], [
++ ZFS_LINUX_TEST_SRC([elevator_change], [
+ #include <linux/blkdev.h>
+ #include <linux/elevator.h>
+ ],[
+- int ret;
+ struct request_queue *q = NULL;
+ char *elevator = NULL;
+- ret = elevator_change(q, elevator);
+- ],[
++ int error __attribute__ ((unused)) =
++ elevator_change(q, elevator);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_ELEVATOR_CHANGE], [
++ AC_MSG_CHECKING([whether elevator_change() is available])
++ ZFS_LINUX_TEST_RESULT([elevator_change], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_ELEVATOR_CHANGE, 1,
+- [elevator_change() is available])
++ [elevator_change() is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-encode-fh-inode.m4 b/config/kernel-encode-fh-inode.m4
+index 287f62a5e..9d4ba5f0f 100644
+--- a/config/kernel-encode-fh-inode.m4
++++ b/config/kernel-encode-fh-inode.m4
+@@ -4,20 +4,23 @@ dnl # torvalds/linux@b0b0382bb4904965a9e9fca77ad87514dfda0d1c changed the
+ dnl # ->encode_fh() callback to pass the child inode and its parents inode
+ dnl # rather than a dentry and a boolean saying whether we want the parent.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE], [
+- AC_MSG_CHECKING([whether eops->encode_fh() wants inode])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE], [
++ ZFS_LINUX_TEST_SRC([export_operations_encode_fh], [
+ #include <linux/exportfs.h>
+ int encode_fh(struct inode *inode, __u32 *fh, int *max_len,
+ struct inode *parent) { return 0; }
+ static struct export_operations eops __attribute__ ((unused))={
+ .encode_fh = encode_fh,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE], [
++ AC_MSG_CHECKING([whether eops->encode_fh() wants inode])
++ ZFS_LINUX_TEST_RESULT([export_operations_encode_fh], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_ENCODE_FH_WITH_INODE, 1,
+- [eops->encode_fh() wants child and parent inodes])
++ [eops->encode_fh() wants child and parent inodes])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-evict-inode.m4 b/config/kernel-evict-inode.m4
+index 683cedb6d..cd91c6669 100644
+--- a/config/kernel-evict-inode.m4
++++ b/config/kernel-evict-inode.m4
+@@ -3,16 +3,19 @@ dnl # 2.6.36 API change
+ dnl # The sops->delete_inode() and sops->clear_inode() callbacks have
+ dnl # replaced by a single sops->evict_inode() callback.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_EVICT_INODE], [
+- AC_MSG_CHECKING([whether sops->evict_inode() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_EVICT_INODE], [
++ ZFS_LINUX_TEST_SRC([evict_inode], [
+ #include <linux/fs.h>
+ void evict_inode (struct inode * t) { return; }
+ static struct super_operations sops __attribute__ ((unused)) = {
+ .evict_inode = evict_inode,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_EVICT_INODE], [
++ AC_MSG_CHECKING([whether sops->evict_inode() exists])
++ ZFS_LINUX_TEST_RESULT([evict_inode], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_EVICT_INODE, 1, [sops->evict_inode() exists])
+ ],[
+diff --git a/config/kernel-fallocate-pax.m4 b/config/kernel-fallocate-pax.m4
+deleted file mode 100644
+index e8948be17..000000000
+--- a/config/kernel-fallocate-pax.m4
++++ /dev/null
+@@ -1,19 +0,0 @@
+-dnl #
+-dnl # PaX Linux 2.6.38 - 3.x API
+-dnl #
+-AC_DEFUN([ZFS_AC_PAX_KERNEL_FILE_FALLOCATE], [
+- AC_MSG_CHECKING([whether fops->fallocate() exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- ],[
+- long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
+- struct file_operations_no_const fops __attribute__ ((unused)) = {
+- .fallocate = fallocate,
+- };
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
+- ],[
+- AC_MSG_RESULT(no)
+- ])
+-])
+diff --git a/config/kernel-fallocate.m4 b/config/kernel-fallocate.m4
+index 550906472..302957a6c 100644
+--- a/config/kernel-fallocate.m4
++++ b/config/kernel-fallocate.m4
+@@ -1,9 +1,11 @@
+ dnl #
+-dnl # Linux 2.6.38 - 3.x API
++dnl # The fallocate callback was moved from the inode_operations
++dnl # structure to the file_operations structure.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FILE_FALLOCATE], [
+- AC_MSG_CHECKING([whether fops->fallocate() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_FALLOCATE], [
++
++ dnl # Linux 2.6.38 - 3.x API
++ ZFS_LINUX_TEST_SRC([file_fallocate], [
+ #include <linux/fs.h>
+
+ long test_fallocate(struct file *file, int mode,
+@@ -13,21 +15,10 @@ AC_DEFUN([ZFS_AC_KERNEL_FILE_FALLOCATE], [
+ fops __attribute__ ((unused)) = {
+ .fallocate = test_fallocate,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
+- ],[
+- AC_MSG_RESULT(no)
+- ])
+-])
++ ], [])
+
+-dnl #
+-dnl # Linux 2.6.x - 2.6.37 API
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_FALLOCATE], [
+- AC_MSG_CHECKING([whether iops->fallocate() exists])
+- ZFS_LINUX_TRY_COMPILE([
++ dnl # Linux 2.6.x - 2.6.37 API
++ ZFS_LINUX_TEST_SRC([inode_fallocate], [
+ #include <linux/fs.h>
+
+ long test_fallocate(struct inode *inode, int mode,
+@@ -37,20 +28,23 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_FALLOCATE], [
+ fops __attribute__ ((unused)) = {
+ .fallocate = test_fallocate,
+ };
++ ], [])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_FALLOCATE], [
++ AC_MSG_CHECKING([whether fops->fallocate() exists])
++ ZFS_LINUX_TEST_RESULT([file_fallocate], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
+ ],[
+- ],[
++ AC_MSG_RESULT(no)
++ ])
++
++ AC_MSG_CHECKING([whether iops->fallocate() exists])
++ ZFS_LINUX_TEST_RESULT([inode_fallocate], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_FALLOCATE, 1, [fops->fallocate() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
+-
+-dnl #
+-dnl # The fallocate callback was moved from the inode_operations
+-dnl # structure to the file_operations structure.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FALLOCATE], [
+- ZFS_AC_KERNEL_FILE_FALLOCATE
+- ZFS_AC_KERNEL_INODE_FALLOCATE
+-])
+diff --git a/config/kernel-file-dentry.m4 b/config/kernel-file-dentry.m4
+index daf742ee1..9cb5869c3 100644
+--- a/config/kernel-file-dentry.m4
++++ b/config/kernel-file-dentry.m4
+@@ -4,14 +4,18 @@ dnl # struct access file->f_path.dentry was replaced by accessor function
+ dnl # since fix torvalds/linux@4bacc9c9234c ("overlayfs: Make f_path always
+ dnl # point to the overlay and f_inode to the underlay").
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FILE_DENTRY], [
+- AC_MSG_CHECKING([whether file_dentry() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_FILE_DENTRY], [
++ ZFS_LINUX_TEST_SRC([file_dentry], [
+ #include <linux/fs.h>
+ ],[
+ struct file *f = NULL;
+ file_dentry(f);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_FILE_DENTRY], [
++ AC_MSG_CHECKING([whether file_dentry() is available])
++ ZFS_LINUX_TEST_RESULT([file_dentry], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_FILE_DENTRY, 1, [file_dentry() is available])
+ ],[
+diff --git a/config/kernel-file-inode.m4 b/config/kernel-file-inode.m4
+index 300188fa3..00a362165 100644
+--- a/config/kernel-file-inode.m4
++++ b/config/kernel-file-inode.m4
+@@ -3,14 +3,18 @@ dnl # 3.19 API change
+ dnl # struct access f->f_dentry->d_inode was replaced by accessor function
+ dnl # file_inode(f)
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FILE_INODE], [
+- AC_MSG_CHECKING([whether file_inode() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_FILE_INODE], [
++ ZFS_LINUX_TEST_SRC([file_inode], [
+ #include <linux/fs.h>
+ ],[
+ struct file *f = NULL;
+ file_inode(f);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_FILE_INODE], [
++ AC_MSG_CHECKING([whether file_inode() is available])
++ ZFS_LINUX_TEST_RESULT([file_inode], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_FILE_INODE, 1, [file_inode() is available])
+ ],[
+diff --git a/config/kernel-fmode-t.m4 b/config/kernel-fmode-t.m4
+index 4a23c391d..bc0001b9e 100644
+--- a/config/kernel-fmode-t.m4
++++ b/config/kernel-fmode-t.m4
+@@ -2,16 +2,19 @@ dnl #
+ dnl # 2.6.28 API change,
+ dnl # check if fmode_t typedef is defined
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_TYPE_FMODE_T],
+- [AC_MSG_CHECKING([whether kernel defines fmode_t])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_FMODE_T], [
++ ZFS_LINUX_TEST_SRC([type_fmode_t], [
+ #include <linux/types.h>
+ ],[
+ fmode_t *ptr __attribute__ ((unused));
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_FMODE_T], [
++ AC_MSG_CHECKING([whether kernel defines fmode_t])
++ ZFS_LINUX_TEST_RESULT([type_fmode_t], [
+ AC_MSG_RESULT([yes])
+- AC_DEFINE(HAVE_FMODE_T, 1,
+- [kernel defines fmode_t])
++ AC_DEFINE(HAVE_FMODE_T, 1, [kernel defines fmode_t])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+diff --git a/config/kernel-follow-down-one.m4 b/config/kernel-follow-down-one.m4
+index 63fa779d8..94e4aeb8d 100644
+--- a/config/kernel-follow-down-one.m4
++++ b/config/kernel-follow-down-one.m4
+@@ -3,14 +3,18 @@ dnl # 2.6.38 API change
+ dnl # follow_down() renamed follow_down_one(). The original follow_down()
+ dnl # symbol still exists but will traverse down all the layers.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_DOWN_ONE], [
+- AC_MSG_CHECKING([whether follow_down_one() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_FOLLOW_DOWN_ONE], [
++ ZFS_LINUX_TEST_SRC([follow_down_one], [
+ #include <linux/namei.h>
+ ],[
+ struct path *p = NULL;
+ follow_down_one(p);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_DOWN_ONE], [
++ AC_MSG_CHECKING([whether follow_down_one() is available])
++ ZFS_LINUX_TEST_RESULT([follow_down_one], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_FOLLOW_DOWN_ONE, 1,
+ [follow_down_one() is available])
+diff --git a/config/kernel-fpu.m4 b/config/kernel-fpu.m4
+index 0e622e859..a2c47d65a 100644
+--- a/config/kernel-fpu.m4
++++ b/config/kernel-fpu.m4
+@@ -18,8 +18,11 @@ dnl #
+ dnl # Pre-4.2: Use kernel_fpu_{begin,end}()
+ dnl # HAVE_KERNEL_FPU & KERNEL_EXPORTS_X86_FPU
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FPU], [
+- AC_MSG_CHECKING([which kernel_fpu header to use])
++dnl # N.B. The header check is performed before all other checks since it
++dnl # depends on HAVE_KERNEL_FPU_API_HEADER being set in confdefs.h.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_FPU_HEADER], [
++ AC_MSG_CHECKING([whether fpu headers are available])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/module.h>
+ #include <asm/fpu/api.h>
+@@ -31,66 +34,88 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
+ ],[
+ AC_MSG_RESULT(i387.h & xcr.h)
+ ])
++])
+
+- AC_MSG_CHECKING([which kernel_fpu function to use])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
+- #include <linux/module.h>
++AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
++ ZFS_LINUX_TEST_SRC([kernel_fpu], [
+ #ifdef HAVE_KERNEL_FPU_API_HEADER
+ #include <asm/fpu/api.h>
+ #else
+ #include <asm/i387.h>
+ #include <asm/xcr.h>
+ #endif
+- MODULE_LICENSE("$ZFS_META_LICENSE");
+- ],[
++ ], [
+ kernel_fpu_begin();
+ kernel_fpu_end();
+- ], [kernel_fpu_begin], [arch/x86/kernel/fpu/core.c], [
++ ], [], [$ZFS_META_LICENSE])
++
++ ZFS_LINUX_TEST_SRC([__kernel_fpu], [
++ #ifdef HAVE_KERNEL_FPU_API_HEADER
++ #include <asm/fpu/api.h>
++ #else
++ #include <asm/i387.h>
++ #include <asm/xcr.h>
++ #endif
++ ], [
++ __kernel_fpu_begin();
++ __kernel_fpu_end();
++ ], [], [$ZFS_META_LICENSE])
++
++ ZFS_LINUX_TEST_SRC([fpu_initialized], [
++ #include <linux/module.h>
++ #include <linux/sched.h>
++ ],[
++ struct fpu *fpu = ¤t->thread.fpu;
++ if (fpu->initialized) { return (0); };
++ ])
++
++ ZFS_LINUX_TEST_SRC([tif_need_fpu_load], [
++ #include <linux/module.h>
++ #include <asm/thread_info.h>
++
++ #if !defined(TIF_NEED_FPU_LOAD)
++ #error "TIF_NEED_FPU_LOAD undefined"
++ #endif
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_FPU], [
++ dnl #
++ dnl # Legacy kernel
++ dnl #
++ AC_MSG_CHECKING([whether kernel fpu is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([kernel_fpu_license],
++ [kernel_fpu_begin], [arch/x86/kernel/fpu/core.c], [
+ AC_MSG_RESULT(kernel_fpu_*)
+ AC_DEFINE(HAVE_KERNEL_FPU, 1,
+ [kernel has kernel_fpu_* functions])
+ AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1,
+ [kernel exports FPU functions])
+ ],[
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
+- #include <linux/module.h>
+- #ifdef HAVE_KERNEL_FPU_API_HEADER
+- #include <asm/fpu/api.h>
+- #else
+- #include <asm/i387.h>
+- #include <asm/xcr.h>
+- #endif
+- MODULE_LICENSE("$ZFS_META_LICENSE");
+- ],[
+- __kernel_fpu_begin();
+- __kernel_fpu_end();
+- ], [__kernel_fpu_begin], [arch/x86/kernel/fpu/core.c arch/x86/kernel/i387.c], [
++ dnl #
++ dnl # Linux 4.2 kernel
++ dnl #
++ ZFS_LINUX_TEST_RESULT_SYMBOL([__kernel_fpu_license],
++ [__kernel_fpu_begin],
++ [arch/x86/kernel/fpu/core.c arch/x86/kernel/i387.c], [
+ AC_MSG_RESULT(__kernel_fpu_*)
+ AC_DEFINE(HAVE_UNDERSCORE_KERNEL_FPU, 1,
+ [kernel has __kernel_fpu_* functions])
+ AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1,
+ [kernel exports FPU functions])
+ ],[
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
+- #include <linux/sched.h>
+- ],[
+- struct fpu *fpu = ¤t->thread.fpu;
+- if (fpu->initialized) { return (0); };
+- ],[
++ dnl #
++ dnl # Linux 5.0 kernel
++ dnl #
++ ZFS_LINUX_TEST_RESULT([fpu_initialized], [
+ AC_MSG_RESULT(fpu.initialized)
+ AC_DEFINE(HAVE_KERNEL_FPU_INITIALIZED, 1,
+ [kernel fpu.initialized exists])
+ ],[
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
+- #include <asm/thread_info.h>
+-
+- #if !defined(TIF_NEED_FPU_LOAD)
+- #error "TIF_NEED_FPU_LOAD undefined"
+- #endif
+- ],[
+- ],[
++ dnl #
++ dnl # Linux 5.2 kernel
++ dnl #
++ ZFS_LINUX_TEST_RESULT([tif_need_fpu_load], [
+ AC_MSG_RESULT(TIF_NEED_FPU_LOAD)
+ AC_DEFINE(
+ HAVE_KERNEL_TIF_NEED_FPU_LOAD, 1,
+diff --git a/config/kernel-fst-mount.m4 b/config/kernel-fst-mount.m4
+index a8ac50bdd..cec1ed4d6 100644
+--- a/config/kernel-fst-mount.m4
++++ b/config/kernel-fst-mount.m4
+@@ -3,9 +3,8 @@ dnl # 2.6.38 API change
+ dnl # The .get_sb callback has been replaced by a .mount callback
+ dnl # in the file_system_type structure.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FST_MOUNT], [
+- AC_MSG_CHECKING([whether fst->mount() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_FST_MOUNT], [
++ ZFS_LINUX_TEST_SRC([file_system_type_mount], [
+ #include <linux/fs.h>
+
+ static struct dentry *
+@@ -18,8 +17,12 @@ AC_DEFUN([ZFS_AC_KERNEL_FST_MOUNT], [
+ static struct file_system_type fst __attribute__ ((unused)) = {
+ .mount = mount,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_FST_MOUNT], [
++ AC_MSG_CHECKING([whether fst->mount() exists])
++ ZFS_LINUX_TEST_RESULT([file_system_type_mount], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_FST_MOUNT, 1, [fst->mount() exists])
+ ],[
+diff --git a/config/kernel-fsync.m4 b/config/kernel-fsync.m4
+index e1f2d68b9..0494e31ad 100644
+--- a/config/kernel-fsync.m4
++++ b/config/kernel-fsync.m4
+@@ -1,8 +1,8 @@
+ dnl #
+-dnl # Linux 2.6.x - 2.6.34 API
++dnl # Check file_operations->fsync interface.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITH_DENTRY], [
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_FSYNC], [
++ ZFS_LINUX_TEST_SRC([fsync_with_dentry], [
+ #include <linux/fs.h>
+
+ int test_fsync(struct file *f, struct dentry *dentry, int x)
+@@ -12,20 +12,9 @@ AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITH_DENTRY], [
+ fops __attribute__ ((unused)) = {
+ .fsync = test_fsync,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT([dentry])
+- AC_DEFINE(HAVE_FSYNC_WITH_DENTRY, 1,
+- [fops->fsync() with dentry])
+- ],[
+- ])
+-])
++ ],[])
+
+-dnl #
+-dnl # Linux 2.6.35 - Linux 3.0 API
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITHOUT_DENTRY], [
+- ZFS_LINUX_TRY_COMPILE([
++ ZFS_LINUX_TEST_SRC([fsync_without_dentry], [
+ #include <linux/fs.h>
+
+ int test_fsync(struct file *f, int x) { return 0; }
+@@ -34,20 +23,9 @@ AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITHOUT_DENTRY], [
+ fops __attribute__ ((unused)) = {
+ .fsync = test_fsync,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT([no dentry])
+- AC_DEFINE(HAVE_FSYNC_WITHOUT_DENTRY, 1,
+- [fops->fsync() without dentry])
+- ],[
+- ])
+-])
++ ],[])
+
+-dnl #
+-dnl # Linux 3.1 - 3.x API
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FSYNC_RANGE], [
+- ZFS_LINUX_TRY_COMPILE([
++ ZFS_LINUX_TEST_SRC([fsync_range], [
+ #include <linux/fs.h>
+
+ int test_fsync(struct file *f, loff_t a, loff_t b, int c)
+@@ -57,18 +35,43 @@ AC_DEFUN([ZFS_AC_KERNEL_FSYNC_RANGE], [
+ fops __attribute__ ((unused)) = {
+ .fsync = test_fsync,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT([range])
+- AC_DEFINE(HAVE_FSYNC_RANGE, 1,
+- [fops->fsync() with range])
+- ],[
+- ])
++ ],[])
+ ])
+
+ AC_DEFUN([ZFS_AC_KERNEL_FSYNC], [
+- AC_MSG_CHECKING([whether fops->fsync() wants])
+- ZFS_AC_KERNEL_FSYNC_WITH_DENTRY
+- ZFS_AC_KERNEL_FSYNC_WITHOUT_DENTRY
+- ZFS_AC_KERNEL_FSYNC_RANGE
++ dnl #
++ dnl # Linux 2.6.x - 2.6.34 API
++ dnl #
++ AC_MSG_CHECKING([whether fops->fsync() wants dentry])
++ ZFS_LINUX_TEST_RESULT([fsync_with_dentry], [
++ AC_MSG_RESULT([yes])
++ AC_DEFINE(HAVE_FSYNC_WITH_DENTRY, 1,
++ [fops->fsync() with dentry])
++ ],[
++ AC_MSG_RESULT([no])
++
++ dnl #
++ dnl # Linux 2.6.35 - Linux 3.0 API
++ dnl #
++ AC_MSG_CHECKING([whether fops->fsync() wants no dentry])
++ ZFS_LINUX_TEST_RESULT([fsync_without_dentry], [
++ AC_MSG_RESULT([yes])
++ AC_DEFINE(HAVE_FSYNC_WITHOUT_DENTRY, 1,
++ [fops->fsync() without dentry])
++ ],[
++ AC_MSG_RESULT([no])
++
++ dnl #
++ dnl # Linux 3.1 - 3.x API
++ dnl #
++ AC_MSG_CHECKING([whether fops->fsync() wants range])
++ ZFS_LINUX_TEST_RESULT([fsync_range], [
++ AC_MSG_RESULT([range])
++ AC_DEFINE(HAVE_FSYNC_RANGE, 1,
++ [fops->fsync() with range])
++ ],[
++ ZFS_LINUX_TEST_ERROR([fops->fsync])
++ ])
++ ])
++ ])
+ ])
+diff --git a/config/kernel-generic_io_acct.m4 b/config/kernel-generic_io_acct.m4
+index 0aa762162..423b3e5a3 100644
+--- a/config/kernel-generic_io_acct.m4
++++ b/config/kernel-generic_io_acct.m4
+@@ -1,12 +1,8 @@
+ dnl #
+-dnl # 3.19 API addition
++dnl # Check for generic io accounting interface.
+ dnl #
+-dnl # torvalds/linux@394ffa503bc40e32d7f54a9b817264e81ce131b4 allows us to
+-dnl # increment iostat counters without generic_make_request().
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT_3ARG], [
+- AC_MSG_CHECKING([whether 3 arg generic IO accounting symbols are available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
++ ZFS_LINUX_TEST_SRC([generic_acct_3args], [
+ #include <linux/bio.h>
+
+ void (*generic_start_io_acct_f)(int, unsigned long,
+@@ -16,24 +12,9 @@ AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT_3ARG], [
+ ], [
+ generic_start_io_acct(0, 0, NULL);
+ generic_end_io_acct(0, NULL, 0);
+- ], [generic_start_io_acct], [block/bio.c], [
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
+- [generic_start_io_acct()/generic_end_io_acct() available])
+- ], [
+- AC_MSG_RESULT(no)
+ ])
+-])
+
+-dnl #
+-dnl # Linux 4.14 API,
+-dnl #
+-dnl # generic_start_io_acct/generic_end_io_acct now require request_queue to be
+-dnl # provided. No functional changes, but preparation for inflight accounting
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT_4ARG], [
+- AC_MSG_CHECKING([whether 4 arg generic IO accounting symbols are available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++ ZFS_LINUX_TEST_SRC([generic_acct_4args], [
+ #include <linux/bio.h>
+
+ void (*generic_start_io_acct_f)(struct request_queue *, int,
+@@ -43,11 +24,41 @@ AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT_4ARG], [
+ ], [
+ generic_start_io_acct(NULL, 0, 0, NULL);
+ generic_end_io_acct(NULL, 0, NULL, 0);
+- ], [generic_start_io_acct], [block/bio.c], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
++ dnl #
++ dnl # 3.19 API addition
++ dnl #
++ dnl # torvalds/linux@394ffa50 allows us to increment iostat
++ dnl # counters without generic_make_request().
++ dnl #
++ AC_MSG_CHECKING([whether generic IO accounting wants 3 args])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_3args],
++ [generic_start_io_acct], [block/bio.c], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
+- [generic_start_io_acct()/generic_end_io_acct() 4 arg available])
++ AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
++ [generic_start_io_acct()/generic_end_io_acct() available])
+ ], [
+ AC_MSG_RESULT(no)
++
++ dnl #
++ dnl # Linux 4.14 API,
++ dnl #
++ dnl # generic_start_io_acct/generic_end_io_acct now require
++ dnl # request_queue to be provided. No functional changes,
++ dnl # but preparation for inflight accounting.
++ dnl #
++ AC_MSG_CHECKING([whether generic IO accounting wants 4 args])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_4args],
++ [generic_start_io_acct], [block/bio.c], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
++ [generic_start_io_acct()/generic_end_io_acct() ]
++ [4 arg available])
++ ], [
++ AC_MSG_RESULT(no)
++ ])
+ ])
+ ])
+diff --git a/config/kernel-generic_readlink.m4 b/config/kernel-generic_readlink.m4
+index 914431de4..a7a33b408 100644
+--- a/config/kernel-generic_readlink.m4
++++ b/config/kernel-generic_readlink.m4
+@@ -4,18 +4,21 @@ dnl #
+ dnl # NULL inode_operations.readlink implies generic_readlink(), which
+ dnl # has been made static.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL], [
+- AC_MSG_CHECKING([whether generic_readlink is global])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_READLINK_GLOBAL], [
++ ZFS_LINUX_TEST_SRC([generic_readlink_global], [
+ #include <linux/fs.h>
+ ],[
+ int i __attribute__ ((unused));
+-
+ i = generic_readlink(NULL, NULL, 0);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL], [
++ AC_MSG_CHECKING([whether generic_readlink is global])
++ ZFS_LINUX_TEST_RESULT([generic_readlink_global], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_GENERIC_READLINK, 1,
+- [generic_readlink is global])
++ [generic_readlink is global])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+diff --git a/config/kernel-get-disk-and-module.m4 b/config/kernel-get-disk-and-module.m4
+index 2a51a5af7..51cf7743c 100644
+--- a/config/kernel-get-disk-and-module.m4
++++ b/config/kernel-get-disk-and-module.m4
+@@ -2,14 +2,19 @@ dnl #
+ dnl # 4.16 API change
+ dnl # Verify if get_disk_and_module() symbol is available.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_AND_MODULE],
+- [AC_MSG_CHECKING([whether get_disk_and_module() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_DISK_AND_MODULE], [
++ ZFS_LINUX_TEST_SRC([get_disk_and_module], [
+ #include <linux/genhd.h>
+ ], [
+ struct gendisk *disk = NULL;
+ (void) get_disk_and_module(disk);
+- ], [get_disk_and_module], [block/genhd.c], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_AND_MODULE], [
++ AC_MSG_CHECKING([whether get_disk_and_module() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([get_disk_and_module],
++ [get_disk_and_module], [block/genhd.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_GET_DISK_AND_MODULE,
+ 1, [get_disk_and_module() is available])
+diff --git a/config/kernel-get-disk-ro.m4 b/config/kernel-get-disk-ro.m4
+index 13ed81217..1e2abb475 100644
+--- a/config/kernel-get-disk-ro.m4
++++ b/config/kernel-get-disk-ro.m4
+@@ -1,21 +1,21 @@
+ dnl #
+ dnl # 2.6.x API change
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_RO], [
+- AC_MSG_CHECKING([whether get_disk_ro() is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_DISK_RO], [
++ ZFS_LINUX_TEST_SRC([get_disk_ro], [
+ #include <linux/blkdev.h>
+ ],[
+ struct gendisk *disk = NULL;
+ (void) get_disk_ro(disk);
+- ],[
++ ], [$NO_UNUSED_BUT_SET_VARIABLE])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_RO], [
++ AC_MSG_CHECKING([whether get_disk_ro() is available])
++ ZFS_LINUX_TEST_RESULT([get_disk_ro], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_GET_DISK_RO, 1,
+- [blk_disk_ro() is available])
++ AC_DEFINE(HAVE_GET_DISK_RO, 1, [blk_disk_ro() is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-get-link.m4 b/config/kernel-get-link.m4
+index 3cda08c1b..e4f478e37 100644
+--- a/config/kernel-get-link.m4
++++ b/config/kernel-get-link.m4
+@@ -1,13 +1,29 @@
+ dnl #
+ dnl # Supported get_link() interfaces checked newest to oldest.
++dnl # Note this interface used to be named follow_link.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_LINK], [
+- dnl #
+- dnl # 4.2 API change
+- dnl # - This kernel retired the nameidata structure.
+- dnl #
+- AC_MSG_CHECKING([whether iops->follow_link() passes cookie])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
++ ZFS_LINUX_TEST_SRC([inode_operations_get_link], [
++ #include <linux/fs.h>
++ const char *get_link(struct dentry *de, struct inode *ip,
++ struct delayed_call *done) { return "symlink"; }
++ static struct inode_operations
++ iops __attribute__ ((unused)) = {
++ .get_link = get_link,
++ };
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([inode_operations_get_link_cookie], [
++ #include <linux/fs.h>
++ const char *get_link(struct dentry *de, struct
++ inode *ip, void **cookie) { return "symlink"; }
++ static struct inode_operations
++ iops __attribute__ ((unused)) = {
++ .get_link = get_link,
++ };
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([inode_operations_follow_link], [
+ #include <linux/fs.h>
+ const char *follow_link(struct dentry *de,
+ void **cookie) { return "symlink"; }
+@@ -15,35 +31,17 @@ AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_LINK], [
+ iops __attribute__ ((unused)) = {
+ .follow_link = follow_link,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_FOLLOW_LINK_COOKIE, 1,
+- [iops->follow_link() cookie])
+- ],[
+- dnl #
+- dnl # 2.6.32 API
+- dnl #
+- AC_MSG_RESULT(no)
+- AC_MSG_CHECKING(
+- [whether iops->follow_link() passes nameidata])
+- ZFS_LINUX_TRY_COMPILE([
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([inode_operations_follow_link_nameidata], [
+ #include <linux/fs.h>
+- void *follow_link(struct dentry *de, struct
+- nameidata *nd) { return (void *)NULL; }
+- static struct inode_operations
+- iops __attribute__ ((unused)) = {
+- .follow_link = follow_link,
+- };
+- ],[
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_FOLLOW_LINK_NAMEIDATA, 1,
+- [iops->follow_link() nameidata])
+- ],[
+- AC_MSG_ERROR(no; please file a bug report)
+- ])
+- ])
++ void *follow_link(struct dentry *de, struct
++ nameidata *nd) { return (void *)NULL; }
++ static struct inode_operations
++ iops __attribute__ ((unused)) = {
++ .follow_link = follow_link,
++ };
++ ],[])
+ ])
+
+ AC_DEFUN([ZFS_AC_KERNEL_GET_LINK], [
+@@ -53,20 +51,12 @@ AC_DEFUN([ZFS_AC_KERNEL_GET_LINK], [
+ dnl # used it to retire the put_link() interface.
+ dnl #
+ AC_MSG_CHECKING([whether iops->get_link() passes delayed])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- const char *get_link(struct dentry *de, struct inode *ip,
+- struct delayed_call *done) { return "symlink"; }
+- static struct inode_operations
+- iops __attribute__ ((unused)) = {
+- .get_link = get_link,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT([inode_operations_get_link], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_GET_LINK_DELAYED, 1,
+- [iops->get_link() delayed])
++ AC_DEFINE(HAVE_GET_LINK_DELAYED, 1, [iops->get_link() delayed])
+ ],[
++ AC_MSG_RESULT(no)
++
+ dnl #
+ dnl # 4.5 API change
+ dnl # The follow_link() interface has been replaced by
+@@ -74,27 +64,41 @@ AC_DEFUN([ZFS_AC_KERNEL_GET_LINK], [
+ dnl # - An inode is passed as a separate argument
+ dnl # - When called in RCU mode a NULL dentry is passed.
+ dnl #
+- AC_MSG_RESULT(no)
+ AC_MSG_CHECKING([whether iops->get_link() passes cookie])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- const char *get_link(struct dentry *de, struct
+- inode *ip, void **cookie) { return "symlink"; }
+- static struct inode_operations
+- iops __attribute__ ((unused)) = {
+- .get_link = get_link,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT([inode_operations_get_link_cookie], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_GET_LINK_COOKIE, 1,
+ [iops->get_link() cookie])
+ ],[
++ AC_MSG_RESULT(no)
++
+ dnl #
+- dnl # Check for the follow_link APIs.
++ dnl # 4.2 API change
++ dnl # This kernel retired the nameidata structure.
+ dnl #
+- AC_MSG_RESULT(no)
+- ZFS_AC_KERNEL_FOLLOW_LINK
++ AC_MSG_CHECKING(
++ [whether iops->follow_link() passes cookie])
++ ZFS_LINUX_TEST_RESULT([inode_operations_follow_link], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_FOLLOW_LINK_COOKIE, 1,
++ [iops->follow_link() cookie])
++ ],[
++ AC_MSG_RESULT(no)
++
++ dnl #
++ dnl # 2.6.32 API
++ dnl #
++ AC_MSG_CHECKING(
++ [whether iops->follow_link() passes nameidata])
++ ZFS_LINUX_TEST_RESULT(
++ [inode_operations_follow_link_nameidata],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_FOLLOW_LINK_NAMEIDATA, 1,
++ [iops->follow_link() nameidata])
++ ],[
++ ZFS_LINUX_TEST_ERROR([get_link])
++ ])
++ ])
+ ])
+ ])
+ ])
+diff --git a/config/kernel-global_page_state.m4 b/config/kernel-global_page_state.m4
+index f4a40011f..a0cb9e2c8 100644
+--- a/config/kernel-global_page_state.m4
++++ b/config/kernel-global_page_state.m4
+@@ -4,16 +4,21 @@ dnl #
+ dnl # 75ef71840539 mm, vmstat: add infrastructure for per-node vmstats
+ dnl # 599d0c954f91 mm, vmscan: move LRU lists to node
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE], [
+- AC_MSG_CHECKING([whether global_node_page_state() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GLOBAL_NODE_PAGE_STATE], [
++ ZFS_LINUX_TEST_SRC([global_node_page_state], [
+ #include <linux/mm.h>
+ #include <linux/vmstat.h>
+ ],[
+ (void) global_node_page_state(0);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE], [
++ AC_MSG_CHECKING([whether global_node_page_state() exists])
++ ZFS_LINUX_TEST_RESULT([global_node_page_state], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(ZFS_GLOBAL_NODE_PAGE_STATE, 1, [global_node_page_state() exists])
++ AC_DEFINE(ZFS_GLOBAL_NODE_PAGE_STATE, 1,
++ [global_node_page_state() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -24,16 +29,21 @@ dnl # 4.14 API change
+ dnl #
+ dnl # c41f012ade0b mm: rename global_page_state to global_zone_page_state
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE], [
+- AC_MSG_CHECKING([whether global_zone_page_state() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GLOBAL_ZONE_PAGE_STATE], [
++ ZFS_LINUX_TEST_SRC([global_zone_page_state], [
+ #include <linux/mm.h>
+ #include <linux/vmstat.h>
+ ],[
+ (void) global_zone_page_state(0);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE], [
++ AC_MSG_CHECKING([whether global_zone_page_state() exists])
++ ZFS_LINUX_TEST_RESULT([global_zone_page_state], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(ZFS_GLOBAL_ZONE_PAGE_STATE, 1, [global_zone_page_state() exists])
++ AC_DEFINE(ZFS_GLOBAL_ZONE_PAGE_STATE, 1,
++ [global_zone_page_state() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -44,9 +54,11 @@ dnl # Create a define and autoconf variable for an enum member
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_ENUM_MEMBER], [
+ AC_MSG_CHECKING([whether enum $2 contains $1])
+- AS_IF([AC_TRY_COMMAND("${srcdir}/scripts/enum-extract.pl" "$2" "$3" | egrep -qx $1)],[
++ AS_IF([AC_TRY_COMMAND(
++ "${srcdir}/scripts/enum-extract.pl" "$2" "$3" | egrep -qx $1)],[
+ AC_MSG_RESULT([yes])
+- AC_DEFINE(m4_join([_], [ZFS_ENUM], m4_toupper($2), $1), 1, [enum $2 contains $1])
++ AC_DEFINE(m4_join([_], [ZFS_ENUM], m4_toupper($2), $1), 1,
++ [enum $2 contains $1])
+ m4_join([_], [ZFS_ENUM], m4_toupper($2), $1)=1
+ ],[
+ AC_MSG_RESULT([no])
+@@ -59,8 +71,7 @@ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR],[
+ AC_MSG_RESULT(no)
+ AC_MSG_RESULT([$1 in either node_stat_item or zone_stat_item: $2])
+- AC_MSG_RESULT([configure needs updating, see: config/kernel-global_page_state.m4])
+- AC_MSG_FAILURE([SHUT 'ER DOWN CLANCY, SHE'S PUMPIN' MUD!])
++ ZFS_LINUX_TEST_ERROR([global page state])
+ ])
+
+ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK], [
+@@ -75,10 +86,10 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK], [
+ ])
+
+ dnl #
+-dnl # Ensure the config tests are finding one and only one of each enum of interest
++dnl # Ensure the config tests are finding one and only one of each enum.
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY], [
+- AC_MSG_CHECKING([global_page_state enums are sane])
++ AC_MSG_CHECKING([whether global_page_state enums are sane])
+
+ ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_FILE_PAGES])
+ ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_ANON])
+@@ -88,6 +99,11 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY], [
+ AC_MSG_RESULT(yes)
+ ])
+
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GLOBAL_PAGE_STATE], [
++ ZFS_AC_KERNEL_SRC_GLOBAL_NODE_PAGE_STATE
++ ZFS_AC_KERNEL_SRC_GLOBAL_ZONE_PAGE_STATE
++])
++
+ dnl #
+ dnl # enum members in which we're interested
+ dnl #
+@@ -95,15 +111,23 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE], [
+ ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE
+ ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE
+
+- ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES], [node_stat_item], [$LINUX/include/linux/mmzone.h])
+- ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON], [node_stat_item], [$LINUX/include/linux/mmzone.h])
+- ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE], [node_stat_item], [$LINUX/include/linux/mmzone.h])
+- ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE], [node_stat_item], [$LINUX/include/linux/mmzone.h])
++ ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES],
++ [node_stat_item], [$LINUX/include/linux/mmzone.h])
++ ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON],
++ [node_stat_item], [$LINUX/include/linux/mmzone.h])
++ ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],
++ [node_stat_item], [$LINUX/include/linux/mmzone.h])
++ ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],
++ [node_stat_item], [$LINUX/include/linux/mmzone.h])
+
+- ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES], [zone_stat_item], [$LINUX/include/linux/mmzone.h])
+- ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON], [zone_stat_item], [$LINUX/include/linux/mmzone.h])
+- ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE], [zone_stat_item], [$LINUX/include/linux/mmzone.h])
+- ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE], [zone_stat_item], [$LINUX/include/linux/mmzone.h])
++ ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES],
++ [zone_stat_item], [$LINUX/include/linux/mmzone.h])
++ ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON],
++ [zone_stat_item], [$LINUX/include/linux/mmzone.h])
++ ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],
++ [zone_stat_item], [$LINUX/include/linux/mmzone.h])
++ ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],
++ [zone_stat_item], [$LINUX/include/linux/mmzone.h])
+
+ ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY
+ ])
+diff --git a/config/kernel-group-info.m4 b/config/kernel-group-info.m4
+index 849a1e246..0fee1d36d 100644
+--- a/config/kernel-group-info.m4
++++ b/config/kernel-group-info.m4
+@@ -2,20 +2,21 @@ dnl #
+ dnl # 4.9 API change
+ dnl # group_info changed from 2d array via >blocks to 1d array via ->gid
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_GROUP_INFO_GID], [
+- AC_MSG_CHECKING([whether group_info->gid exists])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GROUP_INFO_GID], [
++ ZFS_LINUX_TEST_SRC([group_info_gid], [
+ #include <linux/cred.h>
+ ],[
+ struct group_info *gi = groups_alloc(1);
+ gi->gid[0] = KGIDT_INIT(0);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_GROUP_INFO_GID], [
++ AC_MSG_CHECKING([whether group_info->gid exists])
++ ZFS_LINUX_TEST_RESULT([group_info_gid], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_GROUP_INFO_GID, 1, [group_info->gid exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-in-compat-syscall.m4 b/config/kernel-in-compat-syscall.m4
+index 9fca9da20..baaac8c4f 100644
+--- a/config/kernel-in-compat-syscall.m4
++++ b/config/kernel-in-compat-syscall.m4
+@@ -4,13 +4,17 @@ dnl # Added in_compat_syscall() which can be overridden on a per-
+ dnl # architecture basis. Prior to this is_compat_task() was the
+ dnl # provided interface.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_IN_COMPAT_SYSCALL], [
+- AC_MSG_CHECKING([whether in_compat_syscall() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL], [
++ ZFS_LINUX_TEST_SRC([in_compat_syscall], [
+ #include <linux/compat.h>
+ ],[
+ in_compat_syscall();
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_IN_COMPAT_SYSCALL], [
++ AC_MSG_CHECKING([whether in_compat_syscall() is available])
++ ZFS_LINUX_TEST_RESULT([in_compat_syscall], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_IN_COMPAT_SYSCALL, 1,
+ [in_compat_syscall() is available])
+diff --git a/config/kernel-inode-getattr.m4 b/config/kernel-inode-getattr.m4
+index f10e0b251..48391d66f 100644
+--- a/config/kernel-inode-getattr.m4
++++ b/config/kernel-inode-getattr.m4
+@@ -2,9 +2,8 @@ dnl #
+ dnl # Linux 4.11 API
+ dnl # See torvalds/linux@a528d35
+ dnl #
+-AC_DEFUN([ZFS_AC_PATH_KERNEL_IOPS_GETATTR], [
+- AC_MSG_CHECKING([whether iops->getattr() takes a path])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
++ ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
+ #include <linux/fs.h>
+
+ int test_getattr(
+@@ -16,24 +15,9 @@ AC_DEFUN([ZFS_AC_PATH_KERNEL_IOPS_GETATTR], [
+ iops __attribute__ ((unused)) = {
+ .getattr = test_getattr,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
+- [iops->getattr() takes a path])
+- ],[
+- AC_MSG_RESULT(no)
+- ])
+-])
+-
++ ],[])
+
+-
+-dnl #
+-dnl # Linux 3.9 - 4.10 API
+-dnl #
+-AC_DEFUN([ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR], [
+- AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
+- ZFS_LINUX_TRY_COMPILE([
++ ZFS_LINUX_TEST_SRC([inode_operations_getattr_vfsmount], [
+ #include <linux/fs.h>
+
+ int test_getattr(
+@@ -45,23 +29,25 @@ AC_DEFUN([ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR], [
+ iops __attribute__ ((unused)) = {
+ .getattr = test_getattr,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
++ AC_MSG_CHECKING([whether iops->getattr() takes a path])
++ ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
+- [iops->getattr() takes a vfsmount])
++ AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
++ [iops->getattr() takes a path])
+ ],[
+ AC_MSG_RESULT(no)
+- ])
+-])
+-
+
+-dnl #
+-dnl # The interface of the getattr callback from the inode_operations
+-dnl # structure changed. Also, the interface of the simple_getattr()
+-dnl # function provided by the kernel changed.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR], [
+- ZFS_AC_PATH_KERNEL_IOPS_GETATTR
+- ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR
++ AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
++ ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
++ [iops->getattr() takes a vfsmount])
++ ],[
++ AC_MSG_RESULT(no)
++ ])
++ ])
+ ])
+diff --git a/config/kernel-inode-lock.m4 b/config/kernel-inode-lock.m4
+index 8dee01422..5eb04af78 100644
+--- a/config/kernel-inode-lock.m4
++++ b/config/kernel-inode-lock.m4
+@@ -4,20 +4,21 @@ dnl # i_mutex is changed to i_rwsem. Instead of directly using
+ dnl # i_mutex/i_rwsem, we should use inode_lock() and inode_lock_shared()
+ dnl # We test inode_lock_shared because inode_lock is introduced earlier.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_LOCK], [
+- AC_MSG_CHECKING([whether inode_lock_shared() exists])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_LOCK], [
++ ZFS_LINUX_TEST_SRC([inode_lock], [
+ #include <linux/fs.h>
+ ],[
+ struct inode *inode = NULL;
+ inode_lock_shared(inode);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_LOCK], [
++ AC_MSG_CHECKING([whether inode_lock_shared() exists])
++ ZFS_LINUX_TEST_RESULT([inode_lock], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_LOCK_SHARED, 1, [yes])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-inode-set-flags.m4 b/config/kernel-inode-set-flags.m4
+index e0ad26796..133f666a9 100644
+--- a/config/kernel-inode-set-flags.m4
++++ b/config/kernel-inode-set-flags.m4
+@@ -2,14 +2,18 @@ dnl #
+ dnl # 3.15 API change
+ dnl # inode_set_flags introduced to set i_flags
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_FLAGS], [
+- AC_MSG_CHECKING([whether inode_set_flags() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SET_FLAGS], [
++ ZFS_LINUX_TEST_SRC([inode_set_flags], [
+ #include <linux/fs.h>
+ ],[
+ struct inode inode;
+ inode_set_flags(&inode, S_IMMUTABLE, S_IMMUTABLE);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_FLAGS], [
++ AC_MSG_CHECKING([whether inode_set_flags() exists])
++ ZFS_LINUX_TEST_RESULT([inode_set_flags], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_SET_FLAGS, 1, [inode_set_flags() exists])
+ ],[
+diff --git a/config/kernel-inode-set-iversion.m4 b/config/kernel-inode-set-iversion.m4
+index 9a7d7890e..dd415de32 100644
+--- a/config/kernel-inode-set-iversion.m4
++++ b/config/kernel-inode-set-iversion.m4
+@@ -2,14 +2,18 @@ dnl #
+ dnl # 4.16 API change
+ dnl # inode_set_iversion introduced to set i_version
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_IVERSION], [
+- AC_MSG_CHECKING([whether inode_set_iversion() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SET_IVERSION], [
++ ZFS_LINUX_TEST_SRC([inode_set_iversion], [
+ #include <linux/iversion.h>
+ ],[
+ struct inode inode;
+ inode_set_iversion(&inode, 1);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_IVERSION], [
++ AC_MSG_CHECKING([whether inode_set_iversion() exists])
++ ZFS_LINUX_TEST_RESULT([inode_set_iversion], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_SET_IVERSION, 1,
+ [inode_set_iversion() exists])
+diff --git a/config/kernel-inode-times.m4 b/config/kernel-inode-times.m4
+index f5818411a..57e7f31fd 100644
+--- a/config/kernel-inode-times.m4
++++ b/config/kernel-inode-times.m4
+@@ -2,11 +2,8 @@ dnl #
+ dnl # 4.18 API change
+ dnl # i_atime, i_mtime, and i_ctime changed from timespec to timespec64.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
+- AC_MSG_CHECKING([whether inode->i_*time's are timespec64])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [
++ ZFS_LINUX_TEST_SRC([inode_times], [
+ #include <linux/fs.h>
+ ],[
+ struct inode ip;
+@@ -14,12 +11,16 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
+
+ memset(&ip, 0, sizeof(ip));
+ ts = ip.i_mtime;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
++ AC_MSG_CHECKING([whether inode->i_*time's are timespec64])
++ ZFS_LINUX_TEST_RESULT([inode_times], [
+ AC_MSG_RESULT(no)
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_TIMESPEC64_TIMES, 1,
+ [inode->i_*time's are timespec64])
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-insert-inode-locked.m4 b/config/kernel-insert-inode-locked.m4
+index da141d180..4990399c3 100644
+--- a/config/kernel-insert-inode-locked.m4
++++ b/config/kernel-insert-inode-locked.m4
+@@ -2,16 +2,21 @@ dnl #
+ dnl # 2.6.28 API change
+ dnl # Added insert_inode_locked() helper function.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INSERT_INODE_LOCKED],
+- [AC_MSG_CHECKING([whether insert_inode_locked() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED], [
++ ZFS_LINUX_TEST_SRC([insert_inode_locked], [
+ #include <linux/fs.h>
+ ], [
+ insert_inode_locked(NULL);
+- ], [insert_inode_locked], [fs/inode.c], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INSERT_INODE_LOCKED], [
++ AC_MSG_CHECKING([whether insert_inode_locked() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([insert_inode_locked],
++ [insert_inode_locked], [fs/inode.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INSERT_INODE_LOCKED, 1,
+- [insert_inode_locked() is available])
++ [insert_inode_locked() is available])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-invalidate-bdev-args.m4 b/config/kernel-invalidate-bdev-args.m4
+index 09c2ebf26..55a784dd9 100644
+--- a/config/kernel-invalidate-bdev-args.m4
++++ b/config/kernel-invalidate-bdev-args.m4
+@@ -2,17 +2,21 @@ dnl #
+ dnl # 2.6.22 API change
+ dnl # Unused destroy_dirty_buffers arg removed from prototype.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INVALIDATE_BDEV_ARGS], [
+- AC_MSG_CHECKING([whether invalidate_bdev() wants 1 arg])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INVALIDATE_BDEV], [
++ ZFS_LINUX_TEST_SRC([invalidate_bdev], [
+ #include <linux/buffer_head.h>
+ ],[
+ struct block_device *bdev = NULL;
+ invalidate_bdev(bdev);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INVALIDATE_BDEV], [
++ AC_MSG_CHECKING([whether invalidate_bdev() wants 1 arg])
++ ZFS_LINUX_TEST_RESULT([invalidate_bdev], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_1ARG_INVALIDATE_BDEV, 1,
+- [invalidate_bdev() wants 1 arg])
++ [invalidate_bdev() wants 1 arg])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-is_owner_or_cap.m4 b/config/kernel-is_owner_or_cap.m4
+index da07e58dd..ab8072409 100644
+--- a/config/kernel-is_owner_or_cap.m4
++++ b/config/kernel-is_owner_or_cap.m4
+@@ -4,33 +4,40 @@ dnl # The is_owner_or_cap() macro was renamed to inode_owner_or_capable(),
+ dnl # This is used for permission checks in the xattr and file attribute call
+ dnl # paths.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
+- AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [
++ ZFS_LINUX_TEST_SRC([inode_owner_or_capable], [
+ #include <linux/fs.h>
+ ],[
+ struct inode *ip = NULL;
+ (void) inode_owner_or_capable(ip);
++ ])
++
++
++ ZFS_LINUX_TEST_SRC([is_owner_or_cap], [
++ #include <linux/fs.h>
++ #include <linux/sched.h>
+ ],[
++ struct inode *ip = NULL;
++ (void) is_owner_or_cap(ip);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
++ AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
++ ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE, 1,
+ [inode_owner_or_capable() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ AC_MSG_CHECKING([whether is_owner_or_cap() exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- #include <linux/sched.h>
+- ],[
+- struct inode *ip = NULL;
+- (void) is_owner_or_cap(ip);
+- ],[
++
++ ZFS_LINUX_TEST_RESULT([is_owner_or_cap], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_IS_OWNER_OR_CAP, 1,
+ [is_owner_or_cap() exists])
+ ],[
+- AC_MSG_ERROR(no - Please file a bug report at
+- https://github.com/zfsonlinux/zfs/issues/new)
++ ZFS_LINUX_TEST_ERROR([capability])
+ ])
+ ])
+ ])
+diff --git a/config/kernel-kmap-atomic-args.m4 b/config/kernel-kmap-atomic-args.m4
+index beb1692e7..d09e93d7f 100644
+--- a/config/kernel-kmap-atomic-args.m4
++++ b/config/kernel-kmap-atomic-args.m4
+@@ -3,17 +3,21 @@ dnl # 2.6.37 API change
+ dnl # kmap_atomic changed from assigning hard-coded named slot to using
+ dnl # push/pop based dynamical allocation.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS], [
+- AC_MSG_CHECKING([whether kmap_atomic wants 1 args])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_KMAP_ATOMIC_ARGS], [
++ ZFS_LINUX_TEST_SRC([kmap_atomic], [
+ #include <linux/pagemap.h>
+ ],[
+ struct page page;
+ kmap_atomic(&page);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS], [
++ AC_MSG_CHECKING([whether kmap_atomic wants 1 args])
++ ZFS_LINUX_TEST_RESULT([kmap_atomic], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_1ARG_KMAP_ATOMIC, 1,
+- [kmap_atomic wants 1 args])
++ [kmap_atomic wants 1 args])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-kmem-cache.m4 b/config/kernel-kmem-cache.m4
+index 21cc53d34..7576e6cfd 100644
+--- a/config/kernel-kmem-cache.m4
++++ b/config/kernel-kmem-cache.m4
+@@ -5,30 +5,36 @@ dnl # private allocation flags which are applied when allocating a new slab
+ dnl # in kmem_getpages(). Unfortunately there is no public API for setting
+ dnl # non-default flags.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_ALLOCFLAGS], [
+- AC_MSG_CHECKING([whether struct kmem_cache has allocflags])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_KMEM_CACHE_ALLOCFLAGS], [
++ ZFS_LINUX_TEST_SRC([kmem_cache_allocflags], [
+ #include <linux/slab.h>
+ ],[
+ struct kmem_cache cachep __attribute__ ((unused));
+ cachep.allocflags = GFP_KERNEL;
++ ])
++
++ ZFS_LINUX_TEST_SRC([kmem_cache_gfpflags], [
++ #include <linux/slab.h>
+ ],[
++ struct kmem_cache cachep __attribute__ ((unused));
++ cachep.gfpflags = GFP_KERNEL;
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_ALLOCFLAGS], [
++ AC_MSG_CHECKING([whether struct kmem_cache has allocflags])
++ ZFS_LINUX_TEST_RESULT([kmem_cache_allocflags], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KMEM_CACHE_ALLOCFLAGS, 1,
+- [struct kmem_cache has allocflags])
++ [struct kmem_cache has allocflags])
+ ],[
+ AC_MSG_RESULT(no)
+
+ AC_MSG_CHECKING([whether struct kmem_cache has gfpflags])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/slab.h>
+- ],[
+- struct kmem_cache cachep __attribute__ ((unused));
+- cachep.gfpflags = GFP_KERNEL;
+- ],[
++ ZFS_LINUX_TEST_RESULT([kmem_cache_gfpflags], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KMEM_CACHE_GFPFLAGS, 1,
+- [struct kmem_cache has gfpflags])
++ [struct kmem_cache has gfpflags])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -40,16 +46,10 @@ dnl # grsecurity API change,
+ dnl # kmem_cache_create() with SLAB_USERCOPY flag replaced by
+ dnl # kmem_cache_create_usercopy().
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY], [
+- AC_MSG_CHECKING([whether kmem_cache_create_usercopy() exists])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_KMEM_CACHE_CREATE_USERCOPY], [
++ ZFS_LINUX_TEST_SRC([kmem_cache_create_usercopy], [
+ #include <linux/slab.h>
+- static void ctor(void *foo)
+- {
+- // fake ctor
+- }
++ static void ctor(void *foo) { /* fake ctor */ }
+ ],[
+ struct kmem_cache *skc_linux_cache;
+ const char *name = "test";
+@@ -60,13 +60,27 @@ AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY], [
+ size_t usersize = size - useroffset;
+
+ skc_linux_cache = kmem_cache_create_usercopy(
+- name, size, align, flags, useroffset, usersize, ctor);
+- ],[
++ name, size, align, flags, useroffset, usersize, ctor);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY], [
++ AC_MSG_CHECKING([whether kmem_cache_create_usercopy() exists])
++ ZFS_LINUX_TEST_RESULT([kmem_cache_create_usercopy], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KMEM_CACHE_CREATE_USERCOPY, 1,
+- [kmem_cache_create_usercopy() exists])
++ [kmem_cache_create_usercopy() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_KMEM_CACHE], [
++ ZFS_AC_KERNEL_SRC_KMEM_CACHE_ALLOCFLAGS
++ ZFS_AC_KERNEL_SRC_KMEM_CACHE_CREATE_USERCOPY
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE], [
++ ZFS_AC_KERNEL_KMEM_CACHE_ALLOCFLAGS
++ ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY
+ ])
+diff --git a/config/kernel-kstrtoul.m4 b/config/kernel-kstrtoul.m4
+index 5530e0e2d..ef3c9843c 100644
+--- a/config/kernel-kstrtoul.m4
++++ b/config/kernel-kstrtoul.m4
+@@ -1,18 +1,20 @@
+ dnl #
+ dnl # 2.6.39 API change
+ dnl #
+-dnl # 33ee3b2e2eb9 kstrto*: converting strings to integers done (hopefully) right
+-dnl #
+ dnl # If kstrtoul() doesn't exist, fallback to use strict_strtoul() which has
+ dnl # existed since 2.6.25.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_KSTRTOUL], [
+- AC_MSG_CHECKING([whether kstrtoul() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_KSTRTOUL], [
++ ZFS_LINUX_TEST_SRC([kstrtoul], [
+ #include <linux/kernel.h>
+ ],[
+ int ret __attribute__ ((unused)) = kstrtoul(NULL, 10, NULL);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_KSTRTOUL], [
++ AC_MSG_CHECKING([whether kstrtoul() exists])
++ ZFS_LINUX_TEST_RESULT([kstrtoul], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KSTRTOUL, 1, [kstrtoul() exists])
+ ],[
+diff --git a/config/kernel-ktime_get_coarse_real_ts64.m4 b/config/kernel-ktime_get_coarse_real_ts64.m4
+index d6be8c418..28492bf04 100644
+--- a/config/kernel-ktime_get_coarse_real_ts64.m4
++++ b/config/kernel-ktime_get_coarse_real_ts64.m4
+@@ -2,16 +2,21 @@ dnl #
+ dnl # 4.18: ktime_get_coarse_real_ts64() added. Use it in place of
+ dnl # current_kernel_time64().
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64],
+- [AC_MSG_CHECKING([whether ktime_get_coarse_real_ts64() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64], [
++ ZFS_LINUX_TEST_SRC([ktime_get_coarse_real_ts64], [
+ #include <linux/mm.h>
+ ], [
+ struct timespec64 ts;
+ ktime_get_coarse_real_ts64(&ts);
+- ], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64], [
++ AC_MSG_CHECKING([whether ktime_get_coarse_real_ts64() exists])
++ ZFS_LINUX_TEST_RESULT([ktime_get_coarse_real_ts64], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_KTIME_GET_COARSE_REAL_TS64, 1, [ktime_get_coarse_real_ts64() exists])
++ AC_DEFINE(HAVE_KTIME_GET_COARSE_REAL_TS64, 1,
++ [ktime_get_coarse_real_ts64() exists])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-kuid-helpers.m4 b/config/kernel-kuid-helpers.m4
+index 60713b9d3..4bc4e039d 100644
+--- a/config/kernel-kuid-helpers.m4
++++ b/config/kernel-kuid-helpers.m4
+@@ -5,14 +5,18 @@ dnl # became necessary to go through one more level of indirection
+ dnl # when dealing with uid/gid - namely the kuid type.
+ dnl #
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_KUID_HELPERS], [
+- AC_MSG_CHECKING([whether i_(uid|gid)_(read|write) exist])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_KUID_HELPERS], [
++ ZFS_LINUX_TEST_SRC([i_uid_read], [
+ #include <linux/fs.h>
+ ],[
+ struct inode *ip = NULL;
+ (void) i_uid_read(ip);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_KUID_HELPERS], [
++ AC_MSG_CHECKING([whether i_(uid|gid)_(read|write) exist])
++ ZFS_LINUX_TEST_RESULT([i_uid_read], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KUID_HELPERS, 1,
+ [i_(uid|gid)_(read|write) exist])
+diff --git a/config/kernel-kuidgid.m4 b/config/kernel-kuidgid.m4
+index 82685d263..15bf98154 100644
+--- a/config/kernel-kuidgid.m4
++++ b/config/kernel-kuidgid.m4
+@@ -3,20 +3,26 @@ dnl # User namespaces, use kuid_t in place of uid_t
+ dnl # where available. Not strictly a user namespaces thing
+ dnl # but it should prevent surprises
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_KUIDGID_T], [
+- AC_MSG_CHECKING([whether kuid_t/kgid_t is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_KUIDGID_T], [
++ ZFS_LINUX_TEST_SRC([kuidgid_t_init], [
+ #include <linux/uidgid.h>
+ ], [
+ kuid_t userid __attribute__ ((unused)) = KUIDT_INIT(0);
+ kgid_t groupid __attribute__ ((unused)) = KGIDT_INIT(0);
+- ],[
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/uidgid.h>
+- ], [
+- kuid_t userid __attribute__ ((unused)) = 0;
+- kgid_t groupid __attribute__ ((unused)) = 0;
+- ],[
++ ])
++
++ ZFS_LINUX_TEST_SRC([kuidgid_t], [
++ #include <linux/uidgid.h>
++ ], [
++ kuid_t userid __attribute__ ((unused)) = 0;
++ kgid_t groupid __attribute__ ((unused)) = 0;
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_KUIDGID_T], [
++ AC_MSG_CHECKING([whether kuid_t/kgid_t is available])
++ ZFS_LINUX_TEST_RESULT([kuidgid_t_init], [
++ ZFS_LINUX_TEST_RESULT([kuidgid_t], [
+ AC_MSG_RESULT(yes; optional)
+ ],[
+ AC_MSG_RESULT(yes; mandatory)
+diff --git a/config/kernel-lookup-bdev.m4 b/config/kernel-lookup-bdev.m4
+index abbf55d9b..72b4993e1 100644
+--- a/config/kernel-lookup-bdev.m4
++++ b/config/kernel-lookup-bdev.m4
+@@ -2,23 +2,33 @@ dnl #
+ dnl # 2.6.27, lookup_bdev() was exported.
+ dnl # 4.4.0-6.21 - x.y on Ubuntu, lookup_bdev() takes 2 arguments.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_BDEV],
+- [AC_MSG_CHECKING([whether lookup_bdev() wants 1 arg])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_LOOKUP_BDEV], [
++ ZFS_LINUX_TEST_SRC([lookup_bdev_1arg], [
+ #include <linux/fs.h>
+ ], [
+ lookup_bdev(NULL);
+- ], [lookup_bdev], [fs/block_dev.c], [
++ ])
++
++ ZFS_LINUX_TEST_SRC([lookup_bdev_2args], [
++ #include <linux/fs.h>
++ ], [
++ lookup_bdev(NULL, FMODE_READ);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_BDEV], [
++ AC_MSG_CHECKING([whether lookup_bdev() wants 1 arg])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_1arg],
++ [lookup_bdev], [fs/block_dev.c], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_1ARG_LOOKUP_BDEV, 1, [lookup_bdev() wants 1 arg])
++ AC_DEFINE(HAVE_1ARG_LOOKUP_BDEV, 1,
++ [lookup_bdev() wants 1 arg])
+ ], [
+ AC_MSG_RESULT(no)
++
+ AC_MSG_CHECKING([whether lookup_bdev() wants 2 args])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
+- #include <linux/fs.h>
+- ], [
+- lookup_bdev(NULL, FMODE_READ);
+- ], [lookup_bdev], [fs/block_dev.c], [
++ ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_2args],
++ [lookup_bdev], [fs/block_dev.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_2ARGS_LOOKUP_BDEV, 1,
+ [lookup_bdev() wants 2 args])
+@@ -26,4 +36,4 @@ AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_BDEV],
+ AC_MSG_RESULT(no)
+ ])
+ ])
+-])
+\ No newline at end of file
++])
+diff --git a/config/kernel-lookup-nameidata.m4 b/config/kernel-lookup-nameidata.m4
+index 5453be5e8..865b8aff8 100644
+--- a/config/kernel-lookup-nameidata.m4
++++ b/config/kernel-lookup-nameidata.m4
+@@ -1,9 +1,8 @@
+ dnl #
+ dnl # 3.6 API change
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_NAMEIDATA], [
+- AC_MSG_CHECKING([whether iops->lookup() passes nameidata])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_LOOKUP_NAMEIDATA], [
++ ZFS_LINUX_TEST_SRC([lookup_nameidata], [
+ #include <linux/fs.h>
+ #include <linux/sched.h>
+
+@@ -15,11 +14,15 @@ AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_NAMEIDATA], [
+ __attribute__ ((unused)) = {
+ .lookup = inode_lookup,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_NAMEIDATA], [
++ AC_MSG_CHECKING([whether iops->lookup() passes nameidata])
++ ZFS_LINUX_TEST_RESULT([lookup_nameidata], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_LOOKUP_NAMEIDATA, 1,
+- [iops->lookup() passes nameidata])
++ [iops->lookup() passes nameidata])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-lseek-execute.m4 b/config/kernel-lseek-execute.m4
+index 8c4032b92..652f611f8 100644
+--- a/config/kernel-lseek-execute.m4
++++ b/config/kernel-lseek-execute.m4
+@@ -2,9 +2,8 @@ dnl #
+ dnl # 3.11 API change
+ dnl # lseek_execute helper exported
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_LSEEK_EXECUTE],
+- [AC_MSG_CHECKING([whether lseek_execute() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_LSEEK_EXECUTE], [
++ ZFS_LINUX_TEST_SRC([lseek_execute], [
+ #include <linux/fs.h>
+ ], [
+ struct file *fp __attribute__ ((unused)) = NULL;
+@@ -13,10 +12,15 @@ AC_DEFUN([ZFS_AC_KERNEL_LSEEK_EXECUTE],
+ loff_t maxsize __attribute__ ((unused)) = 0;
+
+ lseek_execute(fp, ip, offset, maxsize);
+- ], [lseek_exclusive], [fs/read_write.c], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_LSEEK_EXECUTE], [
++ AC_MSG_CHECKING([whether lseek_execute() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([lseek_execute],
++ [lseek_exclusive], [fs/read_write.c], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_LSEEK_EXECUTE, 1,
+- [lseek_execute() is available])
++ AC_DEFINE(HAVE_LSEEK_EXECUTE, 1, [lseek_execute() is available])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-make-request-fn.m4 b/config/kernel-make-request-fn.m4
+new file mode 100644
+index 000000000..86339aa04
+--- /dev/null
++++ b/config/kernel-make-request-fn.m4
+@@ -0,0 +1,77 @@
++dnl #
++dnl # Check for make_request_fn interface.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
++ ZFS_LINUX_TEST_SRC([make_request_fn_int], [
++ #include <linux/blkdev.h>
++ int make_request(struct request_queue *q,
++ struct bio *bio) { return (0); }
++ ],[
++ blk_queue_make_request(NULL, &make_request);
++ ])
++
++ ZFS_LINUX_TEST_SRC([make_request_fn_void], [
++ #include <linux/blkdev.h>
++ void make_request(struct request_queue *q,
++ struct bio *bio) { return; }
++ ],[
++ blk_queue_make_request(NULL, &make_request);
++ ])
++
++ ZFS_LINUX_TEST_SRC([make_request_fn_blk_qc_t], [
++ #include <linux/blkdev.h>
++ blk_qc_t make_request(struct request_queue *q,
++ struct bio *bio) { return (BLK_QC_T_NONE); }
++ ],[
++ blk_queue_make_request(NULL, &make_request);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
++ dnl #
++ dnl # Legacy API
++ dnl # make_request_fn returns int.
++ dnl #
++ AC_MSG_CHECKING([whether make_request_fn() returns int])
++ ZFS_LINUX_TEST_RESULT([make_request_fn_int], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(MAKE_REQUEST_FN_RET, int,
++ [make_request_fn() return type])
++ AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_INT, 1,
++ [Noting that make_request_fn() returns int])
++ ],[
++ AC_MSG_RESULT(no)
++
++ dnl #
++ dnl # Linux 3.2 API Change
++ dnl # make_request_fn returns void.
++ dnl #
++ AC_MSG_CHECKING([whether make_request_fn() returns void])
++ ZFS_LINUX_TEST_RESULT([make_request_fn_void], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(MAKE_REQUEST_FN_RET, void,
++ [make_request_fn() return type])
++ AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_VOID, 1,
++ [Noting that make_request_fn() returns void])
++ ],[
++ AC_MSG_RESULT(no)
++
++ dnl #
++ dnl # Linux 4.4 API Change
++ dnl # make_request_fn returns blk_qc_t.
++ dnl #
++ AC_MSG_CHECKING(
++ [whether make_request_fn() returns blk_qc_t])
++ ZFS_LINUX_TEST_RESULT([make_request_fn_blk_qc_t], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
++ [make_request_fn() return type])
++ AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
++ [Noting that make_request_fn() ]
++ [returns blk_qc_t])
++ ],[
++ ZFS_LINUX_TEST_ERROR([make_request_fn])
++ ])
++ ])
++ ])
++])
+diff --git a/config/kernel-misc-minor.m4 b/config/kernel-misc-minor.m4
+index a020d2ebc..20fe2cd2f 100644
+--- a/config/kernel-misc-minor.m4
++++ b/config/kernel-misc-minor.m4
+@@ -6,7 +6,7 @@ dnl # number. Start with a large known available unreserved minor and work
+ dnl # our way down to lower value if a collision is detected.
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_MISC_MINOR], [
+- AC_MSG_CHECKING([for available /dev/zfs minor])
++ AC_MSG_CHECKING([whether /dev/zfs minor is available])
+
+ for i in $(seq 249 -1 200); do
+ if ! grep -q "^#define\s\+.*_MINOR\s\+.*$i" \
+diff --git a/config/kernel-mk-request-fn.m4 b/config/kernel-mk-request-fn.m4
+deleted file mode 100644
+index 57eebe23d..000000000
+--- a/config/kernel-mk-request-fn.m4
++++ /dev/null
+@@ -1,65 +0,0 @@
+-dnl #
+-dnl # Linux 3.2 API Change
+-dnl # make_request_fn returns void instead of int.
+-dnl #
+-dnl # Linux 4.4 API Change
+-dnl # make_request_fn returns blk_qc_t.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
+- AC_MSG_CHECKING([whether make_request_fn() returns int])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/blkdev.h>
+-
+- int make_request(struct request_queue *q, struct bio *bio)
+- {
+- return (0);
+- }
+- ],[
+- blk_queue_make_request(NULL, &make_request);
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(MAKE_REQUEST_FN_RET, int,
+- [make_request_fn() returns int])
+- AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_INT, 1,
+- [Noting that make_request_fn() returns int])
+- ],[
+- AC_MSG_RESULT(no)
+- AC_MSG_CHECKING([whether make_request_fn() returns void])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/blkdev.h>
+-
+- void make_request(struct request_queue *q, struct bio *bio)
+- {
+- return;
+- }
+- ],[
+- blk_queue_make_request(NULL, &make_request);
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(MAKE_REQUEST_FN_RET, void,
+- [make_request_fn() returns void])
+- ],[
+- AC_MSG_RESULT(no)
+- AC_MSG_CHECKING([whether make_request_fn() returns blk_qc_t])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/blkdev.h>
+-
+- blk_qc_t make_request(struct request_queue *q, struct bio *bio)
+- {
+- return (BLK_QC_T_NONE);
+- }
+- ],[
+- blk_queue_make_request(NULL, &make_request);
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
+- [make_request_fn() returns blk_qc_t])
+- AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
+- [Noting that make_request_fn() returns blk_qc_t])
+- ],[
+- AC_MSG_ERROR(no - Please file a bug report at
+- https://github.com/zfsonlinux/zfs/issues/new)
+- ])
+- ])
+- ])
+-])
+diff --git a/config/kernel-mkdir-umode-t.m4 b/config/kernel-mkdir-umode-t.m4
+index ebc21be9e..4cbfc0c31 100644
+--- a/config/kernel-mkdir-umode-t.m4
++++ b/config/kernel-mkdir-umode-t.m4
+@@ -6,9 +6,8 @@ dnl # would also change all three prototypes. However, if it turns out that
+ dnl # some distribution doesn't backport the whole thing this could be
+ dnl # broken apart in to three separate checks.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
+- AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T], [
++ ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
+ #include <linux/fs.h>
+
+ int mkdir(struct inode *inode, struct dentry *dentry,
+@@ -18,8 +17,12 @@ AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
+ iops __attribute__ ((unused)) = {
+ .mkdir = mkdir,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
++ AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t])
++ ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
+ [iops->create()/mkdir()/mknod() take umode_t])
+diff --git a/config/kernel-mod-param.m4 b/config/kernel-mod-param.m4
+index b72be684a..e00f19d61 100644
+--- a/config/kernel-mod-param.m4
++++ b/config/kernel-mod-param.m4
+@@ -2,9 +2,8 @@ dnl #
+ dnl # Grsecurity kernel API change
+ dnl # constified parameters of module_param_call() methods
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [
+- AC_MSG_CHECKING([whether module_param_call() is hardened])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST], [
++ ZFS_LINUX_TEST_SRC([module_param_call], [
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+
+@@ -19,8 +18,12 @@ AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [
+ }
+
+ module_param_call(p, param_set, param_get, NULL, 0644);
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [
++ AC_MSG_CHECKING([whether module_param_call() is hardened])
++ ZFS_LINUX_TEST_RESULT([module_param_call], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(MODULE_PARAM_CALL_CONST, 1,
+ [hardened module_param_call])
+diff --git a/config/kernel-objtool.m4 b/config/kernel-objtool.m4
+index 467329b25..bf60e7869 100644
+--- a/config/kernel-objtool.m4
++++ b/config/kernel-objtool.m4
+@@ -1,41 +1,44 @@
+ dnl #
+-dnl # 4.6 API for compile-time stack validation
++dnl # Check for objtool support.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_OBJTOOL], [
+- AC_MSG_CHECKING([for compile-time stack validation (objtool)])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_OBJTOOL], [
++
++ dnl # 4.6 API for compile-time stack validation
++ ZFS_LINUX_TEST_SRC([objtool], [
+ #undef __ASSEMBLY__
+ #include <asm/frame.h>
+ ],[
+ #if !defined(FRAME_BEGIN)
+ CTASSERT(1);
+ #endif
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_KERNEL_OBJTOOL, 1,
+- [kernel does stack verification])
+-
+- ZFS_AC_KERNEL_STACK_FRAME_NON_STANDARD
+- ],[
+- AC_MSG_RESULT(no)
+ ])
+-])
+
+-dnl #
+-dnl # 4.6 API added STACK_FRAME_NON_STANDARD macro
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_STACK_FRAME_NON_STANDARD], [
+- AC_MSG_CHECKING([whether STACK_FRAME_NON_STANDARD is defined])
+- ZFS_LINUX_TRY_COMPILE([
++ dnl # 4.6 API added STACK_FRAME_NON_STANDARD macro
++ ZFS_LINUX_TEST_SRC([stack_frame_non_standard], [
+ #include <linux/frame.h>
+ ],[
+ #if !defined(STACK_FRAME_NON_STANDARD)
+ CTASSERT(1);
+ #endif
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_OBJTOOL], [
++ AC_MSG_CHECKING(
++ [whether compile-time stack validation (objtool) is available])
++ ZFS_LINUX_TEST_RESULT([objtool], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_STACK_FRAME_NON_STANDARD, 1,
+- [STACK_FRAME_NON_STANDARD is defined])
++ AC_DEFINE(HAVE_KERNEL_OBJTOOL, 1,
++ [kernel does stack verification])
++
++ AC_MSG_CHECKING([whether STACK_FRAME_NON_STANDARD is defined])
++ ZFS_LINUX_TEST_RESULT([stack_frame_non_standard], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_STACK_FRAME_NON_STANDARD, 1,
++ [STACK_FRAME_NON_STANDARD is defined])
++ ],[
++ AC_MSG_RESULT(no)
++ ])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-open-bdev-exclusive.m4 b/config/kernel-open-bdev-exclusive.m4
+index 0661315a6..2e46b8876 100644
+--- a/config/kernel-open-bdev-exclusive.m4
++++ b/config/kernel-open-bdev-exclusive.m4
+@@ -2,16 +2,21 @@ dnl #
+ dnl # 2.6.28 API change
+ dnl # open/close_bdev_excl() renamed to open/close_bdev_exclusive()
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_OPEN_BDEV_EXCLUSIVE],
+- [AC_MSG_CHECKING([whether open_bdev_exclusive() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_OPEN_EXCLUSIVE], [
++ ZFS_LINUX_TEST_SRC([open_bdev_exclusive], [
+ #include <linux/fs.h>
+ ], [
+ open_bdev_exclusive(NULL, 0, NULL);
+- ], [open_bdev_exclusive], [fs/block_dev.c], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BDEV_OPEN_EXCLUSIVE], [
++ AC_MSG_CHECKING([whether open_bdev_exclusive() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([open_bdev_exclusive],
++ [open_bdev_exclusive], [fs/block_dev.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_OPEN_BDEV_EXCLUSIVE, 1,
+- [open_bdev_exclusive() is available])
++ [open_bdev_exclusive() is available])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-pde-data.m4 b/config/kernel-pde-data.m4
+index 8aa4c2204..928c5ef0d 100644
+--- a/config/kernel-pde-data.m4
++++ b/config/kernel-pde-data.m4
+@@ -2,15 +2,19 @@ dnl #
+ dnl # 3.10 API change,
+ dnl # PDE is replaced by PDE_DATA
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_PDE_DATA], [
+- AC_MSG_CHECKING([whether PDE_DATA() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_PDE_DATA], [
++ ZFS_LINUX_TEST_SRC([pde_data], [
+ #include <linux/proc_fs.h>
+ ], [
+ PDE_DATA(NULL);
+- ], [PDE_DATA], [], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_PDE_DATA], [
++ AC_MSG_CHECKING([whether PDE_DATA() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([pde_data], [PDE_DATA], [], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_PDE_DATA, 1, [yes])
++ AC_DEFINE(HAVE_PDE_DATA, 1, [PDE_DATA is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-put-link.m4 b/config/kernel-put-link.m4
+index a0bb36ef2..f03df9e99 100644
+--- a/config/kernel-put-link.m4
++++ b/config/kernel-put-link.m4
+@@ -1,17 +1,35 @@
+ dnl #
+ dnl # Supported symlink APIs
+ dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_PUT_LINK], [
++ ZFS_LINUX_TEST_SRC([put_link_cookie], [
++ #include <linux/fs.h>
++ void put_link(struct inode *ip, void *cookie)
++ { return; }
++ static struct inode_operations
++ iops __attribute__ ((unused)) = {
++ .put_link = put_link,
++ };
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([put_link_nameidata], [
++ #include <linux/fs.h>
++ void put_link(struct dentry *de, struct
++ nameidata *nd, void *ptr) { return; }
++ static struct inode_operations
++ iops __attribute__ ((unused)) = {
++ .put_link = put_link,
++ };
++ ],[])
++])
++
+ AC_DEFUN([ZFS_AC_KERNEL_PUT_LINK], [
+ dnl #
+ dnl # 4.5 API change
+ dnl # get_link() uses delayed done, there is no put_link() interface.
++ dnl # This check intially uses the inode_operations_get_link result
+ dnl #
+- ZFS_LINUX_TRY_COMPILE([
+- #if !defined(HAVE_GET_LINK_DELAYED)
+- #error "Expecting get_link() delayed done"
+- #endif
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT([inode_operations_get_link], [
+ AC_DEFINE(HAVE_PUT_LINK_DELAYED, 1, [iops->put_link() delayed])
+ ],[
+ dnl #
+@@ -19,41 +37,24 @@ AC_DEFUN([ZFS_AC_KERNEL_PUT_LINK], [
+ dnl # This kernel retired the nameidata structure.
+ dnl #
+ AC_MSG_CHECKING([whether iops->put_link() passes cookie])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- void put_link(struct inode *ip, void *cookie)
+- { return; }
+- static struct inode_operations
+- iops __attribute__ ((unused)) = {
+- .put_link = put_link,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT([put_link_cookie], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PUT_LINK_COOKIE, 1,
+ [iops->put_link() cookie])
+ ],[
++ AC_MSG_RESULT(no)
++
+ dnl #
+ dnl # 2.6.32 API
+ dnl #
+- AC_MSG_RESULT(no)
+ AC_MSG_CHECKING(
+ [whether iops->put_link() passes nameidata])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- void put_link(struct dentry *de, struct
+- nameidata *nd, void *ptr) { return; }
+- static struct inode_operations
+- iops __attribute__ ((unused)) = {
+- .put_link = put_link,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT([put_link_nameidata], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PUT_LINK_NAMEIDATA, 1,
+ [iops->put_link() nameidata])
+ ],[
+- AC_MSG_ERROR(no; please file a bug report)
++ ZFS_LINUX_TEST_ERROR([put_link])
+ ])
+ ])
+ ])
+diff --git a/config/kernel-rename.m4 b/config/kernel-rename.m4
+index 9f894fb4d..f70739153 100644
+--- a/config/kernel-rename.m4
++++ b/config/kernel-rename.m4
+@@ -3,9 +3,8 @@ dnl # 4.9 API change,
+ dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
+ dnl # flags.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
+- AC_MSG_CHECKING([whether iops->rename() wants flags])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
++ ZFS_LINUX_TEST_SRC([inode_operations_rename], [
+ #include <linux/fs.h>
+ int rename_fn(struct inode *sip, struct dentry *sdp,
+ struct inode *tip, struct dentry *tdp,
+@@ -15,10 +14,15 @@ AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
+ iops __attribute__ ((unused)) = {
+ .rename = rename_fn,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
++ AC_MSG_CHECKING([whether iops->rename() wants flags])
++ ZFS_LINUX_TEST_RESULT([inode_operations_rename], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1, [iops->rename() wants flags])
++ AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
++ [iops->rename() wants flags])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-rw.m4 b/config/kernel-rw.m4
+index 1c8a265e0..85b47d5c6 100644
+--- a/config/kernel-rw.m4
++++ b/config/kernel-rw.m4
+@@ -3,11 +3,8 @@ 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([ZFS_AC_KERNEL_WRITE], [
+- AC_MSG_CHECKING([whether kernel_write() takes loff_t pointer])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_WRITE], [
++ ZFS_LINUX_TEST_SRC([kernel_write], [
+ #include <linux/fs.h>
+ ],[
+ struct file *file = NULL;
+@@ -17,14 +14,18 @@ AC_DEFUN([ZFS_AC_KERNEL_WRITE], [
+ ssize_t ret;
+
+ ret = kernel_write(file, buf, count, pos);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_WRITE], [
++ AC_MSG_CHECKING([whether kernel_write() takes loff_t pointer])
++ ZFS_LINUX_TEST_RESULT([kernel_write], [
+ 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 #
+@@ -32,11 +33,8 @@ 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([ZFS_AC_KERNEL_READ], [
+- AC_MSG_CHECKING([whether kernel_read() takes loff_t pointer])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_READ], [
++ ZFS_LINUX_TEST_SRC([kernel_read], [
+ #include <linux/fs.h>
+ ],[
+ struct file *file = NULL;
+@@ -46,12 +44,26 @@ AC_DEFUN([ZFS_AC_KERNEL_READ], [
+ ssize_t ret;
+
+ ret = kernel_read(file, buf, count, pos);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_READ], [
++ AC_MSG_CHECKING([whether kernel_read() takes loff_t pointer])
++ ZFS_LINUX_TEST_RESULT([kernel_read], [
+ 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"
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_RW], [
++ ZFS_AC_KERNEL_SRC_WRITE
++ ZFS_AC_KERNEL_SRC_READ
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_RW], [
++ ZFS_AC_KERNEL_WRITE
++ ZFS_AC_KERNEL_READ
+ ])
+diff --git a/config/kernel-rwsem.m4 b/config/kernel-rwsem.m4
+index 532c22718..67c5cf908 100644
+--- a/config/kernel-rwsem.m4
++++ b/config/kernel-rwsem.m4
+@@ -4,25 +4,26 @@ dnl #
+ dnl # The rw_semaphore.wait_lock member was changed from spinlock_t to
+ dnl # raw_spinlock_t at commit ddb6c9b58a19edcfac93ac670b066c836ff729f1.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW], [
+- AC_MSG_CHECKING([whether struct rw_semaphore member wait_lock is raw])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM_SPINLOCK_IS_RAW], [
++ ZFS_LINUX_TEST_SRC([rwsem_spinlock_is_raw], [
+ #include <linux/rwsem.h>
+ ],[
+ struct rw_semaphore dummy_semaphore __attribute__ ((unused));
+ raw_spinlock_t dummy_lock __attribute__ ((unused)) =
+ __RAW_SPIN_LOCK_INITIALIZER(dummy_lock);
+ dummy_semaphore.wait_lock = dummy_lock;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW], [
++ AC_MSG_CHECKING([whether struct rw_semaphore member wait_lock is raw])
++ ZFS_LINUX_TEST_RESULT([rwsem_spinlock_is_raw], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(RWSEM_SPINLOCK_IS_RAW, 1,
+- [struct rw_semaphore member wait_lock is raw_spinlock_t])
++ [struct rw_semaphore member wait_lock is raw_spinlock_t])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+
+ dnl #
+@@ -30,23 +31,24 @@ dnl # 3.16 API Change
+ dnl #
+ dnl # rwsem-spinlock "->activity" changed to "->count"
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ACTIVITY], [
+- AC_MSG_CHECKING([whether struct rw_semaphore has member activity])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM_ACTIVITY], [
++ ZFS_LINUX_TEST_SRC([rwsem_activity], [
+ #include <linux/rwsem.h>
+ ],[
+ struct rw_semaphore dummy_semaphore __attribute__ ((unused));
+ dummy_semaphore.activity = 0;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ACTIVITY], [
++ AC_MSG_CHECKING([whether struct rw_semaphore has member activity])
++ ZFS_LINUX_TEST_RESULT([rwsem_activity], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_RWSEM_ACTIVITY, 1,
+- [struct rw_semaphore has member activity])
++ [struct rw_semaphore has member activity])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+
+ dnl #
+@@ -54,22 +56,35 @@ dnl # 4.8 API Change
+ dnl #
+ dnl # rwsem "->count" changed to atomic_long_t type
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT], [
+- AC_MSG_CHECKING(
+- [whether struct rw_semaphore has atomic_long_t member count])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM_ATOMIC_LONG_COUNT], [
++ ZFS_LINUX_TEST_SRC([rwsem_atomic_long_count], [
+ #include <linux/rwsem.h>
+ ],[
+ DECLARE_RWSEM(dummy_semaphore);
+ (void) atomic_long_read(&dummy_semaphore.count);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT], [
++ AC_MSG_CHECKING(
++ [whether struct rw_semaphore has atomic_long_t member count])
++ ZFS_LINUX_TEST_RESULT([rwsem_atomic_long_count], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_RWSEM_ATOMIC_LONG_COUNT, 1,
+- [struct rw_semaphore has atomic_long_t member count])
++ [struct rw_semaphore has atomic_long_t member count])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM], [
++ ZFS_AC_KERNEL_SRC_RWSEM_SPINLOCK_IS_RAW
++ ZFS_AC_KERNEL_SRC_RWSEM_ACTIVITY
++ ZFS_AC_KERNEL_SRC_RWSEM_ATOMIC_LONG_COUNT
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_RWSEM], [
++ ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW
++ ZFS_AC_KERNEL_RWSEM_ACTIVITY
++ ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT
+ ])
+diff --git a/config/kernel-sched.m4 b/config/kernel-sched.m4
+index 640b008aa..4a7db970a 100644
+--- a/config/kernel-sched.m4
++++ b/config/kernel-sched.m4
+@@ -2,14 +2,18 @@ dnl #
+ dnl # 3.9 API change,
+ dnl # Moved things from linux/sched.h to linux/sched/rt.h
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SCHED_RT_HEADER],
+- [AC_MSG_CHECKING([whether header linux/sched/rt.h exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SCHED_RT_HEADER], [
++ ZFS_LINUX_TEST_SRC([sched_rt_header], [
+ #include <linux/sched.h>
+ #include <linux/sched/rt.h>
+ ],[
+ return 0;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SCHED_RT_HEADER], [
++ AC_MSG_CHECKING([whether header linux/sched/rt.h exists])
++ ZFS_LINUX_TEST_RESULT([sched_rt_header], [
+ AC_DEFINE(HAVE_SCHED_RT_HEADER, 1, [linux/sched/rt.h exists])
+ AC_MSG_RESULT(yes)
+ ],[
+@@ -21,36 +25,59 @@ dnl #
+ dnl # 4.11 API change,
+ dnl # Moved things from linux/sched.h to linux/sched/signal.h
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER],
+- [AC_MSG_CHECKING([whether header linux/sched/signal.h exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SCHED_SIGNAL_HEADER], [
++ ZFS_LINUX_TEST_SRC([sched_signal_header], [
+ #include <linux/sched.h>
+ #include <linux/sched/signal.h>
+ ],[
+ return 0;
+- ],[
+- AC_DEFINE(HAVE_SCHED_SIGNAL_HEADER, 1, [linux/sched/signal.h exists])
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER], [
++ AC_MSG_CHECKING([whether header linux/sched/signal.h exists])
++ ZFS_LINUX_TEST_RESULT([sched_signal_header], [
++ AC_DEFINE(HAVE_SCHED_SIGNAL_HEADER, 1,
++ [linux/sched/signal.h exists])
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
+ dnl #
+ dnl # 3.19 API change
+ dnl # The io_schedule_timeout() function is present in all 2.6.32 kernels
+ dnl # but it was not exported until Linux 3.19. The RHEL 7.x kernels which
+ dnl # are based on a 3.10 kernel do export this symbol.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT], [
+- AC_MSG_CHECKING([whether io_schedule_timeout() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_IO_SCHEDULE_TIMEOUT], [
++ ZFS_LINUX_TEST_SRC([io_schedule_timeout], [
+ #include <linux/sched.h>
+ ], [
+ (void) io_schedule_timeout(1);
+- ], [io_schedule_timeout], [], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT], [
++ AC_MSG_CHECKING([whether io_schedule_timeout() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([io_schedule_timeout],
++ [io_schedule_timeout], [], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_IO_SCHEDULE_TIMEOUT, 1, [yes])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SCHED], [
++ ZFS_AC_KERNEL_SRC_SCHED_RT_HEADER
++ ZFS_AC_KERNEL_SRC_SCHED_SIGNAL_HEADER
++ ZFS_AC_KERNEL_SRC_IO_SCHEDULE_TIMEOUT
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SCHED], [
++ ZFS_AC_KERNEL_SCHED_RT_HEADER
++ ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER
++ ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT
++])
+diff --git a/config/kernel-security-inode-init.m4 b/config/kernel-security-inode-init.m4
+index a62176d42..0dea7e392 100644
+--- a/config/kernel-security-inode-init.m4
++++ b/config/kernel-security-inode-init.m4
+@@ -5,9 +5,8 @@ dnl # qstr argument which must be passed in from the dentry if available.
+ dnl # Passing a NULL is safe when no qstr is available the relevant
+ dnl # security checks will just be skipped.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY], [
+- AC_MSG_CHECKING([whether security_inode_init_security wants 6 args])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_6ARGS], [
++ ZFS_LINUX_TEST_SRC([security_inode_init_security_6args], [
+ #include <linux/security.h>
+ ],[
+ struct inode *ip __attribute__ ((unused)) = NULL;
+@@ -18,10 +17,15 @@ AC_DEFUN([ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY], [
+ size_t len __attribute__ ((unused)) = 0;
+
+ security_inode_init_security(ip, dip, str, &name, &value, &len);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_6ARGS], [
++ AC_MSG_CHECKING([whether security_inode_init_security wants 6 args])
++ ZFS_LINUX_TEST_RESULT([security_inode_init_security_6args], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY, 1,
+- [security_inode_init_security wants 6 args])
++ [security_inode_init_security wants 6 args])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -34,9 +38,8 @@ dnl # a filesystem specific callback to write security extended attributes.
+ dnl # This was done to support the initialization of multiple LSM xattrs
+ dnl # and the EVM xattr.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY], [
+- AC_MSG_CHECKING([whether security_inode_init_security wants callback])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_CALLBACK], [
++ ZFS_LINUX_TEST_SRC([security_inode_init_security], [
+ #include <linux/security.h>
+ ],[
+ struct inode *ip __attribute__ ((unused)) = NULL;
+@@ -45,11 +48,26 @@ AC_DEFUN([ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY], [
+ initxattrs func __attribute__ ((unused)) = NULL;
+
+ security_inode_init_security(ip, dip, str, func, NULL);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_CALLBACK], [
++ AC_MSG_CHECKING([whether security_inode_init_security wants callback])
++ ZFS_LINUX_TEST_RESULT([security_inode_init_security], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY, 1,
+- [security_inode_init_security wants callback])
++ [security_inode_init_security wants callback])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SECURITY_INODE], [
++ ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_6ARGS
++ ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_CALLBACK
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SECURITY_INODE], [
++ ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_6ARGS
++ ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_CALLBACK
++])
+diff --git a/config/kernel-set-nlink.m4 b/config/kernel-set-nlink.m4
+index f7ffc0d3a..63a5a8c0d 100644
+--- a/config/kernel-set-nlink.m4
++++ b/config/kernel-set-nlink.m4
+@@ -2,18 +2,21 @@ dnl #
+ dnl # Linux v3.2-rc1 API change
+ dnl # SHA: bfe8684869601dacfcb2cd69ef8cfd9045f62170
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SET_NLINK], [
+- AC_MSG_CHECKING([whether set_nlink() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_NLINK], [
++ ZFS_LINUX_TEST_SRC([set_nlink], [
+ #include <linux/fs.h>
+ ],[
+ struct inode node;
+ unsigned int link = 0;
+ (void) set_nlink(&node, link);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SET_NLINK], [
++ AC_MSG_CHECKING([whether set_nlink() is available])
++ ZFS_LINUX_TEST_RESULT([set_nlink], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_SET_NLINK, 1,
+- [set_nlink() is available])
++ AC_DEFINE(HAVE_SET_NLINK, 1, [set_nlink() is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-setattr-prepare.m4 b/config/kernel-setattr-prepare.m4
+index 32f7deb77..45408c45c 100644
+--- a/config/kernel-setattr-prepare.m4
++++ b/config/kernel-setattr-prepare.m4
+@@ -3,17 +3,21 @@ dnl # 4.9 API change
+ dnl # The inode_change_ok() function has been renamed setattr_prepare()
+ dnl # and updated to take a dentry rather than an inode.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE],
+- [AC_MSG_CHECKING([whether setattr_prepare() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
++ ZFS_LINUX_TEST_SRC([setattr_prepare], [
+ #include <linux/fs.h>
+ ], [
+ struct dentry *dentry = NULL;
+ struct iattr *attr = NULL;
+- int error;
++ int error __attribute__ ((unused)) =
++ setattr_prepare(dentry, attr);
++ ])
++])
+
+- error = setattr_prepare(dentry, attr);
+- ], [setattr_prepare], [fs/attr.c], [
++AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
++ AC_MSG_CHECKING([whether setattr_prepare() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare],
++ [setattr_prepare], [fs/attr.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SETATTR_PREPARE, 1,
+ [setattr_prepare() is available])
+diff --git a/config/kernel-sget-args.m4 b/config/kernel-sget-args.m4
+index 9d1745925..13581399e 100644
+--- a/config/kernel-sget-args.m4
++++ b/config/kernel-sget-args.m4
+@@ -2,9 +2,8 @@ dnl #
+ dnl # 3.6 API change,
+ dnl # 'sget' now takes the mount flags as an argument.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_5ARG_SGET],
+- [AC_MSG_CHECKING([whether sget() wants 5 args])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SGET], [
++ ZFS_LINUX_TEST_SRC([sget_5args], [
+ #include <linux/fs.h>
+ ],[
+ struct file_system_type *type = NULL;
+@@ -13,11 +12,15 @@ AC_DEFUN([ZFS_AC_KERNEL_5ARG_SGET],
+ int flags = 0;
+ void *data = NULL;
+ (void) sget(type, test, set, flags, data);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SGET], [
++ AC_MSG_CHECKING([whether sget() wants 5 args])
++ ZFS_LINUX_TEST_RESULT([sget_5args], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_5ARG_SGET, 1, [sget() wants 5 args])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
+-
+diff --git a/config/kernel-show-options.m4 b/config/kernel-show-options.m4
+index 67d683c55..9e426bc39 100644
+--- a/config/kernel-show-options.m4
++++ b/config/kernel-show-options.m4
+@@ -1,21 +1,26 @@
+ dnl #
+ dnl # Linux 3.3 API
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SHOW_OPTIONS], [
+- AC_MSG_CHECKING([whether sops->show_options() wants dentry])
+-
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SHOW_OPTIONS], [
++ ZFS_LINUX_TEST_SRC([super_operations_show_options], [
+ #include <linux/fs.h>
+
+- int show_options (struct seq_file * x, struct dentry * y) { return 0; };
++ int show_options(struct seq_file * x, struct dentry * y) {
++ return 0;
++ };
++
+ static struct super_operations sops __attribute__ ((unused)) = {
+ .show_options = show_options,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SHOW_OPTIONS], [
++ AC_MSG_CHECKING([whether sops->show_options() wants dentry])
++ ZFS_LINUX_TEST_RESULT([super_operations_show_options], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_SHOW_OPTIONS_WITH_DENTRY, 1,
+- [sops->show_options() with dentry])
++ [sops->show_options() with dentry])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+diff --git a/config/kernel-shrink.m4 b/config/kernel-shrink.m4
+index 405cbf42c..45b4b5d4b 100644
+--- a/config/kernel-shrink.m4
++++ b/config/kernel-shrink.m4
+@@ -4,9 +4,8 @@ dnl # The super_block structure now stores a per-filesystem shrinker.
+ dnl # This interface is preferable because it can be used to specifically
+ dnl # target only the zfs filesystem for pruning.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SHRINK], [
+- AC_MSG_CHECKING([whether super_block has s_shrink])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK], [
++ ZFS_LINUX_TEST_SRC([super_block_s_shrink], [
+ #include <linux/fs.h>
+
+ int shrink(struct shrinker *s, struct shrink_control *sc)
+@@ -18,8 +17,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINK], [
+ .s_shrink.seeks = DEFAULT_SEEKS,
+ .s_shrink.batch = 0,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK], [
++ AC_MSG_CHECKING([whether super_block has s_shrink])
++ ZFS_LINUX_TEST_RESULT([super_block_s_shrink], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SHRINK, 1, [struct super_block has s_shrink])
+
+@@ -50,15 +53,18 @@ dnl # a list_head is used. Then to prevent the spinning from occurring
+ dnl # the .next pointer is set to the fs_supers list_head which ensures
+ dnl # the iterate_supers_type() function will always terminate.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD], [
+- AC_MSG_CHECKING([whether super_block has s_instances list_head])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_INSTANCES_LIST_HEAD], [
++ ZFS_LINUX_TEST_SRC([super_block_s_instances_list_head], [
+ #include <linux/fs.h>
+ ],[
+ struct super_block sb __attribute__ ((unused));
+-
+ INIT_LIST_HEAD(&sb.s_instances);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_INSTANCES_LIST_HEAD], [
++ AC_MSG_CHECKING([whether super_block has s_instances list_head])
++ ZFS_LINUX_TEST_RESULT([super_block_s_instances_list_head], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_S_INSTANCES_LIST_HEAD, 1,
+ [struct super_block has s_instances list_head])
+@@ -67,9 +73,8 @@ AC_DEFUN([ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD], [
+ ])
+ ])
+
+-AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [
+- AC_MSG_CHECKING([whether sops->nr_cached_objects() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_NR_CACHED_OBJECTS], [
++ ZFS_LINUX_TEST_SRC([nr_cached_objects], [
+ #include <linux/fs.h>
+
+ int nr_cached_objects(struct super_block *sb) { return 0; }
+@@ -78,19 +83,22 @@ AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [
+ sops __attribute__ ((unused)) = {
+ .nr_cached_objects = nr_cached_objects,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [
++ AC_MSG_CHECKING([whether sops->nr_cached_objects() exists])
++ ZFS_LINUX_TEST_RESULT([nr_cached_objects], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_NR_CACHED_OBJECTS, 1,
+- [sops->nr_cached_objects() exists])
++ [sops->nr_cached_objects() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
+
+-AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [
+- AC_MSG_CHECKING([whether sops->free_cached_objects() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_FREE_CACHED_OBJECTS], [
++ ZFS_LINUX_TEST_SRC([free_cached_objects], [
+ #include <linux/fs.h>
+
+ void free_cached_objects(struct super_block *sb, int x)
+@@ -100,11 +108,15 @@ AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [
+ sops __attribute__ ((unused)) = {
+ .free_cached_objects = free_cached_objects,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [
++ AC_MSG_CHECKING([whether sops->free_cached_objects() exists])
++ ZFS_LINUX_TEST_RESULT([free_cached_objects], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_FREE_CACHED_OBJECTS, 1,
+- [sops->free_cached_objects() exists])
++ [sops->free_cached_objects() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -115,15 +127,19 @@ dnl # 3.12 API change
+ dnl # The nid member was added to struct shrink_control to support
+ dnl # NUMA-aware shrinkers.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
+- AC_MSG_CHECKING([whether shrink_control has nid])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID], [
++ ZFS_LINUX_TEST_SRC([shrink_control_nid], [
+ #include <linux/fs.h>
+ ],[
+ struct shrink_control sc __attribute__ ((unused));
+ unsigned long scnidsize __attribute__ ((unused)) =
+ sizeof(sc.nid);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
++ AC_MSG_CHECKING([whether shrink_control has nid])
++ ZFS_LINUX_TEST_RESULT([shrink_control_nid], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(SHRINK_CONTROL_HAS_NID, 1,
+ [struct shrink_control has nid])
+@@ -132,84 +148,96 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
+ ])
+ ])
+
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [
++ ZFS_LINUX_TEST_SRC([shrinker_cb_2arg], [
++ #include <linux/mm.h>
++ int shrinker_cb(int nr_to_scan, gfp_t gfp_mask) { return 0; }
++ ],[
++ struct shrinker cache_shrinker = {
++ .shrink = shrinker_cb,
++ .seeks = DEFAULT_SEEKS,
++ };
++ register_shrinker(&cache_shrinker);
++ ])
+
+-AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+- dnl #
+- dnl # 2.6.23 to 2.6.34 API change
+- dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask)
+- dnl #
+- AC_MSG_CHECKING([whether old 2-argument shrinker exists])
+- ZFS_LINUX_TRY_COMPILE([
++ ZFS_LINUX_TEST_SRC([shrinker_cb_3arg], [
+ #include <linux/mm.h>
++ int shrinker_cb(struct shrinker *shrink, int nr_to_scan,
++ gfp_t gfp_mask) { return 0; }
++ ],[
++ struct shrinker cache_shrinker = {
++ .shrink = shrinker_cb,
++ .seeks = DEFAULT_SEEKS,
++ };
++ register_shrinker(&cache_shrinker);
++ ])
+
+- int shrinker_cb(int nr_to_scan, gfp_t gfp_mask) {
+- return 0;
+- }
++ ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control], [
++ #include <linux/mm.h>
++ int shrinker_cb(struct shrinker *shrink,
++ struct shrink_control *sc) { return 0; }
+ ],[
+ struct shrinker cache_shrinker = {
+ .shrink = shrinker_cb,
+ .seeks = DEFAULT_SEEKS,
+ };
+ register_shrinker(&cache_shrinker);
++ ])
++
++ ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control_split], [
++ #include <linux/mm.h>
++ unsigned long shrinker_cb(struct shrinker *shrink,
++ struct shrink_control *sc) { return 0; }
+ ],[
++ struct shrinker cache_shrinker = {
++ .count_objects = shrinker_cb,
++ .scan_objects = shrinker_cb,
++ .seeks = DEFAULT_SEEKS,
++ };
++ register_shrinker(&cache_shrinker);
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
++ dnl #
++ dnl # 2.6.23 to 2.6.34 API change
++ dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask)
++ dnl #
++ AC_MSG_CHECKING([whether old 2-argument shrinker exists])
++ ZFS_LINUX_TEST_RESULT([shrinker_cb_2arg], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_2ARGS_OLD_SHRINKER_CALLBACK, 1,
+- [old shrinker callback wants 2 args])
++ [old shrinker callback wants 2 args])
+ ],[
+ AC_MSG_RESULT(no)
++
+ dnl #
+ dnl # 2.6.35 - 2.6.39 API change
+ dnl # ->shrink(struct shrinker *,
+ dnl # int nr_to_scan, gfp_t gfp_mask)
+ dnl #
+ AC_MSG_CHECKING([whether old 3-argument shrinker exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/mm.h>
+-
+- int shrinker_cb(struct shrinker *shrink, int nr_to_scan,
+- gfp_t gfp_mask) {
+- return 0;
+- }
+- ],[
+- struct shrinker cache_shrinker = {
+- .shrink = shrinker_cb,
+- .seeks = DEFAULT_SEEKS,
+- };
+- register_shrinker(&cache_shrinker);
+- ],[
++ ZFS_LINUX_TEST_RESULT([shrinker_cb_3arg], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1,
+ [old shrinker callback wants 3 args])
+ ],[
+ AC_MSG_RESULT(no)
++
+ dnl #
+ dnl # 3.0 - 3.11 API change
+ dnl # ->shrink(struct shrinker *,
+ dnl # struct shrink_control *sc)
+ dnl #
+ AC_MSG_CHECKING(
+- [whether new 2-argument shrinker exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/mm.h>
+-
+- int shrinker_cb(struct shrinker *shrink,
+- struct shrink_control *sc) {
+- return 0;
+- }
+- ],[
+- struct shrinker cache_shrinker = {
+- .shrink = shrinker_cb,
+- .seeks = DEFAULT_SEEKS,
+- };
+- register_shrinker(&cache_shrinker);
+- ],[
++ [whether new 2-argument shrinker exists])
++ ZFS_LINUX_TEST_RESULT([shrinker_cb_shrink_control], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_2ARGS_NEW_SHRINKER_CALLBACK, 1,
+ [new shrinker callback wants 2 args])
+ ],[
+ AC_MSG_RESULT(no)
++
+ dnl #
+ dnl # 3.12 API change,
+ dnl # ->shrink() is logically split in to
+@@ -217,52 +245,61 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
+ dnl #
+ AC_MSG_CHECKING(
+ [whether ->count_objects callback exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/mm.h>
+-
+- unsigned long shrinker_cb(
+- struct shrinker *shrink,
+- struct shrink_control *sc) {
+- return 0;
+- }
+- ],[
+- struct shrinker cache_shrinker = {
+- .count_objects = shrinker_cb,
+- .scan_objects = shrinker_cb,
+- .seeks = DEFAULT_SEEKS,
+- };
+- register_shrinker(&cache_shrinker);
+- ],[
++ ZFS_LINUX_TEST_RESULT(
++ [shrinker_cb_shrink_control_split], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK,
+ 1, [->count_objects exists])
+ ],[
+- AC_MSG_ERROR(error)
++ ZFS_LINUX_TEST_ERROR([shrinker])
+ ])
+ ])
+ ])
+ ])
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+
+ dnl #
+ dnl # 2.6.39 API change,
+ dnl # Shrinker adjust to use common shrink_control structure.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT], [
+- AC_MSG_CHECKING([whether struct shrink_control exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT], [
++ ZFS_LINUX_TEST_SRC([shrink_control_struct], [
+ #include <linux/mm.h>
+ ],[
+ struct shrink_control sc __attribute__ ((unused));
+
+ sc.nr_to_scan = 0;
+ sc.gfp_mask = GFP_KERNEL;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT], [
++ AC_MSG_CHECKING([whether struct shrink_control exists])
++ ZFS_LINUX_TEST_RESULT([shrink_control_struct], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SHRINK_CONTROL_STRUCT, 1,
+- [struct shrink_control exists])
++ [struct shrink_control exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER], [
++ ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK
++ ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_INSTANCES_LIST_HEAD
++ ZFS_AC_KERNEL_SRC_NR_CACHED_OBJECTS
++ ZFS_AC_KERNEL_SRC_FREE_CACHED_OBJECTS
++ ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID
++ ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK
++ ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SHRINKER], [
++ ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK
++ ZFS_AC_KERNEL_SUPER_BLOCK_S_INSTANCES_LIST_HEAD
++ ZFS_AC_KERNEL_NR_CACHED_OBJECTS
++ ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
++ ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID
++ ZFS_AC_KERNEL_SHRINKER_CALLBACK
++ ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT
++])
+diff --git a/config/kernel-submit_bio.m4 b/config/kernel-submit_bio.m4
+index da5f85ca7..cf80e9b83 100644
+--- a/config/kernel-submit_bio.m4
++++ b/config/kernel-submit_bio.m4
+@@ -3,15 +3,19 @@ dnl # 4.8 API change
+ dnl # The rw argument has been removed from submit_bio/submit_bio_wait.
+ dnl # Callers are now expected to set bio->bi_rw instead of passing it in.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SUBMIT_BIO], [
+- AC_MSG_CHECKING([whether submit_bio() wants 1 arg])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SUBMIT_BIO], [
++ ZFS_LINUX_TEST_SRC([submit_bio], [
+ #include <linux/bio.h>
+ ],[
+ blk_qc_t blk_qc;
+ struct bio *bio = NULL;
+ blk_qc = submit_bio(bio);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SUBMIT_BIO], [
++ AC_MSG_CHECKING([whether submit_bio() wants 1 arg])
++ ZFS_LINUX_TEST_RESULT([submit_bio], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_1ARG_SUBMIT_BIO, 1, [submit_bio() wants 1 arg])
+ ],[
+diff --git a/config/kernel-super-userns.m4 b/config/kernel-super-userns.m4
+index de94ad967..1ad35f2d1 100644
+--- a/config/kernel-super-userns.m4
++++ b/config/kernel-super-userns.m4
+@@ -3,15 +3,19 @@ dnl # 4.8 API change
+ dnl # struct user_namespace was added to struct super_block as
+ dnl # super->s_user_ns member
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SUPER_USER_NS], [
+- AC_MSG_CHECKING([whether super_block->s_user_ns exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_USER_NS], [
++ ZFS_LINUX_TEST_SRC([super_user_ns], [
+ #include <linux/fs.h>
+ #include <linux/user_namespace.h>
+- ],[
++ ], [
+ struct super_block super;
+ super.s_user_ns = (struct user_namespace *)NULL;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SUPER_USER_NS], [
++ AC_MSG_CHECKING([whether super_block->s_user_ns exists])
++ ZFS_LINUX_TEST_RESULT([super_user_ns], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SUPER_USER_NS, 1,
+ [super_block->s_user_ns exists])
+diff --git a/config/kernel-timer.m4 b/config/kernel-timer.m4
+index b0e1afa15..5e8fc0d3a 100644
+--- a/config/kernel-timer.m4
++++ b/config/kernel-timer.m4
+@@ -8,13 +8,9 @@ dnl # kernels that support the new timer_list.func signature.
+ dnl #
+ dnl # Also check for the existance of flags in struct timer_list, they were
+ dnl # added in 4.1-rc8 via 0eeda71bc30d.
+-
+-AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
+- AC_MSG_CHECKING([whether timer_setup() is available])
+- tmp_flags="$EXTRA_KCFLAGS"
+- EXTRA_KCFLAGS="-Werror"
+-
+- ZFS_LINUX_TRY_COMPILE([
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_TIMER_SETUP], [
++ ZFS_LINUX_TEST_SRC([timer_setup], [
+ #include <linux/timer.h>
+
+ struct my_task_timer {
+@@ -24,13 +20,34 @@ AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
+
+ void task_expire(struct timer_list *tl)
+ {
+- struct my_task_timer *task_timer = from_timer(task_timer, tl, timer);
++ struct my_task_timer *task_timer =
++ from_timer(task_timer, tl, timer);
+ task_timer->data = 42;
+ }
+ ],[
+ struct my_task_timer task_timer;
+ timer_setup(&task_timer.timer, task_expire, 0);
++ ])
++
++ ZFS_LINUX_TEST_SRC([timer_list_function], [
++ #include <linux/timer.h>
++ void task_expire(struct timer_list *tl) {}
+ ],[
++ struct timer_list tl;
++ tl.function = task_expire;
++ ])
++
++ ZFS_LINUX_TEST_SRC([timer_list_flags], [
++ #include <linux/timer.h>
++ ],[
++ struct timer_list tl;
++ tl.flags = 2;
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
++ AC_MSG_CHECKING([whether timer_setup() is available])
++ ZFS_LINUX_TEST_RESULT([timer_setup], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KERNEL_TIMER_SETUP, 1,
+ [timer_setup() is available])
+@@ -39,14 +56,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
+ ])
+
+ AC_MSG_CHECKING([whether timer function expects timer_list])
+-
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/timer.h>
+- void task_expire(struct timer_list *tl) {}
+- ],[
+- struct timer_list tl;
+- tl.function = task_expire;
+- ],[
++ ZFS_LINUX_TEST_RESULT([timer_list_function], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST, 1,
+ [timer_list.function gets a timer_list])
+@@ -55,19 +65,11 @@ AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
+ ])
+
+ AC_MSG_CHECKING([whether struct timer_list has flags])
+-
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/timer.h>
+- ],[
+- struct timer_list tl;
+- tl.flags = 2;
+- ],[
++ ZFS_LINUX_TEST_RESULT([timer_list_flags], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KERNEL_TIMER_LIST_FLAGS, 1,
+ [struct timer_list has a flags member])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+-
+- EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/config/kernel-tmpfile.m4 b/config/kernel-tmpfile.m4
+index 5aad90450..f510bfe6b 100644
+--- a/config/kernel-tmpfile.m4
++++ b/config/kernel-tmpfile.m4
+@@ -2,9 +2,8 @@ dnl #
+ dnl # 3.11 API change
+ dnl # Add support for i_op->tmpfile
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
+- AC_MSG_CHECKING([whether i_op->tmpfile() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
++ ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
+ #include <linux/fs.h>
+ int tmpfile(struct inode *inode, struct dentry *dentry,
+ umode_t mode) { return 0; }
+@@ -12,11 +11,14 @@ AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
+ iops __attribute__ ((unused)) = {
+ .tmpfile = tmpfile,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
++ AC_MSG_CHECKING([whether i_op->tmpfile() exists])
++ ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_TMPFILE, 1,
+- [i_op->tmpfile() exists])
++ AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-totalhigh_pages.m4 b/config/kernel-totalhigh_pages.m4
+index b22e86d4d..4ecb03a50 100644
+--- a/config/kernel-totalhigh_pages.m4
++++ b/config/kernel-totalhigh_pages.m4
+@@ -1,16 +1,18 @@
+ dnl #
+ dnl # 5.0 API change
+ dnl #
+-dnl # ca79b0c211af mm: convert totalram_pages and totalhigh_pages variables to atomic
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_TOTALHIGH_PAGES], [
+- AC_MSG_CHECKING([whether totalhigh_pages() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES], [
++ ZFS_LINUX_TEST_SRC([totalhigh_pages], [
+ #include <linux/highmem.h>
+ ],[
+ unsigned long pages __attribute__ ((unused));
+ pages = totalhigh_pages();
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_TOTALHIGH_PAGES], [
++ AC_MSG_CHECKING([whether totalhigh_pages() exists])
++ ZFS_LINUX_TEST_RESULT([totalhigh_pages], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_TOTALHIGH_PAGES, 1, [totalhigh_pages() exists])
+ ],[
+diff --git a/config/kernel-totalram-pages-func.m4 b/config/kernel-totalram-pages-func.m4
+index a6eac6454..d0e812a8d 100644
+--- a/config/kernel-totalram-pages-func.m4
++++ b/config/kernel-totalram-pages-func.m4
+@@ -2,16 +2,21 @@ dnl #
+ dnl # Linux 5.0: totalram_pages is no longer a global variable, and must be
+ dnl # read via the totalram_pages() helper function.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC], [
+- AC_MSG_CHECKING([whether totalram_pages() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_TOTALRAM_PAGES_FUNC], [
++ ZFS_LINUX_TEST_SRC([totalram_pages], [
+ #include <linux/mm.h>
+ ],[
+ unsigned long pages __attribute__ ((unused));
+ pages = totalram_pages();
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC], [
++ AC_MSG_CHECKING([whether totalram_pages() exists])
++ ZFS_LINUX_TEST_RESULT([totalram_pages], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_TOTALRAM_PAGES_FUNC, 1, [kernel has totalram_pages()])
++ AC_DEFINE(HAVE_TOTALRAM_PAGES_FUNC, 1,
++ [kernel has totalram_pages()])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-truncate-range.m4 b/config/kernel-truncate-range.m4
+index da2cb50fc..8fdbb1086 100644
+--- a/config/kernel-truncate-range.m4
++++ b/config/kernel-truncate-range.m4
+@@ -4,17 +4,20 @@ dnl # torvalds/linux@17cf28afea2a1112f240a3a2da8af883be024811 removed
+ dnl # truncate_range(). The file hole punching functionality is now
+ dnl # provided by fallocate()
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_RANGE], [
+- AC_MSG_CHECKING([whether iops->truncate_range() exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_TRUNCATE_RANGE], [
++ ZFS_LINUX_TEST_SRC([inode_operations_truncate_range], [
+ #include <linux/fs.h>
+ void truncate_range(struct inode *inode, loff_t start,
+ loff_t end) { return; }
+ static struct inode_operations iops __attribute__ ((unused)) = {
+ .truncate_range = truncate_range,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_RANGE], [
++ AC_MSG_CHECKING([whether iops->truncate_range() exists])
++ ZFS_LINUX_TEST_RESULT([inode_operations_truncate_range], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_TRUNCATE_RANGE, 1,
+ [iops->truncate_range() exists])
+diff --git a/config/kernel-truncate-setsize.m4 b/config/kernel-truncate-setsize.m4
+index 7e4aff479..e719c1444 100644
+--- a/config/kernel-truncate-setsize.m4
++++ b/config/kernel-truncate-setsize.m4
+@@ -2,16 +2,21 @@ dnl #
+ dnl # 2.6.35 API change
+ dnl # Added truncate_setsize() helper function.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_SETSIZE],
+- [AC_MSG_CHECKING([whether truncate_setsize() is available])
+- ZFS_LINUX_TRY_COMPILE_SYMBOL([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE], [
++ ZFS_LINUX_TEST_SRC([truncate_setsize], [
+ #include <linux/mm.h>
+ ], [
+ truncate_setsize(NULL, 0);
+- ], [truncate_setsize], [mm/truncate.c], [
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_SETSIZE], [
++ AC_MSG_CHECKING([whether truncate_setsize() is available])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([truncate_setsize],
++ [truncate_setsize], [mm/truncate.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_TRUNCATE_SETSIZE, 1,
+- [truncate_setsize() is available])
++ [truncate_setsize() is available])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-userns-capabilities.m4 b/config/kernel-userns-capabilities.m4
+index fa3381978..5dcbc03d3 100644
+--- a/config/kernel-userns-capabilities.m4
++++ b/config/kernel-userns-capabilities.m4
+@@ -2,16 +2,19 @@ dnl #
+ dnl # 2.6.38 API change
+ dnl # ns_capable() was introduced
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_NS_CAPABLE], [
+- AC_MSG_CHECKING([whether ns_capable exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_NS_CAPABLE], [
++ ZFS_LINUX_TEST_SRC([ns_capable], [
+ #include <linux/capability.h>
+ ],[
+ ns_capable((struct user_namespace *)NULL, CAP_SYS_ADMIN);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_NS_CAPABLE], [
++ AC_MSG_CHECKING([whether ns_capable exists])
++ ZFS_LINUX_TEST_RESULT([ns_capable], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_NS_CAPABLE, 1,
+- [ns_capable exists])
++ AC_DEFINE(HAVE_NS_CAPABLE, 1, [ns_capable exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -23,17 +26,20 @@ dnl # struct user_namespace was added to struct cred_t as
+ dnl # cred->user_ns member
+ dnl # Note that current_user_ns() was added in 2.6.28.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CRED_USER_NS], [
+- AC_MSG_CHECKING([whether cred_t->user_ns exists])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CRED_USER_NS], [
++ ZFS_LINUX_TEST_SRC([cred_user_ns], [
+ #include <linux/cred.h>
+ ],[
+ struct cred cr;
+ cr.user_ns = (struct user_namespace *)NULL;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CRED_USER_NS], [
++ AC_MSG_CHECKING([whether cred_t->user_ns exists])
++ ZFS_LINUX_TEST_RESULT([cred_user_ns], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_CRED_USER_NS, 1,
+- [cred_t->user_ns exists])
++ AC_DEFINE(HAVE_CRED_USER_NS, 1, [cred_t->user_ns exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -44,14 +50,18 @@ dnl # 3.4 API change
+ dnl # kuid_has_mapping() and kgid_has_mapping() were added to distinguish
+ dnl # between internal kernel uids/gids and user namespace uids/gids.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_KUID_HAS_MAPPING], [
+- AC_MSG_CHECKING([whether kuid_has_mapping/kgid_has_mapping exist])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_KUID_HAS_MAPPING], [
++ ZFS_LINUX_TEST_SRC([kuid_has_mapping], [
+ #include <linux/uidgid.h>
+ ],[
+ kuid_has_mapping((struct user_namespace *)NULL, KUIDT_INIT(0));
+ kgid_has_mapping((struct user_namespace *)NULL, KGIDT_INIT(0));
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_KUID_HAS_MAPPING], [
++ AC_MSG_CHECKING([whether kuid_has_mapping/kgid_has_mapping exist])
++ ZFS_LINUX_TEST_RESULT([kuid_has_mapping], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_KUID_HAS_MAPPING, 1,
+ [kuid_has_mapping/kgid_has_mapping exist])
+@@ -60,6 +70,12 @@ AC_DEFUN([ZFS_AC_KERNEL_KUID_HAS_MAPPING], [
+ ])
+ ])
+
++AC_DEFUN([ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES], [
++ ZFS_AC_KERNEL_SRC_NS_CAPABLE
++ ZFS_AC_KERNEL_SRC_CRED_USER_NS
++ ZFS_AC_KERNEL_SRC_KUID_HAS_MAPPING
++])
++
+ AC_DEFUN([ZFS_AC_KERNEL_USERNS_CAPABILITIES], [
+ ZFS_AC_KERNEL_NS_CAPABLE
+ ZFS_AC_KERNEL_CRED_USER_NS
+diff --git a/config/kernel-urange-sleep.m4 b/config/kernel-usleep_range.m4
+similarity index 60%
+rename from config/kernel-urange-sleep.m4
+rename to config/kernel-usleep_range.m4
+index b5764de3e..5bf051ab4 100644
+--- a/config/kernel-urange-sleep.m4
++++ b/config/kernel-usleep_range.m4
+@@ -1,20 +1,23 @@
+ dnl #
+-dnl # 2.6.36 API compatibility.
+-dnl # Added usleep_range timer.
++dnl # 2.6.36 API compatibility- Added usleep_range timer.
++dnl #
+ dnl # usleep_range is a finer precision implementation of msleep
+ dnl # designed to be a drop-in replacement for udelay where a precise
+ dnl # sleep / busy-wait is unnecessary.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_USLEEP_RANGE], [
+- AC_MSG_CHECKING([whether usleep_range() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_USLEEP_RANGE], [
++ ZFS_LINUX_TEST_SRC([usleep_range], [
+ #include <linux/delay.h>
+ ],[
+ usleep_range(0, 0);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_USLEEP_RANGE], [
++ AC_MSG_CHECKING([whether usleep_range() is available])
++ ZFS_LINUX_TEST_RESULT([usleep_range], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_USLEEP_RANGE, 1,
+- [usleep_range is available])
++ AC_DEFINE(HAVE_USLEEP_RANGE, 1, [usleep_range is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-vfs-direct_IO.m4 b/config/kernel-vfs-direct_IO.m4
+index cc50bfbe4..82583d52f 100644
+--- a/config/kernel-vfs-direct_IO.m4
++++ b/config/kernel-vfs-direct_IO.m4
+@@ -1,9 +1,8 @@
+ dnl #
+-dnl # Linux 4.6.x API change
++dnl # Check for direct IO interfaces.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER], [
+- AC_MSG_CHECKING([whether aops->direct_IO() uses iov_iter])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO], [
++ ZFS_LINUX_TEST_SRC([direct_io_iter], [
+ #include <linux/fs.h>
+
+ ssize_t test_direct_IO(struct kiocb *kiocb,
+@@ -13,24 +12,9 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER], [
+ aops __attribute__ ((unused)) = {
+ .direct_IO = test_direct_IO,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT([yes])
+- AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER, 1,
+- [aops->direct_IO() uses iov_iter without rw])
+- zfs_ac_direct_io="yes"
+- ],[
+- AC_MSG_RESULT([no])
+- ])
+-])
++ ],[])
+
+-dnl #
+-dnl # Linux 4.1.x API change
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_OFFSET], [
+- AC_MSG_CHECKING(
+- [whether aops->direct_IO() uses iov_iter with offset])
+- ZFS_LINUX_TRY_COMPILE([
++ ZFS_LINUX_TEST_SRC([direct_io_iter_offset], [
+ #include <linux/fs.h>
+
+ ssize_t test_direct_IO(struct kiocb *kiocb,
+@@ -40,24 +24,9 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_OFFSET], [
+ aops __attribute__ ((unused)) = {
+ .direct_IO = test_direct_IO,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT([yes])
+- AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_OFFSET, 1,
+- [aops->direct_IO() uses iov_iter with offset])
+- zfs_ac_direct_io="yes"
+- ],[
+- AC_MSG_RESULT([no])
+- ])
+-])
++ ],[])
+
+-dnl #
+-dnl # Linux 3.16.x API change
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_RW_OFFSET], [
+- AC_MSG_CHECKING(
+- [whether aops->direct_IO() uses iov_iter with rw and offset])
+- ZFS_LINUX_TRY_COMPILE([
++ ZFS_LINUX_TEST_SRC([direct_io_iter_rw_offset], [
+ #include <linux/fs.h>
+
+ ssize_t test_direct_IO(int rw, struct kiocb *kiocb,
+@@ -67,23 +36,9 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_RW_OFFSET], [
+ aops __attribute__ ((unused)) = {
+ .direct_IO = test_direct_IO,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT([yes])
+- AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_RW_OFFSET, 1,
+- [aops->direct_IO() uses iov_iter with rw and offset])
+- zfs_ac_direct_io="yes"
+- ],[
+- AC_MSG_RESULT([no])
+- ])
+-])
++ ],[])
+
+-dnl #
+-dnl # Ancient Linux API (predates git)
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_IOVEC], [
+- AC_MSG_CHECKING([whether aops->direct_IO() uses iovec])
+- ZFS_LINUX_TRY_COMPILE([
++ ZFS_LINUX_TEST_SRC([direct_io_iovec], [
+ #include <linux/fs.h>
+
+ ssize_t test_direct_IO(int rw, struct kiocb *kiocb,
+@@ -94,37 +49,61 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_IOVEC], [
+ aops __attribute__ ((unused)) = {
+ .direct_IO = test_direct_IO,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT([yes])
+- AC_DEFINE(HAVE_VFS_DIRECT_IO_IOVEC, 1,
+- [aops->direct_IO() uses iovec])
+- zfs_ac_direct_io="yes"
+- ],[
+- AC_MSG_RESULT([no])
+- ])
++ ],[])
+ ])
+
+ AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO], [
+- zfs_ac_direct_io="no"
+-
+- if test "$zfs_ac_direct_io" = "no"; then
+- ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER
+- fi
+-
+- if test "$zfs_ac_direct_io" = "no"; then
+- ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_OFFSET
+- fi
+-
+- if test "$zfs_ac_direct_io" = "no"; then
+- ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_RW_OFFSET
+- fi
+-
+- if test "$zfs_ac_direct_io" = "no"; then
+- ZFS_AC_KERNEL_VFS_DIRECT_IO_IOVEC
+- fi
++ dnl #
++ dnl # Linux 4.6.x API change
++ dnl #
++ AC_MSG_CHECKING([whether aops->direct_IO() uses iov_iter])
++ ZFS_LINUX_TEST_RESULT([direct_io_iter], [
++ AC_MSG_RESULT([yes])
++ AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER, 1,
++ [aops->direct_IO() uses iov_iter without rw])
++ ],[
++ AC_MSG_RESULT([no])
+
+- if test "$zfs_ac_direct_io" = "no"; then
+- AC_MSG_ERROR([no; unknown direct IO interface])
+- fi
++ dnl #
++ dnl # Linux 4.1.x API change
++ dnl #
++ AC_MSG_CHECKING(
++ [whether aops->direct_IO() uses offset])
++ ZFS_LINUX_TEST_RESULT([direct_io_iter_offset], [
++ AC_MSG_RESULT([yes])
++ AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_OFFSET, 1,
++ [aops->direct_IO() uses iov_iter with offset])
++
++ ],[
++ AC_MSG_RESULT([no])
++
++ dnl #
++ dnl # Linux 3.16.x API change
++ dnl #
++ AC_MSG_CHECKING(
++ [whether aops->direct_IO() uses rw and offset])
++ ZFS_LINUX_TEST_RESULT([direct_io_iter_rw_offset], [
++ AC_MSG_RESULT([yes])
++ AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_RW_OFFSET, 1,
++ [aops->direct_IO() uses iov_iter with ]
++ [rw and offset])
++ ],[
++ AC_MSG_RESULT([no])
++
++ dnl #
++ dnl # Ancient Linux API (predates git)
++ dnl #
++ AC_MSG_CHECKING(
++ [whether aops->direct_IO() uses iovec])
++ ZFS_LINUX_TEST_RESULT([direct_io_iovec], [
++ AC_MSG_RESULT([yes])
++ AC_DEFINE(HAVE_VFS_DIRECT_IO_IOVEC, 1,
++ [aops->direct_IO() uses iovec])
++ ],[
++ ZFS_LINUX_TEST_ERROR([direct IO])
++ AC_MSG_RESULT([no])
++ ])
++ ])
++ ])
++ ])
+ ])
+diff --git a/config/kernel-vfs-fsync.m4 b/config/kernel-vfs-fsync.m4
+index a474f9f17..18a60d29a 100644
+--- a/config/kernel-vfs-fsync.m4
++++ b/config/kernel-vfs-fsync.m4
+@@ -2,13 +2,17 @@ dnl #
+ dnl # 2.6.35 API change,
+ dnl # Unused 'struct dentry *' removed from vfs_fsync() prototype.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_2ARGS_VFS_FSYNC], [
+- AC_MSG_CHECKING([whether vfs_fsync() wants 2 args])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS], [
++ ZFS_LINUX_TEST_SRC([vfs_fsync_2args], [
+ #include <linux/fs.h>
+ ],[
+ vfs_fsync(NULL, 0);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_VFS_FSYNC_2ARGS], [
++ AC_MSG_CHECKING([whether vfs_fsync() wants 2 args])
++ ZFS_LINUX_TEST_RESULT([vfs_fsync_2args], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_2ARGS_VFS_FSYNC, 1, [vfs_fsync() wants 2 args])
+ ],[
+diff --git a/config/kernel-vfs-getattr.m4 b/config/kernel-vfs-getattr.m4
+index b13723538..eb07853cc 100644
+--- a/config/kernel-vfs-getattr.m4
++++ b/config/kernel-vfs-getattr.m4
+@@ -2,19 +2,23 @@ dnl #
+ dnl # 4.11 API, a528d35e@torvalds/linux
+ dnl # vfs_getattr(const struct path *p, struct kstat *s, u32 m, unsigned int f)
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_4ARGS_VFS_GETATTR], [
+- AC_MSG_CHECKING([whether vfs_getattr() wants 4 args])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR_4ARGS], [
++ ZFS_LINUX_TEST_SRC([vfs_getattr_4args], [
+ #include <linux/fs.h>
+ ],[
+ vfs_getattr((const struct path *)NULL,
+ (struct kstat *)NULL,
+ (u32)0,
+ (unsigned int)0);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR_4ARGS], [
++ AC_MSG_CHECKING([whether vfs_getattr() wants 4 args])
++ ZFS_LINUX_TEST_RESULT([vfs_getattr_4args], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_4ARGS_VFS_GETATTR, 1,
+- [vfs_getattr wants 4 args])
++ [vfs_getattr wants 4 args])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -24,17 +28,21 @@ dnl #
+ dnl # 3.9 API
+ dnl # vfs_getattr(struct path *p, struct kstat *s)
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_2ARGS_VFS_GETATTR], [
+- AC_MSG_CHECKING([whether vfs_getattr() wants 2 args])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR_2ARGS], [
++ ZFS_LINUX_TEST_SRC([vfs_getattr_2args], [
+ #include <linux/fs.h>
+ ],[
+ vfs_getattr((struct path *) NULL,
+ (struct kstat *)NULL);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR_2ARGS], [
++ AC_MSG_CHECKING([whether vfs_getattr() wants 2 args])
++ ZFS_LINUX_TEST_RESULT([vfs_getattr_2args], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_2ARGS_VFS_GETATTR, 1,
+- [vfs_getattr wants 2 args])
++ [vfs_getattr wants 2 args])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -44,19 +52,35 @@ dnl #
+ dnl # <3.9 API
+ dnl # vfs_getattr(struct vfsmount *v, struct dentry *d, struct kstat *k)
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_3ARGS_VFS_GETATTR], [
+- AC_MSG_CHECKING([whether vfs_getattr() wants 3 args])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR_3ARGS], [
++ ZFS_LINUX_TEST_SRC([vfs_getattr_3args], [
+ #include <linux/fs.h>
+ ],[
+ vfs_getattr((struct vfsmount *)NULL,
+ (struct dentry *)NULL,
+ (struct kstat *)NULL);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR_3ARGS], [
++ AC_MSG_CHECKING([whether vfs_getattr() wants 3 args])
++ ZFS_LINUX_TEST_RESULT([vfs_getattr_3args], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_3ARGS_VFS_GETATTR, 1,
+- [vfs_getattr wants 3 args])
++ [vfs_getattr wants 3 args])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR], [
++ ZFS_AC_KERNEL_SRC_VFS_GETATTR_4ARGS
++ ZFS_AC_KERNEL_SRC_VFS_GETATTR_2ARGS
++ ZFS_AC_KERNEL_SRC_VFS_GETATTR_3ARGS
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR], [
++ ZFS_AC_KERNEL_VFS_GETATTR_4ARGS
++ ZFS_AC_KERNEL_VFS_GETATTR_2ARGS
++ ZFS_AC_KERNEL_VFS_GETATTR_3ARGS
++])
+diff --git a/config/kernel-vfs-iterate.m4 b/config/kernel-vfs-iterate.m4
+index 5de901d44..172118eac 100644
+--- a/config/kernel-vfs-iterate.m4
++++ b/config/kernel-vfs-iterate.m4
+@@ -1,9 +1,5 @@
+-AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
+- dnl #
+- dnl # 4.7 API change
+- dnl #
+- AC_MSG_CHECKING([whether fops->iterate_shared() is available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_ITERATE], [
++ ZFS_LINUX_TEST_SRC([file_operations_iterate_shared], [
+ #include <linux/fs.h>
+ int iterate(struct file *filp, struct dir_context * context)
+ { return 0; }
+@@ -12,11 +8,44 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
+ __attribute__ ((unused)) = {
+ .iterate_shared = iterate,
+ };
+- ],[
+- ],[
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([file_operations_iterate], [
++ #include <linux/fs.h>
++ int iterate(struct file *filp,
++ struct dir_context *context) { return 0; }
++
++ static const struct file_operations fops
++ __attribute__ ((unused)) = {
++ .iterate = iterate,
++ };
++
++ #if defined(FMODE_KABI_ITERATE)
++ #error "RHEL 7.5, FMODE_KABI_ITERATE interface"
++ #endif
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([file_operations_readdir], [
++ #include <linux/fs.h>
++ int readdir(struct file *filp, void *entry,
++ filldir_t func) { return 0; }
++
++ static const struct file_operations fops
++ __attribute__ ((unused)) = {
++ .readdir = readdir,
++ };
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
++ dnl #
++ dnl # 4.7 API change
++ dnl #
++ AC_MSG_CHECKING([whether fops->iterate_shared() is available])
++ ZFS_LINUX_TEST_RESULT([file_operations_iterate_shared], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_VFS_ITERATE_SHARED, 1,
+- [fops->iterate_shared() is available])
++ [fops->iterate_shared() is available])
+ ],[
+ AC_MSG_RESULT(no)
+
+@@ -31,44 +60,23 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
+ dnl # to using fops.readdir() to retain KABI compatibility.
+ dnl #
+ AC_MSG_CHECKING([whether fops->iterate() is available])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- int iterate(struct file *filp,
+- struct dir_context *context) { return 0; }
+-
+- static const struct file_operations fops
+- __attribute__ ((unused)) = {
+- .iterate = iterate,
+- };
+-
+- #if defined(FMODE_KABI_ITERATE)
+- #error "RHEL 7.5, FMODE_KABI_ITERATE interface"
+- #endif
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT([file_operations_iterate], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_VFS_ITERATE, 1,
+- [fops->iterate() is available])
++ [fops->iterate() is available])
+ ],[
+ AC_MSG_RESULT(no)
+
++ dnl #
++ dnl # readdir interface introduced
++ dnl #
+ AC_MSG_CHECKING([whether fops->readdir() is available])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- int readdir(struct file *filp, void *entry,
+- filldir_t func) { return 0; }
+-
+- static const struct file_operations fops
+- __attribute__ ((unused)) = {
+- .readdir = readdir,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT([file_operations_readdir], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_VFS_READDIR, 1,
+- [fops->readdir() is available])
++ [fops->readdir() is available])
+ ],[
+- AC_MSG_ERROR(no; file a bug report with ZoL)
++ ZFS_LINUX_TEST_ERROR([vfs_iterate])
+ ])
+ ])
+ ])
+diff --git a/config/kernel-vfs-rw-iterate.m4 b/config/kernel-vfs-rw-iterate.m4
+index ace54f707..000353ec1 100644
+--- a/config/kernel-vfs-rw-iterate.m4
++++ b/config/kernel-vfs-rw-iterate.m4
+@@ -1,9 +1,8 @@
+ dnl #
+ dnl # Linux 3.16 API
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
+- [AC_MSG_CHECKING([whether fops->read/write_iter() are available])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_RW_ITERATE], [
++ ZFS_LINUX_TEST_SRC([file_operations_rw], [
+ #include <linux/fs.h>
+
+ ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to)
+@@ -16,39 +15,41 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
+ .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])
++ ],[])
+
+- ZFS_AC_KERNEL_NEW_SYNC_READ
++ ZFS_LINUX_TEST_SRC([new_sync_rw], [
++ #include <linux/fs.h>
+ ],[
+- AC_MSG_RESULT(no)
++ ssize_t ret __attribute__ ((unused));
++ struct file *filp = NULL;
++ char __user *rbuf = NULL;
++ const char __user *wbuf = NULL;
++ size_t len = 0;
++ loff_t ppos;
++
++ ret = new_sync_read(filp, rbuf, len, &ppos);
++ ret = new_sync_write(filp, wbuf, len, &ppos);
+ ])
+ ])
+
+-dnl #
+-dnl # Linux 4.1 API
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_NEW_SYNC_READ],
+- [AC_MSG_CHECKING([whether new_sync_read/write() are available])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
+- ],[
+- ssize_t ret __attribute__ ((unused));
+- struct file *filp = NULL;
+- char __user *rbuf = NULL;
+- const char __user *wbuf = NULL;
+- size_t len = 0;
+- loff_t ppos;
+-
+- ret = new_sync_read(filp, rbuf, len, &ppos);
+- ret = new_sync_write(filp, wbuf, len, &ppos);
+- ],[
++AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE], [
++ AC_MSG_CHECKING([whether fops->read/write_iter() are available])
++ ZFS_LINUX_TEST_RESULT([file_operations_rw], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_NEW_SYNC_READ, 1,
+- [new_sync_read()/new_sync_write() are available])
++ AC_DEFINE(HAVE_VFS_RW_ITERATE, 1,
++ [fops->read/write_iter() are available])
++
++ dnl #
++ dnl # Linux 4.1 API
++ dnl #
++ AC_MSG_CHECKING([whether new_sync_read/write() are available])
++ ZFS_LINUX_TEST_RESULT([new_sync_rw], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_NEW_SYNC_READ, 1,
++ [new_sync_read()/new_sync_write() are available])
++ ],[
++ AC_MSG_RESULT(no)
++ ])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -57,19 +58,22 @@ AC_DEFUN([ZFS_AC_KERNEL_NEW_SYNC_READ],
+ dnl #
+ dnl # Linux 4.1.x API
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_GENERIC_WRITE_CHECKS],
+- [AC_MSG_CHECKING([whether generic_write_checks() takes kiocb])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GENERIC_WRITE_CHECKS], [
++ ZFS_LINUX_TEST_SRC([generic_write_checks], [
+ #include <linux/fs.h>
+-
+ ],[
+ struct kiocb *iocb = NULL;
+ struct iov_iter *iov = NULL;
+ generic_write_checks(iocb, iov);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_VFS_GENERIC_WRITE_CHECKS], [
++ AC_MSG_CHECKING([whether generic_write_checks() takes kiocb])
++ ZFS_LINUX_TEST_RESULT([generic_write_checks], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_GENERIC_WRITE_CHECKS_KIOCB, 1,
+- [generic_write_checks() takes kiocb])
++ [generic_write_checks() takes kiocb])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel-wait.m4 b/config/kernel-wait.m4
+index d6442c1df..0414242bf 100644
+--- a/config/kernel-wait.m4
++++ b/config/kernel-wait.m4
+@@ -1,3 +1,26 @@
++dnl #
++dnl # 4.13 API change
++dnl # Renamed struct wait_queue -> struct wait_queue_entry.
++dnl #
++dnl # N.B. The type check is performed before all other checks
++dnl # since ZFS_AC_KERNEL_SRC_WAIT_QUEUE_HEAD_ENTRY depends on
++dnl # HAVE_WAIT_QUEUE_ENTRY_T being set in confdefs.h.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T], [
++ AC_MSG_CHECKING([whether wait_queue_entry_t exists])
++ ZFS_LINUX_TRY_COMPILE([
++ #include <linux/wait.h>
++ ],[
++ wait_queue_entry_t *entry __attribute__ ((unused));
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_WAIT_QUEUE_ENTRY_T, 1,
++ [wait_queue_entry_t exists])
++ ],[
++ AC_MSG_RESULT(no)
++ ])
++])
++
+ dnl #
+ dnl # 3.17 API change,
+ dnl # wait_on_bit() no longer requires an action argument. The former
+@@ -8,34 +31,20 @@ dnl # of just two functions: one which uses io_schedule() and one which just
+ dnl # uses schedule(). This API change was made to consolidate all of those
+ dnl # redundant wait functions.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_WAIT_ON_BIT], [
+- AC_MSG_CHECKING([whether wait_on_bit() takes an action])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_WAIT_ON_BIT], [
++ ZFS_LINUX_TEST_SRC([wait_on_bit], [
+ #include <linux/wait.h>
+ ],[
+ int (*action)(void *) = NULL;
+ wait_on_bit(NULL, 0, action, 0);
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_WAIT_ON_BIT_ACTION, 1, [yes])
+- ],[
+- AC_MSG_RESULT(no)
+ ])
+ ])
+-dnl #
+-dnl # 4.13 API change
+-dnl # Renamed struct wait_queue -> struct wait_queue_entry.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T], [
+- AC_MSG_CHECKING([whether wait_queue_entry_t exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/wait.h>
+- ],[
+- wait_queue_entry_t *entry __attribute__ ((unused));
+- ],[
++
++AC_DEFUN([ZFS_AC_KERNEL_WAIT_ON_BIT], [
++ AC_MSG_CHECKING([whether wait_on_bit() takes an action])
++ ZFS_LINUX_TEST_RESULT([wait_on_bit], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_WAIT_QUEUE_ENTRY_T, 1,
+- [wait_queue_entry_t exists])
++ AC_DEFINE(HAVE_WAIT_ON_BIT_ACTION, 1, [yes])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+@@ -46,9 +55,8 @@ dnl # 4.13 API change
+ dnl # Renamed wait_queue_head::task_list -> wait_queue_head::head
+ dnl # Renamed wait_queue_entry::task_list -> wait_queue_entry::entry
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY], [
+- AC_MSG_CHECKING([whether wq_head->head and wq_entry->entry exist])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_WAIT_QUEUE_HEAD_ENTRY], [
++ ZFS_LINUX_TEST_SRC([wait_queue_head_entry], [
+ #include <linux/wait.h>
+
+ #ifdef HAVE_WAIT_QUEUE_ENTRY_T
+@@ -66,7 +74,12 @@ AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY], [
+
+ head = &wq_head.head;
+ entry = &wq_entry.entry;
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY], [
++ AC_MSG_CHECKING([whether wq_head->head and wq_entry->entry exist])
++ ZFS_LINUX_TEST_RESULT([wait_queue_head_entry], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_WAIT_QUEUE_HEAD_ENTRY, 1,
+ [wq_head->head and wq_entry->entry exist])
+@@ -74,3 +87,13 @@ AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY], [
+ AC_MSG_RESULT(no)
+ ])
+ ])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_WAIT], [
++ ZFS_AC_KERNEL_SRC_WAIT_ON_BIT
++ ZFS_AC_KERNEL_SRC_WAIT_QUEUE_HEAD_ENTRY
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_WAIT], [
++ ZFS_AC_KERNEL_WAIT_ON_BIT
++ ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY
++])
+diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
+index 0b61b85b1..ed84c6390 100644
+--- a/config/kernel-xattr-handler.m4
++++ b/config/kernel-xattr-handler.m4
+@@ -3,9 +3,8 @@ dnl # 2.6.35 API change,
+ dnl # The 'struct xattr_handler' was constified in the generic
+ dnl # super_block structure.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [
+- AC_MSG_CHECKING([whether super_block uses const struct xattr_handler])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CONST_XATTR_HANDLER], [
++ ZFS_LINUX_TEST_SRC([const_xattr_handler], [
+ #include <linux/fs.h>
+ #include <linux/xattr.h>
+
+@@ -22,11 +21,15 @@ AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [
+ const struct super_block sb __attribute__ ((unused)) = {
+ .s_xattr = xattr_handlers,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [
++ AC_MSG_CHECKING([whether super_block uses const struct xattr_handler])
++ ZFS_LINUX_TEST_RESULT([const_xattr_handler], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_CONST_XATTR_HANDLER, 1,
+- [super_block uses const struct xattr_handler])
++ [super_block uses const struct xattr_handler])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+@@ -38,17 +41,20 @@ dnl # struct xattr_handler added new member "name".
+ dnl # xattr_handler which matches to whole name rather than prefix should use
+ dnl # "name" instead of "prefix", e.g. "system.posix_acl_access"
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [
+- AC_MSG_CHECKING([whether xattr_handler has name])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_NAME], [
++ ZFS_LINUX_TEST_SRC([xattr_handler_name], [
+ #include <linux/xattr.h>
+
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .name = XATTR_NAME_POSIX_ACL_ACCESS,
+ };
+- ],[
+- ],[
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [
++ AC_MSG_CHECKING([whether xattr_handler has name])
++ ZFS_LINUX_TEST_RESULT([xattr_handler_name], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_HANDLER_NAME, 1,
+ [xattr_handler has name])
+@@ -58,52 +64,65 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [
+ ])
+
+ dnl #
+-dnl # 4.9 API change,
+-dnl # iops->{set,get,remove}xattr and generic_{set,get,remove}xattr are
+-dnl # removed. xattr operations will directly go through sb->s_xattr.
++dnl # Supported xattr handler get() interfaces checked newest to oldest.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR], [
+- AC_MSG_CHECKING([whether generic_setxattr() exists])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/fs.h>
++AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_GET], [
++ ZFS_LINUX_TEST_SRC([xattr_handler_get_dentry_inode], [
+ #include <linux/xattr.h>
+
+- static const struct inode_operations
+- iops __attribute__ ((unused)) = {
+- .setxattr = generic_setxattr
++ int get(const struct xattr_handler *handler,
++ struct dentry *dentry, struct inode *inode,
++ const char *name, void *buffer, size_t size) { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .get = get,
+ };
+- ],[
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_GENERIC_SETXATTR, 1,
+- [generic_setxattr() exists])
+- ],[
+- AC_MSG_RESULT(no)
+- ])
+-])
++ ],[])
+
+-dnl #
+-dnl # Supported xattr handler get() interfaces checked newest to oldest.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
+- dnl #
+- dnl # 4.7 API change,
+- dnl # The xattr_handler->get() callback was changed to take both
+- dnl # dentry and inode.
+- dnl #
+- AC_MSG_CHECKING([whether xattr_handler->get() wants both dentry and inode])
+- ZFS_LINUX_TRY_COMPILE([
++ ZFS_LINUX_TEST_SRC([xattr_handler_get_xattr_handler], [
+ #include <linux/xattr.h>
+
+ int get(const struct xattr_handler *handler,
+- struct dentry *dentry, struct inode *inode,
+- const char *name, void *buffer, size_t size) { return 0; }
++ struct dentry *dentry, const char *name,
++ void *buffer, size_t size) { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .get = get,
+ };
+- ],[
+- ],[
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([xattr_handler_get_dentry], [
++ #include <linux/xattr.h>
++
++ int get(struct dentry *dentry, const char *name,
++ void *buffer, size_t size, int handler_flags)
++ { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .get = get,
++ };
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([xattr_handler_get_inode], [
++ #include <linux/xattr.h>
++
++ int get(struct inode *ip, const char *name,
++ void *buffer, size_t size) { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .get = get,
++ };
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
++ dnl #
++ dnl # 4.7 API change,
++ dnl # The xattr_handler->get() callback was changed to take both
++ dnl # dentry and inode.
++ dnl #
++ AC_MSG_CHECKING([whether xattr_handler->get() wants dentry and inode])
++ ZFS_LINUX_TEST_RESULT([xattr_handler_get_dentry_inode], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1,
+ [xattr_handler->get() wants both dentry and inode])
+@@ -115,69 +134,40 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
+ dnl # should be accessed by handler->flags.
+ dnl #
+ AC_MSG_RESULT(no)
+- AC_MSG_CHECKING([whether xattr_handler->get() wants xattr_handler])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/xattr.h>
+-
+- int get(const struct xattr_handler *handler,
+- struct dentry *dentry, const char *name,
+- void *buffer, size_t size) { return 0; }
+- static const struct xattr_handler
+- xops __attribute__ ((unused)) = {
+- .get = get,
+- };
+- ],[
+- ],[
++ AC_MSG_CHECKING(
++ [whether xattr_handler->get() wants xattr_handler])
++ ZFS_LINUX_TEST_RESULT([xattr_handler_get_xattr_handler], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1,
+ [xattr_handler->get() wants xattr_handler])
+ ],[
+ dnl #
+ dnl # 2.6.33 API change,
+- dnl # The xattr_handler->get() callback was changed to take
+- dnl # a dentry instead of an inode, and a handler_flags
+- dnl # argument was added.
++ dnl # The xattr_handler->get() callback was changed
++ dnl # to take a dentry instead of an inode, and a
++ dnl # handler_flags argument was added.
+ dnl #
+ AC_MSG_RESULT(no)
+- AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/xattr.h>
+-
+- int get(struct dentry *dentry, const char *name,
+- void *buffer, size_t size, int handler_flags)
+- { return 0; }
+- static const struct xattr_handler
+- xops __attribute__ ((unused)) = {
+- .get = get,
+- };
+- ],[
+- ],[
++ AC_MSG_CHECKING(
++ [whether xattr_handler->get() wants dentry])
++ ZFS_LINUX_TEST_RESULT([xattr_handler_get_dentry], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1,
+ [xattr_handler->get() wants dentry])
+ ],[
+ dnl #
+- dnl # 2.6.32 API
++ dnl # Legacy 2.6.32 API
+ dnl #
+ AC_MSG_RESULT(no)
+ AC_MSG_CHECKING(
+ [whether xattr_handler->get() wants inode])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/xattr.h>
+-
+- int get(struct inode *ip, const char *name,
+- void *buffer, size_t size) { return 0; }
+- static const struct xattr_handler
+- xops __attribute__ ((unused)) = {
+- .get = get,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT(
++ [xattr_handler_get_inode], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_GET_INODE, 1,
+ [xattr_handler->get() wants inode])
+ ],[
+- AC_MSG_ERROR([no; please file a bug report])
++ ZFS_LINUX_TEST_ERROR([xattr get()])
+ ])
+ ])
+ ])
+@@ -187,14 +177,8 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
+ dnl #
+ dnl # Supported xattr handler set() interfaces checked newest to oldest.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+- dnl #
+- dnl # 4.7 API change,
+- dnl # The xattr_handler->set() callback was changed to take both
+- dnl # dentry and inode.
+- dnl #
+- AC_MSG_CHECKING([whether xattr_handler->set() wants both dentry and inode])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
++ ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [
+ #include <linux/xattr.h>
+
+ int set(const struct xattr_handler *handler,
+@@ -206,8 +190,54 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+ xops __attribute__ ((unused)) = {
+ .set = set,
+ };
+- ],[
+- ],[
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([xattr_handler_set_xattr_handler], [
++ #include <linux/xattr.h>
++
++ int set(const struct xattr_handler *handler,
++ struct dentry *dentry, const char *name,
++ const void *buffer, size_t size, int flags)
++ { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .set = set,
++ };
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry], [
++ #include <linux/xattr.h>
++
++ int set(struct dentry *dentry, const char *name,
++ const void *buffer, size_t size, int flags,
++ int handler_flags) { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .set = set,
++ };
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([xattr_handler_set_inode], [
++ #include <linux/xattr.h>
++
++ int set(struct inode *ip, const char *name,
++ const void *buffer, size_t size, int flags)
++ { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .set = set,
++ };
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
++ dnl #
++ dnl # 4.7 API change,
++ dnl # The xattr_handler->set() callback was changed to take both
++ dnl # dentry and inode.
++ dnl #
++ AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
++ ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
+ [xattr_handler->set() wants both dentry and inode])
+@@ -219,71 +249,40 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+ dnl # should be accessed by handler->flags.
+ dnl #
+ AC_MSG_RESULT(no)
+- AC_MSG_CHECKING([whether xattr_handler->set() wants xattr_handler])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/xattr.h>
+-
+- int set(const struct xattr_handler *handler,
+- struct dentry *dentry, const char *name,
+- const void *buffer, size_t size, int flags)
+- { return 0; }
+- static const struct xattr_handler
+- xops __attribute__ ((unused)) = {
+- .set = set,
+- };
+- ],[
+- ],[
++ AC_MSG_CHECKING(
++ [whether xattr_handler->set() wants xattr_handler])
++ ZFS_LINUX_TEST_RESULT([xattr_handler_set_xattr_handler], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
+ [xattr_handler->set() wants xattr_handler])
+ ],[
+ dnl #
+ dnl # 2.6.33 API change,
+- dnl # The xattr_handler->set() callback was changed to take a
+- dnl # dentry instead of an inode, and a handler_flags
+- dnl # argument was added.
++ dnl # The xattr_handler->set() callback was changed
++ dnl # to take a dentry instead of an inode, and a
++ dnl # handler_flags argument was added.
+ dnl #
+ AC_MSG_RESULT(no)
+- AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/xattr.h>
+-
+- int set(struct dentry *dentry, const char *name,
+- const void *buffer, size_t size, int flags,
+- int handler_flags) { return 0; }
+- static const struct xattr_handler
+- xops __attribute__ ((unused)) = {
+- .set = set,
+- };
+- ],[
+- ],[
++ AC_MSG_CHECKING(
++ [whether xattr_handler->set() wants dentry])
++ ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
+ [xattr_handler->set() wants dentry])
+ ],[
+ dnl #
+- dnl # 2.6.32 API
++ dnl # Legacy 2.6.32 API
+ dnl #
+ AC_MSG_RESULT(no)
+ AC_MSG_CHECKING(
+ [whether xattr_handler->set() wants inode])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/xattr.h>
+-
+- int set(struct inode *ip, const char *name,
+- const void *buffer, size_t size, int flags)
+- { return 0; }
+- static const struct xattr_handler
+- xops __attribute__ ((unused)) = {
+- .set = set,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT(
++ [xattr_handler_set_inode], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_SET_INODE, 1,
+ [xattr_handler->set() wants inode])
+ ],[
+- AC_MSG_ERROR([no; please file a bug report])
++ ZFS_LINUX_TEST_ERROR([xattr set()])
+ ])
+ ])
+ ])
+@@ -293,12 +292,8 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+ dnl #
+ dnl # Supported xattr handler list() interfaces checked newest to oldest.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
+- dnl # 4.5 API change,
+- dnl # The xattr_handler->list() callback was changed to take only a
+- dnl # dentry and it only needs to return if it's accessible.
+- AC_MSG_CHECKING([whether xattr_handler->list() wants simple])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_LIST], [
++ ZFS_LINUX_TEST_SRC([xattr_handler_list_simple], [
+ #include <linux/xattr.h>
+
+ bool list(struct dentry *dentry) { return 0; }
+@@ -306,8 +301,52 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
+ xops __attribute__ ((unused)) = {
+ .list = list,
+ };
+- ],[
+- ],[
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([xattr_handler_list_xattr_handler], [
++ #include <linux/xattr.h>
++
++ size_t list(const struct xattr_handler *handler,
++ struct dentry *dentry, char *list, size_t list_size,
++ const char *name, size_t name_len) { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .list = list,
++ };
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([xattr_handler_list_dentry], [
++ #include <linux/xattr.h>
++
++ size_t list(struct dentry *dentry,
++ char *list, size_t list_size,
++ const char *name, size_t name_len,
++ int handler_flags) { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .list = list,
++ };
++ ],[])
++
++ ZFS_LINUX_TEST_SRC([xattr_handler_list_inode], [
++ #include <linux/xattr.h>
++
++ size_t list(struct inode *ip, char *lst,
++ size_t list_size, const char *name,
++ size_t name_len) { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .list = list,
++ };
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
++ dnl # 4.5 API change,
++ dnl # The xattr_handler->list() callback was changed to take only a
++ dnl # dentry and it only needs to return if it's accessible.
++ AC_MSG_CHECKING([whether xattr_handler->list() wants simple])
++ ZFS_LINUX_TEST_RESULT([xattr_handler_list_simple], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_LIST_SIMPLE, 1,
+ [xattr_handler->list() wants simple])
+@@ -321,18 +360,7 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
+ AC_MSG_RESULT(no)
+ AC_MSG_CHECKING(
+ [whether xattr_handler->list() wants xattr_handler])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/xattr.h>
+-
+- size_t list(const struct xattr_handler *handler,
+- struct dentry *dentry, char *list, size_t list_size,
+- const char *name, size_t name_len) { return 0; }
+- static const struct xattr_handler
+- xops __attribute__ ((unused)) = {
+- .list = list,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT([xattr_handler_list_xattr_handler], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_LIST_HANDLER, 1,
+ [xattr_handler->list() wants xattr_handler])
+@@ -346,47 +374,24 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
+ AC_MSG_RESULT(no)
+ AC_MSG_CHECKING(
+ [whether xattr_handler->list() wants dentry])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/xattr.h>
+-
+- size_t list(struct dentry *dentry,
+- char *list, size_t list_size,
+- const char *name, size_t name_len,
+- int handler_flags) { return 0; }
+- static const struct xattr_handler
+- xops __attribute__ ((unused)) = {
+- .list = list,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT([xattr_handler_list_dentry], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_LIST_DENTRY, 1,
+ [xattr_handler->list() wants dentry])
+ ],[
+ dnl #
+- dnl # 2.6.32 API
++ dnl # Legacy 2.6.32 API
+ dnl #
+ AC_MSG_RESULT(no)
+ AC_MSG_CHECKING(
+ [whether xattr_handler->list() wants inode])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/xattr.h>
+-
+- size_t list(struct inode *ip, char *lst,
+- size_t list_size, const char *name,
+- size_t name_len) { return 0; }
+- static const struct xattr_handler
+- xops __attribute__ ((unused)) = {
+- .list = list,
+- };
+- ],[
+- ],[
++ ZFS_LINUX_TEST_RESULT(
++ [xattr_handler_list_inode], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_LIST_INODE, 1,
+ [xattr_handler->list() wants inode])
+ ],[
+- AC_MSG_ERROR(
+- [no; please file a bug report])
++ ZFS_LINUX_TEST_ERROR([xattr list()])
+ ])
+ ])
+ ])
+@@ -398,15 +403,19 @@ dnl # 3.7 API change,
+ dnl # The posix_acl_{from,to}_xattr functions gained a new
+ dnl # parameter: user_ns
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS], [
+- AC_MSG_CHECKING([whether posix_acl_from_xattr() needs user_ns])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_FROM_XATTR_USERNS], [
++ ZFS_LINUX_TEST_SRC([posix_acl_from_xattr_userns], [
+ #include <linux/cred.h>
+ #include <linux/fs.h>
+ #include <linux/posix_acl_xattr.h>
+ ],[
+ posix_acl_from_xattr(&init_user_ns, NULL, 0);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS], [
++ AC_MSG_CHECKING([whether posix_acl_from_xattr() needs user_ns])
++ ZFS_LINUX_TEST_RESULT([posix_acl_from_xattr_userns], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_POSIX_ACL_FROM_XATTR_USERNS, 1,
+ [posix_acl_from_xattr() needs user_ns])
+@@ -415,3 +424,50 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS], [
+ ])
+ ])
+
++dnl #
++dnl # 4.9 API change,
++dnl # iops->{set,get,remove}xattr and generic_{set,get,remove}xattr are
++dnl # removed. xattr operations will directly go through sb->s_xattr.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_SETXATTR], [
++ ZFS_LINUX_TEST_SRC([have_generic_setxattr], [
++ #include <linux/fs.h>
++ #include <linux/xattr.h>
++
++ static const struct inode_operations
++ iops __attribute__ ((unused)) = {
++ .setxattr = generic_setxattr
++ };
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_GENERIC_SETXATTR], [
++ AC_MSG_CHECKING([whether generic_setxattr() exists])
++ ZFS_LINUX_TEST_RESULT([have_generic_setxattr], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_GENERIC_SETXATTR, 1,
++ [generic_setxattr() exists])
++ ],[
++ AC_MSG_RESULT(no)
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR], [
++ ZFS_AC_KERNEL_SRC_CONST_XATTR_HANDLER
++ ZFS_AC_KERNEL_SRC_XATTR_HANDLER_NAME
++ ZFS_AC_KERNEL_SRC_XATTR_HANDLER_GET
++ ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET
++ ZFS_AC_KERNEL_SRC_XATTR_HANDLER_LIST
++ ZFS_AC_KERNEL_SRC_POSIX_ACL_FROM_XATTR_USERNS
++ ZFS_AC_KERNEL_SRC_GENERIC_SETXATTR
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_XATTR], [
++ ZFS_AC_KERNEL_CONST_XATTR_HANDLER
++ ZFS_AC_KERNEL_XATTR_HANDLER_NAME
++ ZFS_AC_KERNEL_XATTR_HANDLER_GET
++ ZFS_AC_KERNEL_XATTR_HANDLER_SET
++ ZFS_AC_KERNEL_XATTR_HANDLER_LIST
++ ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS
++ ZFS_AC_KERNEL_GENERIC_SETXATTR
++])
+diff --git a/config/kernel-zlib.m4 b/config/kernel-zlib.m4
+index 3ca7cf682..d554d1168 100644
+--- a/config/kernel-zlib.m4
++++ b/config/kernel-zlib.m4
+@@ -1,62 +1,25 @@
+-dnl #
+-dnl # zlib inflate compat,
+-dnl # Verify the kernel has CONFIG_ZLIB_INFLATE support enabled.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE], [
+- AC_MSG_CHECKING([whether CONFIG_ZLIB_INFLATE is defined])
+- ZFS_LINUX_TRY_COMPILE([
+- #if !defined(CONFIG_ZLIB_INFLATE) && \
+- !defined(CONFIG_ZLIB_INFLATE_MODULE)
+- #error CONFIG_ZLIB_INFLATE not defined
+- #endif
+- ],[ ],[
+- AC_MSG_RESULT([yes])
+- ],[
+- AC_MSG_RESULT([no])
+- AC_MSG_ERROR([
+- *** This kernel does not include the required zlib inflate support.
+- *** Rebuild the kernel with CONFIG_ZLIB_INFLATE=y|m set.])
+- ])
+-])
+-
+-dnl #
+-dnl # zlib deflate compat,
+-dnl # Verify the kernel has CONFIG_ZLIB_DEFLATE support enabled.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE], [
+- AC_MSG_CHECKING([whether CONFIG_ZLIB_DEFLATE is defined])
+- ZFS_LINUX_TRY_COMPILE([
+- #if !defined(CONFIG_ZLIB_DEFLATE) && \
+- !defined(CONFIG_ZLIB_DEFLATE_MODULE)
+- #error CONFIG_ZLIB_DEFLATE not defined
+- #endif
+- ],[ ],[
+- AC_MSG_RESULT([yes])
+- ],[
+- AC_MSG_RESULT([no])
+- AC_MSG_ERROR([
+- *** This kernel does not include the required zlib deflate support.
+- *** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set.])
+- ])
+-])
+-
+ dnl #
+ dnl # 2.6.39 API compat,
++dnl
+ dnl # The function zlib_deflate_workspacesize() now take 2 arguments.
+ dnl # This was done to avoid always having to allocate the maximum size
+ dnl # workspace (268K). The caller can now specific the windowBits and
+ dnl # memLevel compression parameters to get a smaller workspace.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE],
+- [AC_MSG_CHECKING([whether zlib_deflate_workspacesize() wants 2 args])
+- ZFS_LINUX_TRY_COMPILE([
++AC_DEFUN([ZFS_AC_KERNEL_SRC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE], [
++ ZFS_LINUX_TEST_SRC([2args_zlib_deflate_workspacesize], [
+ #include <linux/zlib.h>
+ ],[
+ return zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL);
+- ],[
++ ])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE], [
++ AC_MSG_CHECKING([whether zlib_deflate_workspacesize() wants 2 args])
++ ZFS_LINUX_TEST_RESULT([2args_zlib_deflate_workspacesize], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE, 1,
+- [zlib_deflate_workspacesize() wants 2 args])
++ [zlib_deflate_workspacesize() wants 2 args])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+diff --git a/config/kernel.m4 b/config/kernel.m4
+index 8e89c8014..b22a00cdd 100644
+--- a/config/kernel.m4
++++ b/config/kernel.m4
+@@ -2,111 +2,217 @@ dnl #
+ dnl # Default ZFS kernel configuration
+ dnl #
+ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
++ dnl # Setup the kernel build environment.
+ ZFS_AC_KERNEL
+ ZFS_AC_QAT
+- ZFS_AC_KERNEL_ACCESS_OK_TYPE
+- ZFS_AC_TEST_MODULE
++
++ dnl # Sanity checks for module building and CONFIG_* defines
++ ZFS_AC_KERNEL_TEST_MODULE
++ ZFS_AC_KERNEL_CONFIG_DEFINED
++
++ dnl # Sequential ZFS_LINUX_TRY_COMPILE tests
++ ZFS_AC_KERNEL_FPU_HEADER
++ ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T
+ ZFS_AC_KERNEL_MISC_MINOR
++ ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
++
++ dnl # Parallel ZFS_LINUX_TEST_SRC / ZFS_LINUX_TEST_RESULT tests
++ ZFS_AC_KERNEL_TEST_SRC
++ ZFS_AC_KERNEL_TEST_RESULT
++
++ AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
++ KERNEL_MAKE="$KERNEL_MAKE O=$LINUX_OBJ"
++ ])
++
++ AC_SUBST(KERNEL_MAKE)
++])
++
++dnl #
++dnl # Generate and compile all of the kernel API test cases to determine
++dnl # which interfaces are available. By invoking the kernel build system
++dnl # only once the compilation can be done in parallel significantly
++dnl # speeding up the process.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
++ ZFS_AC_KERNEL_SRC_OBJTOOL
++ ZFS_AC_KERNEL_SRC_GLOBAL_PAGE_STATE
++ ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE
++ ZFS_AC_KERNEL_SRC_CTL_NAME
++ ZFS_AC_KERNEL_SRC_PDE_DATA
++ ZFS_AC_KERNEL_SRC_FALLOCATE
++ ZFS_AC_KERNEL_SRC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
++ ZFS_AC_KERNEL_SRC_RWSEM
++ ZFS_AC_KERNEL_SRC_SCHED
++ ZFS_AC_KERNEL_SRC_USLEEP_RANGE
++ ZFS_AC_KERNEL_SRC_KMEM_CACHE
++ ZFS_AC_KERNEL_SRC_WAIT
++ ZFS_AC_KERNEL_SRC_INODE_TIMES
++ ZFS_AC_KERNEL_SRC_INODE_LOCK
++ ZFS_AC_KERNEL_SRC_GROUP_INFO_GID
++ ZFS_AC_KERNEL_SRC_RW
++ ZFS_AC_KERNEL_SRC_TIMER_SETUP
++ ZFS_AC_KERNEL_SRC_CURRENT_BIO_TAIL
++ ZFS_AC_KERNEL_SRC_SUPER_USER_NS
++ ZFS_AC_KERNEL_SRC_SUBMIT_BIO
++ ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS
++ ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
++ ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART
++ ZFS_AC_KERNEL_SRC_INVALIDATE_BDEV
++ ZFS_AC_KERNEL_SRC_LOOKUP_BDEV
++ ZFS_AC_KERNEL_SRC_BDEV_OPEN_EXCLUSIVE
++ ZFS_AC_KERNEL_SRC_BDEV_LOGICAL_BLOCK_SIZE
++ ZFS_AC_KERNEL_SRC_BDEV_PHYSICAL_BLOCK_SIZE
++ ZFS_AC_KERNEL_SRC_BIO_BVEC_ITER
++ ZFS_AC_KERNEL_SRC_BIO_FAILFAST
++ ZFS_AC_KERNEL_SRC_BIO_SET_DEV
++ ZFS_AC_KERNEL_SRC_BIO_OPS
++ ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS
++ ZFS_AC_KERNEL_SRC_BIO_BI_STATUS
++ ZFS_AC_KERNEL_SRC_BIO_RW_BARRIER
++ ZFS_AC_KERNEL_SRC_BIO_RW_DISCARD
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAGS
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLUSH
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_HW_SECTORS
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_SEGMENTS
++ ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG
++ ZFS_AC_KERNEL_SRC_GET_DISK_AND_MODULE
++ ZFS_AC_KERNEL_SRC_GET_DISK_RO
++ ZFS_AC_KERNEL_SRC_GENERIC_READLINK_GLOBAL
++ ZFS_AC_KERNEL_SRC_DISCARD_GRANULARITY
++ ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE
++ ZFS_AC_KERNEL_SRC_XATTR
++ ZFS_AC_KERNEL_SRC_ACL
++ ZFS_AC_KERNEL_SRC_INODE_GETATTR
++ ZFS_AC_KERNEL_SRC_INODE_SET_FLAGS
++ ZFS_AC_KERNEL_SRC_INODE_SET_IVERSION
++ ZFS_AC_KERNEL_SRC_SHOW_OPTIONS
++ ZFS_AC_KERNEL_SRC_FILE_INODE
++ ZFS_AC_KERNEL_SRC_FILE_DENTRY
++ ZFS_AC_KERNEL_SRC_FSYNC
++ ZFS_AC_KERNEL_SRC_AIO_FSYNC
++ ZFS_AC_KERNEL_SRC_EVICT_INODE
++ ZFS_AC_KERNEL_SRC_DIRTY_INODE
++ ZFS_AC_KERNEL_SRC_SHRINKER
++ ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T
++ ZFS_AC_KERNEL_SRC_LOOKUP_NAMEIDATA
++ ZFS_AC_KERNEL_SRC_CREATE_NAMEIDATA
++ ZFS_AC_KERNEL_SRC_GET_LINK
++ ZFS_AC_KERNEL_SRC_PUT_LINK
++ ZFS_AC_KERNEL_SRC_TMPFILE
++ ZFS_AC_KERNEL_SRC_TRUNCATE_RANGE
++ ZFS_AC_KERNEL_SRC_AUTOMOUNT
++ ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE
++ ZFS_AC_KERNEL_SRC_COMMIT_METADATA
++ ZFS_AC_KERNEL_SRC_CLEAR_INODE
++ ZFS_AC_KERNEL_SRC_SETATTR_PREPARE
++ ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED
++ ZFS_AC_KERNEL_SRC_DENTRY
++ ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE
++ ZFS_AC_KERNEL_SRC_SECURITY_INODE
++ ZFS_AC_KERNEL_SRC_FST_MOUNT
++ ZFS_AC_KERNEL_SRC_BDI
++ ZFS_AC_KERNEL_SRC_SET_NLINK
++ ZFS_AC_KERNEL_SRC_ELEVATOR_CHANGE
++ ZFS_AC_KERNEL_SRC_SGET
++ ZFS_AC_KERNEL_SRC_LSEEK_EXECUTE
++ ZFS_AC_KERNEL_SRC_VFS_GETATTR
++ ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS
++ ZFS_AC_KERNEL_SRC_VFS_ITERATE
++ ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO
++ ZFS_AC_KERNEL_SRC_VFS_RW_ITERATE
++ ZFS_AC_KERNEL_SRC_VFS_GENERIC_WRITE_CHECKS
++ ZFS_AC_KERNEL_SRC_KMAP_ATOMIC_ARGS
++ ZFS_AC_KERNEL_SRC_FOLLOW_DOWN_ONE
++ ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN
++ ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT
++ ZFS_AC_KERNEL_SRC_FPU
++ ZFS_AC_KERNEL_SRC_FMODE_T
++ ZFS_AC_KERNEL_SRC_KUIDGID_T
++ ZFS_AC_KERNEL_SRC_KUID_HELPERS
++ ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST
++ ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS
++ ZFS_AC_KERNEL_SRC_CURRENT_TIME
++ ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
++ ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL
++ ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64
++ ZFS_AC_KERNEL_SRC_TOTALRAM_PAGES_FUNC
++ ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES
++ ZFS_AC_KERNEL_SRC_KSTRTOUL
++
++ AC_MSG_CHECKING([for available kernel interfaces])
++ ZFS_LINUX_TEST_COMPILE_ALL([kabi])
++ AC_MSG_RESULT([done])
++])
++
++dnl #
++dnl # Check results of kernel interface tests.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
++ ZFS_AC_KERNEL_ACCESS_OK_TYPE
++ ZFS_AC_KERNEL_GLOBAL_PAGE_STATE
+ ZFS_AC_KERNEL_OBJTOOL
+- ZFS_AC_KERNEL_CONFIG
+ ZFS_AC_KERNEL_CTL_NAME
+ ZFS_AC_KERNEL_PDE_DATA
+- ZFS_AC_KERNEL_2ARGS_VFS_FSYNC
+- ZFS_AC_KERNEL_KUIDGID_T
+ ZFS_AC_KERNEL_FALLOCATE
+ ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
+- ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW
+- ZFS_AC_KERNEL_RWSEM_ACTIVITY
+- ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT
+- ZFS_AC_KERNEL_SCHED_RT_HEADER
+- ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER
+- ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT
+- ZFS_AC_KERNEL_4ARGS_VFS_GETATTR
+- ZFS_AC_KERNEL_3ARGS_VFS_GETATTR
+- ZFS_AC_KERNEL_2ARGS_VFS_GETATTR
++ ZFS_AC_KERNEL_RWSEM
++ ZFS_AC_KERNEL_SCHED
+ ZFS_AC_KERNEL_USLEEP_RANGE
+- ZFS_AC_KERNEL_KMEM_CACHE_ALLOCFLAGS
+- ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY
+- ZFS_AC_KERNEL_WAIT_ON_BIT
+- ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T
+- ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY
++ ZFS_AC_KERNEL_KMEM_CACHE
++ ZFS_AC_KERNEL_WAIT
+ ZFS_AC_KERNEL_INODE_TIMES
+ ZFS_AC_KERNEL_INODE_LOCK
+ ZFS_AC_KERNEL_GROUP_INFO_GID
+- ZFS_AC_KERNEL_WRITE
+- ZFS_AC_KERNEL_READ
++ ZFS_AC_KERNEL_RW
+ ZFS_AC_KERNEL_TIMER_SETUP
+- ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
+ ZFS_AC_KERNEL_CURRENT_BIO_TAIL
+ ZFS_AC_KERNEL_SUPER_USER_NS
+ ZFS_AC_KERNEL_SUBMIT_BIO
+- ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
+- ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
+- ZFS_AC_KERNEL_TYPE_FMODE_T
++ ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS
+ ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH
+ ZFS_AC_KERNEL_BLKDEV_REREAD_PART
+- ZFS_AC_KERNEL_OPEN_BDEV_EXCLUSIVE
++ ZFS_AC_KERNEL_INVALIDATE_BDEV
+ ZFS_AC_KERNEL_LOOKUP_BDEV
+- ZFS_AC_KERNEL_INVALIDATE_BDEV_ARGS
++ ZFS_AC_KERNEL_BDEV_OPEN_EXCLUSIVE
+ ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE
+ ZFS_AC_KERNEL_BDEV_PHYSICAL_BLOCK_SIZE
+ ZFS_AC_KERNEL_BIO_BVEC_ITER
+- ZFS_AC_KERNEL_BIO_FAILFAST_DTD
++ ZFS_AC_KERNEL_BIO_FAILFAST
+ ZFS_AC_KERNEL_BIO_SET_DEV
+- ZFS_AC_KERNEL_REQ_FAILFAST_MASK
+- ZFS_AC_KERNEL_REQ_OP_DISCARD
+- ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE
+- ZFS_AC_KERNEL_REQ_OP_FLUSH
+- ZFS_AC_KERNEL_BIO_BI_OPF
++ ZFS_AC_KERNEL_BIO_OPS
+ ZFS_AC_KERNEL_BIO_END_IO_T_ARGS
+ ZFS_AC_KERNEL_BIO_BI_STATUS
+ ZFS_AC_KERNEL_BIO_RW_BARRIER
+ ZFS_AC_KERNEL_BIO_RW_DISCARD
+ ZFS_AC_KERNEL_BLK_QUEUE_BDI
+- ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR
+- ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET
++ ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
++ ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
++ ZFS_AC_KERNEL_BLK_QUEUE_FLAGS
+ ZFS_AC_KERNEL_BLK_QUEUE_FLUSH
+ ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS
+ ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS
+- ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG
+- ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BLK_PLUG
++ ZFS_AC_KERNEL_BLK_QUEUE_PLUG
+ ZFS_AC_KERNEL_GET_DISK_AND_MODULE
+ ZFS_AC_KERNEL_GET_DISK_RO
+- ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS
+ ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL
+ ZFS_AC_KERNEL_DISCARD_GRANULARITY
+- ZFS_AC_KERNEL_CONST_XATTR_HANDLER
+- ZFS_AC_KERNEL_XATTR_HANDLER_NAME
+- ZFS_AC_KERNEL_XATTR_HANDLER_GET
+- ZFS_AC_KERNEL_XATTR_HANDLER_SET
+- ZFS_AC_KERNEL_XATTR_HANDLER_LIST
+ ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE
+- ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS
+- ZFS_AC_KERNEL_POSIX_ACL_RELEASE
+- ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE
+- ZFS_AC_KERNEL_POSIX_ACL_CHMOD
+- ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
+- ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS
+- ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION
+- ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
+- ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
+- ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
+- ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
+- ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
+- ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR
++ ZFS_AC_KERNEL_XATTR
++ ZFS_AC_KERNEL_ACL
++ ZFS_AC_KERNEL_INODE_GETATTR
+ ZFS_AC_KERNEL_INODE_SET_FLAGS
+ ZFS_AC_KERNEL_INODE_SET_IVERSION
+- ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE
+ ZFS_AC_KERNEL_SHOW_OPTIONS
+ ZFS_AC_KERNEL_FILE_INODE
+ ZFS_AC_KERNEL_FILE_DENTRY
+ ZFS_AC_KERNEL_FSYNC
+- ZFS_AC_KERNEL_EVICT_INODE
+- ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS
+- ZFS_AC_KERNEL_NR_CACHED_OBJECTS
+- ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
+- ZFS_AC_KERNEL_FALLOCATE
+ ZFS_AC_KERNEL_AIO_FSYNC
++ ZFS_AC_KERNEL_EVICT_INODE
++ ZFS_AC_KERNEL_DIRTY_INODE
++ ZFS_AC_KERNEL_SHRINKER
+ ZFS_AC_KERNEL_MKDIR_UMODE_T
+ ZFS_AC_KERNEL_LOOKUP_NAMEIDATA
+ ZFS_AC_KERNEL_CREATE_NAMEIDATA
+@@ -120,58 +226,38 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
+ ZFS_AC_KERNEL_CLEAR_INODE
+ ZFS_AC_KERNEL_SETATTR_PREPARE
+ ZFS_AC_KERNEL_INSERT_INODE_LOCKED
+- ZFS_AC_KERNEL_D_MAKE_ROOT
+- ZFS_AC_KERNEL_D_OBTAIN_ALIAS
+- ZFS_AC_KERNEL_D_PRUNE_ALIASES
+- ZFS_AC_KERNEL_D_SET_D_OP
+- ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA
+- ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS
++ ZFS_AC_KERNEL_DENTRY
+ ZFS_AC_KERNEL_TRUNCATE_SETSIZE
+- ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY
+- ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY
++ ZFS_AC_KERNEL_SECURITY_INODE
+ ZFS_AC_KERNEL_FST_MOUNT
+- ZFS_AC_KERNEL_SHRINK
+- ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID
+- ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT
+- ZFS_AC_KERNEL_SHRINKER_CALLBACK
+- ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD
+- ZFS_AC_KERNEL_S_D_OP
+ ZFS_AC_KERNEL_BDI
+ ZFS_AC_KERNEL_SET_NLINK
+ ZFS_AC_KERNEL_ELEVATOR_CHANGE
+- ZFS_AC_KERNEL_5ARG_SGET
++ ZFS_AC_KERNEL_SGET
+ ZFS_AC_KERNEL_LSEEK_EXECUTE
++ ZFS_AC_KERNEL_VFS_GETATTR
++ ZFS_AC_KERNEL_VFS_FSYNC_2ARGS
+ ZFS_AC_KERNEL_VFS_ITERATE
+- ZFS_AC_KERNEL_VFS_RW_ITERATE
+ ZFS_AC_KERNEL_VFS_DIRECT_IO
+- ZFS_AC_KERNEL_GENERIC_WRITE_CHECKS
++ ZFS_AC_KERNEL_VFS_RW_ITERATE
++ ZFS_AC_KERNEL_VFS_GENERIC_WRITE_CHECKS
+ ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS
+ ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
+ ZFS_AC_KERNEL_MAKE_REQUEST_FN
+- ZFS_AC_KERNEL_GENERIC_IO_ACCT_3ARG
+- ZFS_AC_KERNEL_GENERIC_IO_ACCT_4ARG
++ ZFS_AC_KERNEL_GENERIC_IO_ACCT
+ ZFS_AC_KERNEL_FPU
++ ZFS_AC_KERNEL_FMODE_T
++ ZFS_AC_KERNEL_KUIDGID_T
+ ZFS_AC_KERNEL_KUID_HELPERS
+ ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST
+ ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
+- ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR
+ ZFS_AC_KERNEL_CURRENT_TIME
+- ZFS_AC_KERNEL_GLOBAL_PAGE_STATE
+- ZFS_AC_KERNEL_ACL_HAS_REFCOUNT
+ ZFS_AC_KERNEL_USERNS_CAPABILITIES
+ ZFS_AC_KERNEL_IN_COMPAT_SYSCALL
+ ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64
+ ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC
+ ZFS_AC_KERNEL_TOTALHIGH_PAGES
+- ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
+- ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
+ ZFS_AC_KERNEL_KSTRTOUL
+-
+- AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
+- KERNEL_MAKE="$KERNEL_MAKE O=$LINUX_OBJ"
+- ])
+-
+- AC_SUBST(KERNEL_MAKE)
+ ])
+
+ dnl #
+@@ -190,9 +276,10 @@ AC_DEFUN([ZFS_AC_MODULE_SYMVERS], [
+ AS_IF([test ! -f "$LINUX_OBJ/$LINUX_SYMBOLS"], [
+ AC_MSG_ERROR([
+ *** Please make sure the kernel devel package for your distribution
+- *** is installed. If you are building with a custom kernel, make sure the
+- *** kernel is configured, built, and the '--with-linux=PATH' configure
+- *** option refers to the location of the kernel source.])
++ *** is installed. If you are building with a custom kernel, make sure
++ *** the kernel is configured, built, and the '--with-linux=PATH'
++ *** configure option refers to the location of the kernel source.
++ ])
+ ])
+ ], [
+ LINUX_SYMBOLS=NONE
+@@ -285,12 +372,16 @@ AC_DEFUN([ZFS_AC_KERNEL], [
+
+ AS_IF([test -z "$kernsrcver"], [
+ AC_MSG_RESULT([Not found])
+- AC_MSG_ERROR([*** Cannot determine kernel version.])
++ AC_MSG_ERROR([
++ *** Cannot determine kernel version.
++ ])
+ ])
+ ], [
+ AC_MSG_RESULT([Not found])
+ if test "x$enable_linux_builtin" != xyes; then
+- AC_MSG_ERROR([*** Cannot find UTS_RELEASE definition.])
++ AC_MSG_ERROR([
++ *** Cannot find UTS_RELEASE definition.
++ ])
+ else
+ AC_MSG_ERROR([
+ *** Cannot find UTS_RELEASE definition.
+@@ -312,24 +403,27 @@ AC_DEFUN([ZFS_AC_KERNEL], [
+ ])
+
+ dnl #
+-dnl # Detect the QAT module to be built against
+-dnl # QAT provides hardware acceleration for data compression:
+-dnl # https://01.org/intel-quickassist-technology
+-dnl # * Download and install QAT driver from the above link
+-dnl # * Start QAT driver in your system:
+-dnl # service qat_service start
+-dnl # * Enable QAT in ZFS, e.g.:
+-dnl # ./configure --with-qat=<qat-driver-path>/QAT1.6
+-dnl # make
+-dnl # * Set GZIP compression in ZFS dataset:
+-dnl # zfs set compression = gzip <dataset>
+-dnl # Then the data written to this ZFS pool is compressed
+-dnl # by QAT accelerator automatically, and de-compressed by
+-dnl # QAT when read from the pool.
+-dnl # * Get QAT hardware statistics by:
+-dnl # cat /proc/icp_dh895xcc_dev/qat
+-dnl # * To disable QAT:
+-dnl # insmod zfs.ko zfs_qat_disable=1
++dnl # Detect the QAT module to be built against, QAT provides hardware
++dnl # acceleration for data compression:
++dnl #
++dnl # https://01.org/intel-quickassist-technology
++dnl #
++dnl # 1) Download and install QAT driver from the above link
++dnl # 2) Start QAT driver in your system:
++dnl # service qat_service start
++dnl # 3) Enable QAT in ZFS, e.g.:
++dnl # ./configure --with-qat=<qat-driver-path>/QAT1.6
++dnl # make
++dnl # 4) Set GZIP compression in ZFS dataset:
++dnl # zfs set compression = gzip <dataset>
++dnl #
++dnl # Then the data written to this ZFS pool is compressed by QAT accelerator
++dnl # automatically, and de-compressed by QAT when read from the pool.
++dnl #
++dnl # 1) Get QAT hardware statistics with:
++dnl # cat /proc/icp_dh895xcc_dev/qat
++dnl # 2) To disable QAT:
++dnl # insmod zfs.ko zfs_qat_disable=1
+ dnl #
+ AC_DEFUN([ZFS_AC_QAT], [
+ AC_ARG_WITH([qat],
+@@ -350,11 +444,11 @@ AC_DEFUN([ZFS_AC_QAT], [
+ QAT_SRC="${qatsrc}/quickassist"
+ AS_IF([ test ! -e "$QAT_SRC/include/cpa.h"], [
+ AC_MSG_ERROR([
+- *** Please make sure the qat driver package is installed
+- *** and specify the location of the qat source with the
+- *** '--with-qat=PATH' option then try again. Failed to
+- *** find cpa.h in:
+- ${QAT_SRC}/include])
++ *** Please make sure the qat driver package is installed
++ *** and specify the location of the qat source with the
++ *** '--with-qat=PATH' option then try again. Failed to
++ *** find cpa.h in:
++ ${QAT_SRC}/include])
+ ])
+ ])
+
+@@ -368,9 +462,9 @@ AC_DEFUN([ZFS_AC_QAT], [
+ QAT_OBJ=${qatbuild}
+ AS_IF([ ! test -e "$QAT_OBJ/icp_qa_al.ko" && ! test -e "$QAT_OBJ/qat_api.ko"], [
+ AC_MSG_ERROR([
+- *** Please make sure the qat driver is installed then try again.
+- *** Failed to find icp_qa_al.ko or qat_api.ko in:
+- $QAT_OBJ])
++ *** Please make sure the qat driver is installed then try again.
++ *** Failed to find icp_qa_al.ko or qat_api.ko in:
++ $QAT_OBJ])
+ ])
+
+ AC_SUBST(QAT_SRC)
+@@ -391,10 +485,10 @@ AC_DEFUN([ZFS_AC_QAT], [
+ AC_MSG_RESULT([$QAT_SYMBOLS])
+ AC_SUBST(QAT_SYMBOLS)
+ ],[
+- AC_MSG_ERROR([
+- *** Please make sure the qat driver is installed then try again.
+- *** Failed to find Module.symvers in:
+- $QAT_SYMBOLS])
++ AC_MSG_ERROR([
++ *** Please make sure the qat driver is installed then try again.
++ *** Failed to find Module.symvers in:
++ $QAT_SYMBOLS
+ ])
+ ])
+ ])
+@@ -403,14 +497,16 @@ AC_DEFUN([ZFS_AC_QAT], [
+ dnl #
+ dnl # Basic toolchain sanity check.
+ dnl #
+-AC_DEFUN([ZFS_AC_TEST_MODULE], [
++AC_DEFUN([ZFS_AC_KERNEL_TEST_MODULE], [
+ AC_MSG_CHECKING([whether modules can be built])
+- ZFS_LINUX_TRY_COMPILE([],[],[
++ ZFS_LINUX_TRY_COMPILE([], [], [
+ AC_MSG_RESULT([yes])
+ ],[
+ AC_MSG_RESULT([no])
+ if test "x$enable_linux_builtin" != xyes; then
+- AC_MSG_ERROR([*** Unable to build an empty module.])
++ AC_MSG_ERROR([
++ *** Unable to build an empty module.
++ ])
+ else
+ AC_MSG_ERROR([
+ *** Unable to build an empty module.
+@@ -420,207 +516,313 @@ AC_DEFUN([ZFS_AC_TEST_MODULE], [
+ ])
+
+ dnl #
+-dnl # Certain kernel build options are not supported. These must be
+-dnl # detected at configure time and cause a build failure. Otherwise
+-dnl # modules may be successfully built that behave incorrectly.
++dnl # ZFS_LINUX_CONFTEST_H
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CONFIG], [
+- AS_IF([test "x$cross_compiling" != xyes], [
+- AC_RUN_IFELSE([
+- AC_LANG_PROGRAM([
+- #include "$LINUX/include/linux/license.h"
+- ], [
+- return !license_is_gpl_compatible("$ZFS_META_LICENSE");
+- ])
+- ], [
+- AC_DEFINE([ZFS_IS_GPL_COMPATIBLE], [1],
+- [Define to 1 if GPL-only symbols can be used])
+- ], [
+- ])
+- ])
++AC_DEFUN([ZFS_LINUX_CONFTEST_H], [
++test -d build/$2 || mkdir -p build/$2
++cat - <<_ACEOF >build/$2/$2.h
++$1
++_ACEOF
++])
+
+- ZFS_AC_KERNEL_CONFIG_THREAD_SIZE
+- ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC
+- ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS
+- ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE
+- ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE
++dnl #
++dnl # ZFS_LINUX_CONFTEST_C
++dnl #
++AC_DEFUN([ZFS_LINUX_CONFTEST_C], [
++test -d build/$2 || mkdir -p build/$2
++cat confdefs.h - <<_ACEOF >build/$2/$2.c
++$1
++_ACEOF
+ ])
+
+ dnl #
+-dnl # Check configured THREAD_SIZE
++dnl # ZFS_LINUX_CONFTEST_MAKEFILE
+ dnl #
+-dnl # The stack size will vary by architecture, but as of Linux 3.15 on x86_64
+-dnl # the default thread stack size was increased to 16K from 8K. Therefore,
+-dnl # on newer kernels and some architectures stack usage optimizations can be
+-dnl # conditionally applied to improve performance without negatively impacting
+-dnl # stability.
++dnl # $1 - test case name
++dnl # $2 - add to top-level Makefile
++dnl # $3 - additional build flags
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CONFIG_THREAD_SIZE], [
+- AC_MSG_CHECKING([whether kernel was built with 16K or larger stacks])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
+- ],[
+- #if (THREAD_SIZE < 16384)
+- #error "THREAD_SIZE is less than 16K"
+- #endif
+- ],[
+- AC_MSG_RESULT([yes])
+- AC_DEFINE(HAVE_LARGE_STACKS, 1, [kernel has large stacks])
+- ],[
+- AC_MSG_RESULT([no])
+- ])
++AC_DEFUN([ZFS_LINUX_CONFTEST_MAKEFILE], [
++ test -d build || mkdir -p build
++ test -d build/$1 || mkdir -p build/$1
++
++ file=build/$1/Makefile
++
++ dnl # Example command line to manually build source.
++ cat - <<_ACEOF >$file
++# Example command line to manually build source
++# make modules -C $LINUX_OBJ $ARCH_UM M=$PWD/build/$1
++
++ccflags-y := -Werror $FRAME_LARGER_THAN
++_ACEOF
++
++ dnl # Additional custom CFLAGS as requested.
++ m4_ifval($3, [echo "ccflags-y += $3" >>$file], [])
++
++ dnl # Test case source
++ echo "obj-m := $1.o" >>$file
++
++ AS_IF([test "x$2" = "xyes"], [echo "obj-m += $1/" >>build/Makefile], [])
+ ])
+
+ dnl #
+-dnl # Check CONFIG_DEBUG_LOCK_ALLOC
++dnl # ZFS_LINUX_TEST_PROGRAM(C)([PROLOGUE], [BODY])
+ dnl #
+-dnl # This is typically only set for debug kernels because it comes with
+-dnl # a performance penalty. However, when it is set it maps the non-GPL
+-dnl # symbol mutex_lock() to the GPL-only mutex_lock_nested() symbol.
+-dnl # This will cause a failure at link time which we'd rather know about
+-dnl # at compile time.
++m4_define([ZFS_LINUX_TEST_PROGRAM], [
++$1
++int
++main (void)
++{
++$2
++ ;
++ return 0;
++}
++])
++
+ dnl #
+-dnl # Since we plan to pursue making mutex_lock_nested() a non-GPL symbol
+-dnl # with the upstream community we add a check to detect this case.
++dnl # ZFS_LINUX_TEST_REMOVE
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [
+-
+- ZFS_LINUX_CONFIG([DEBUG_LOCK_ALLOC], [
+- AC_MSG_CHECKING([whether mutex_lock() is GPL-only])
+- tmp_flags="$EXTRA_KCFLAGS"
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
+- #include <linux/mutex.h>
+-
+- MODULE_LICENSE("$ZFS_META_LICENSE");
+- ],[
+- struct mutex lock;
++dnl # Removes the specified test source and results.
++dnl #
++AC_DEFUN([ZFS_LINUX_TEST_REMOVE], [
++ test -d build/$1 && rm -Rf build/$1
++ test -f build/Makefile && sed '/$1/d' build/Makefile
++])
+
+- mutex_init(&lock);
+- mutex_lock(&lock);
+- mutex_unlock(&lock);
+- ],[
+- AC_MSG_RESULT(no)
+- ],[
+- AC_MSG_RESULT(yes)
+- AC_MSG_ERROR([
+- *** Kernel built with CONFIG_DEBUG_LOCK_ALLOC which is incompatible
+- *** with the CDDL license and will prevent the module linking stage
+- *** from succeeding. You must rebuild your kernel without this
+- *** option enabled.])
+- ])
+- EXTRA_KCFLAGS="$tmp_flags"
+- ], [])
++dnl #
++dnl # ZFS_LINUX_COMPILE
++dnl #
++dnl # $1 - build dir
++dnl # $2 - test command
++dnl # $3 - pass command
++dnl # $4 - fail command
++dnl # $5 - set KBUILD_MODPOST_NOFINAL='yes'
++dnl # $6 - set KBUILD_MODPOST_WARN='yes'
++dnl #
++dnl # Used internally by ZFS_LINUX_TEST_{COMPILE,MODPOST}
++dnl #
++AC_DEFUN([ZFS_LINUX_COMPILE], [
++ AC_TRY_COMMAND([
++ KBUILD_MODPOST_NOFINAL="$5" KBUILD_MODPOST_WARN="$6"
++ make modules -k -j$TEST_JOBS -C $LINUX_OBJ $ARCH_UM
++ M=$PWD/$1 &>$1/build.log])
++ AS_IF([AC_TRY_COMMAND([$2])], [$3], [$4])
+ ])
+
+ dnl #
+-dnl # Check CONFIG_TRIM_UNUSED_KSYMS
++dnl # ZFS_LINUX_TEST_COMPILE
+ dnl #
+-dnl # Verify the kernel has CONFIG_TRIM_UNUSED_KSYMS disabled.
++dnl # Perform a full compile excluding the final modpost phase.
+ dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS], [
+- AC_MSG_CHECKING([whether CONFIG_TRIM_UNUSED_KSYM is disabled])
+- ZFS_LINUX_TRY_COMPILE([
+- #if defined(CONFIG_TRIM_UNUSED_KSYMS)
+- #error CONFIG_TRIM_UNUSED_KSYMS not defined
+- #endif
+- ],[ ],[
+- AC_MSG_RESULT([yes])
++AC_DEFUN([ZFS_LINUX_TEST_COMPILE], [
++ ZFS_LINUX_COMPILE([$2], [test -f $2/build.log], [
++ mv $2/Makefile $2/Makefile.compile.$1
++ mv $2/build.log $2/build.log.$1
+ ],[
+- AC_MSG_RESULT([no])
+- AS_IF([test "x$enable_linux_builtin" != xyes], [
+- AC_MSG_ERROR([
+- *** This kernel has unused symbols trimming enabled, please disable.
+- *** Rebuild the kernel with CONFIG_TRIM_UNUSED_KSYMS=n set.])
+- ])])
++ AC_MSG_ERROR([
++ *** Unable to compile test source to determine kernel interfaces.])
++ ], [yes], [])
+ ])
+
+ dnl #
+-dnl # ZFS_LINUX_CONFTEST_H
++dnl # ZFS_LINUX_TEST_MODPOST
+ dnl #
+-AC_DEFUN([ZFS_LINUX_CONFTEST_H], [
+-cat - <<_ACEOF >conftest.h
+-$1
+-_ACEOF
++dnl # Perform a full compile including the modpost phase. This may
++dnl # be an incremental build if the objects have already been built.
++dnl #
++AC_DEFUN([ZFS_LINUX_TEST_MODPOST], [
++ ZFS_LINUX_COMPILE([$2], [test -f $2/build.log], [
++ mv $2/Makefile $2/Makefile.modpost.$1
++ cat $2/build.log >>build/build.log.$1
++ ],[
++ AC_MSG_ERROR([
++ *** Unable to modpost test source to determine kernel interfaces.])
++ ], [], [yes])
+ ])
+
+ dnl #
+-dnl # ZFS_LINUX_CONFTEST_C
++dnl # Perform the compilation of the test cases in two phases.
+ dnl #
+-AC_DEFUN([ZFS_LINUX_CONFTEST_C], [
+-cat confdefs.h - <<_ACEOF >conftest.c
+-$1
+-_ACEOF
++dnl # Phase 1) attempt to build the object files for all of the tests
++dnl # defined by the ZFS_LINUX_TEST_SRC macro. But do not
++dnl # perform the final modpost stage.
++dnl #
++dnl # Phase 2) disable all tests which failed the initial compilation,
++dnl # then invoke the final modpost step for the remaining tests.
++dnl #
++dnl # This allows us efficiently build the test cases in parallel while
++dnl # remaining resilient to build failures which are expected when
++dnl # detecting the available kernel interfaces.
++dnl #
++dnl # The maximum allowed parallelism can be controlled by setting the
++dnl # TEST_JOBS environment variable. Otherwise, it default to $(nproc).
++dnl #
++AC_DEFUN([ZFS_LINUX_TEST_COMPILE_ALL], [
++ dnl # Phase 1 - Compilation only, final linking is skipped.
++ ZFS_LINUX_TEST_COMPILE([$1], [build])
++
++ dnl #
++ dnl # Phase 2 - When building external modules disable test cases
++ dnl # which failed to compile and invoke modpost to verify the
++ dnl # final linking.
++ dnl #
++ dnl # Test names suffixed with '_license' call modpost independently
++ dnl # to ensure that a single incompatibility does not result in the
++ dnl # modpost phase exiting early. This check is not performed on
++ dnl # every symbol since the majority are compatible and doing so
++ dnl # would significantly slow down this phase.
++ dnl #
++ dnl # When configuring for builtin (--enable-linux-builtin)
++ dnl # fake the linking step artificially create the expected .ko
++ dnl # files for tests which did compile. This is required for
++ dnl # kernels which do not have loadable module support or have
++ dnl # not yet been built.
++ dnl #
++ AS_IF([test "x$enable_linux_builtin" = "xno"], [
++ for dir in $(awk '/^obj-m/ { print [$]3 }' \
++ build/Makefile.compile.$1); do
++ name=${dir%/}
++ AS_IF([test -f build/$name/$name.o], [
++ AS_IF([test "${name##*_}" = "license"], [
++ ZFS_LINUX_TEST_MODPOST([$1],
++ [build/$name])
++ echo "obj-n += $dir" >>build/Makefile
++ ], [
++ echo "obj-m += $dir" >>build/Makefile
++ ])
++ ], [
++ echo "obj-n += $dir" >>build/Makefile
++ ])
++ done
++
++ ZFS_LINUX_TEST_MODPOST([$1], [build])
++ ], [
++ for dir in $(awk '/^obj-m/ { print [$]3 }' \
++ build/Makefile.compile.$1); do
++ name=${dir%/}
++ AS_IF([test -f build/$name/$name.o], [
++ touch build/$name/$name.ko
++ ])
++ done
++ ])
+ ])
+
+ dnl #
+-dnl # ZFS_LANG_PROGRAM(C)([PROLOGUE], [BODY])
++dnl # ZFS_LINUX_TEST_SRC
+ dnl #
+-m4_define([ZFS_LANG_PROGRAM], [
+-$1
+-int
+-main (void)
+-{
+-dnl Do *not* indent the following line: there may be CPP directives.
+-dnl Don't move the `;' right after for the same reason.
+-$2
+- ;
+- return 0;
+-}
++dnl # $1 - name
++dnl # $2 - global
++dnl # $3 - source
++dnl # $4 - extra cflags
++dnl # $5 - check license-compatibility
++dnl #
++dnl # N.B because all of the test cases are compiled in parallel they
++dnl # must never depend on the results of previous tests. Each test
++dnl # needs to be entirely independent.
++dnl #
++AC_DEFUN([ZFS_LINUX_TEST_SRC], [
++ ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM([[$2]], [[$3]])], [$1])
++ ZFS_LINUX_CONFTEST_MAKEFILE([$1], [yes], [$4])
++
++ AS_IF([ test -n "$5" ], [
++ ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM([[
++ #include <linux/module.h>
++ MODULE_LICENSE("$5");
++ $2]], [[$3]])], [$1_license])
++ ZFS_LINUX_CONFTEST_MAKEFILE([$1_license], [yes], [$4])
++ ])
+ ])
+
+ dnl #
+-dnl # ZFS_LINUX_COMPILE_IFELSE / like AC_COMPILE_IFELSE
++dnl # ZFS_LINUX_TEST_RESULT
+ dnl #
+-AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [
+- m4_ifvaln([$1], [ZFS_LINUX_CONFTEST_C([$1])])
+- m4_ifvaln([$6], [ZFS_LINUX_CONFTEST_H([$6])], [ZFS_LINUX_CONFTEST_H([])])
+- rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+- echo "obj-m := conftest.o" >build/Makefile
+- modpost_flag=''
+- test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+- AS_IF(
+- [AC_TRY_COMMAND(cp conftest.c conftest.h build && make [$2] -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $FRAME_LARGER_THAN $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag) >/dev/null && AC_TRY_COMMAND([$3])],
+- [$4],
+- [_AC_MSG_LOG_CONFTEST m4_ifvaln([$5],[$5])]
+- )
+- rm -Rf build
++dnl # $1 - name of a test source (ZFS_LINUX_TEST_SRC)
++dnl # $2 - run on success (valid .ko generated)
++dnl # $3 - run on failure (unable to compile)
++dnl #
++AC_DEFUN([ZFS_LINUX_TEST_RESULT], [
++ AS_IF([test -d build/$1], [
++ AS_IF([test -f build/$1/$1.ko], [$2], [$3])
++ ], [
++ AC_MSG_ERROR([
++ *** No matching source for the "$1" test, check that
++ *** both the test source and result macros refer to the same name.
++ ])
++ ])
+ ])
+
+ dnl #
+-dnl # ZFS_LINUX_TRY_COMPILE like AC_TRY_COMPILE
++dnl # ZFS_LINUX_TEST_ERROR
+ dnl #
+-AC_DEFUN([ZFS_LINUX_TRY_COMPILE],
+- [ZFS_LINUX_COMPILE_IFELSE(
+- [AC_LANG_SOURCE([ZFS_LANG_PROGRAM([[$1]], [[$2]])])],
+- [modules],
+- [test -s build/conftest.o],
+- [$3], [$4])
++dnl # Generic error message which can be used when none of the expected
++dnl # kernel interfaces were detected.
++dnl #
++AC_DEFUN([ZFS_LINUX_TEST_ERROR], [
++ AC_MSG_ERROR([
++ *** None of the expected "$1" interfaces were detected.
++ *** This may be because your kernel version is newer than what is
++ *** supported, or you are using a patched custom kernel with
++ *** incompatible modifications.
++ ***
++ *** ZFS Version: $ZFS_META_ALIAS
++ *** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
++ ])
+ ])
+
+ dnl #
+-dnl # ZFS_LINUX_CONFIG
++dnl # ZFS_LINUX_TEST_RESULT_SYMBOL
+ dnl #
+-AC_DEFUN([ZFS_LINUX_CONFIG],
+- [AC_MSG_CHECKING([whether kernel was built with CONFIG_$1])
+- ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
+- ],[
+- #ifndef CONFIG_$1
+- #error CONFIG_$1 not #defined
+- #endif
+- ],[
+- AC_MSG_RESULT([yes])
+- $2
+- ],[
+- AC_MSG_RESULT([no])
+- $3
++dnl # Like ZFS_LINUX_TEST_RESULT except ZFS_CHECK_SYMBOL_EXPORT is called to
++dnl # verify symbol exports, unless --enable-linux-builtin was provided to
++dnl # configure.
++dnl #
++AC_DEFUN([ZFS_LINUX_TEST_RESULT_SYMBOL], [
++ AS_IF([ ! test -f build/$1/$1.ko], [
++ $5
++ ], [
++ AS_IF([test "x$enable_linux_builtin" != "xyes"], [
++ ZFS_CHECK_SYMBOL_EXPORT([$2], [$3], [$4], [$5])
++ ], [
++ $4
++ ])
+ ])
+ ])
+
++dnl #
++dnl # ZFS_LINUX_COMPILE_IFELSE
++dnl #
++AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [
++ ZFS_LINUX_TEST_REMOVE([conftest])
++
++ m4_ifvaln([$1], [ZFS_LINUX_CONFTEST_C([$1], [conftest])])
++ m4_ifvaln([$5], [ZFS_LINUX_CONFTEST_H([$5], [conftest])],
++ [ZFS_LINUX_CONFTEST_H([], [conftest])])
++
++ ZFS_LINUX_CONFTEST_MAKEFILE([conftest], [no],
++ [m4_ifvaln([$5], [-I$PWD/build/conftest], [])])
++ ZFS_LINUX_COMPILE([build/conftest], [$2], [$3], [$4], [], [])
++])
++
++dnl #
++dnl # ZFS_LINUX_TRY_COMPILE
++dnl #
++dnl # $1 - global
++dnl # $2 - source
++dnl # $3 - run on success (valid .ko generated)
++dnl # $4 - run on failure (unable to compile)
++dnl #
++AC_DEFUN([ZFS_LINUX_TRY_COMPILE], [
++ ZFS_LINUX_COMPILE_IFELSE(
++ [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]])],
++ [test -f build/conftest/conftest.ko],
++ [$3], [$4])
++])
++
+ dnl #
+ dnl # ZFS_CHECK_SYMBOL_EXPORT
+-dnl # check symbol exported or not
++dnl #
++dnl # Check if a symbol is exported on not by consulting the symbols
++dnl # file, or optionally the source code.
+ dnl #
+ AC_DEFUN([ZFS_CHECK_SYMBOL_EXPORT], [
+ grep -q -E '[[[:space:]]]$1[[[:space:]]]' \
+@@ -649,8 +851,10 @@ AC_DEFUN([ZFS_CHECK_SYMBOL_EXPORT], [
+
+ dnl #
+ dnl # ZFS_LINUX_TRY_COMPILE_SYMBOL
+-dnl # like ZFS_LINUX_TRY_COMPILE, except ZFS_CHECK_SYMBOL_EXPORT
+-dnl # is called if not compiling for builtin
++dnl #
++dnl # Like ZFS_LINUX_TRY_COMPILER except ZFS_CHECK_SYMBOL_EXPORT is called
++dnl # to verify symbol exports, unless --enable-linux-builtin was provided
++dnl # to configure.
+ dnl #
+ AC_DEFUN([ZFS_LINUX_TRY_COMPILE_SYMBOL], [
+ ZFS_LINUX_TRY_COMPILE([$1], [$2], [rc=0], [rc=1])
+@@ -673,10 +877,9 @@ dnl # ZFS_LINUX_TRY_COMPILE_HEADER
+ dnl # like ZFS_LINUX_TRY_COMPILE, except the contents conftest.h are
+ dnl # provided via the fifth parameter
+ dnl #
+-AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER],
+- [ZFS_LINUX_COMPILE_IFELSE(
+- [AC_LANG_SOURCE([ZFS_LANG_PROGRAM([[$1]], [[$2]])])],
+- [modules],
+- [test -s build/conftest.o],
+- [$3], [$4], [$5])
++AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [
++ ZFS_LINUX_COMPILE_IFELSE(
++ [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]])],
++ [test -f build/conftest/conftest.ko],
++ [$3], [$4], [$5])
+ ])
+diff --git a/config/zfs-build.m4 b/config/zfs-build.m4
+index 8e221f2d7..d2c355425 100644
+--- a/config/zfs-build.m4
++++ b/config/zfs-build.m4
+@@ -166,6 +166,17 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
+ ])
+
+ AC_DEFUN([ZFS_AC_CONFIG], [
++
++ dnl # Remove the previous build test directory.
++ rm -Rf build
++
++ AC_ARG_VAR([TEST_JOBS],
++ [simultaneous jobs during configure (defaults to $(nproc))])
++ if test "x$ac_cv_env_TEST_JOBS_set" != "xset"; then
++ TEST_JOBS=$(nproc)
++ fi
++ AC_SUBST(TEST_JOBS)
++
+ ZFS_CONFIG=all
+ AC_ARG_WITH([config],
+ AS_HELP_STRING([--with-config=CONFIG],
+diff --git a/config/zfs-meta.m4 b/config/zfs-meta.m4
+index f525e2010..660d8ccb9 100644
+--- a/config/zfs-meta.m4
++++ b/config/zfs-meta.m4
+@@ -162,6 +162,24 @@ AC_DEFUN([ZFS_AC_META], [
+ AC_SUBST([ZFS_META_AUTHOR])
+ fi
+
++ ZFS_META_KVER_MIN=_ZFS_AC_META_GETVAL([Linux-Minimum]);
++ if test -n "$ZFS_META_KVER_MIN"; then
++ AC_DEFINE_UNQUOTED([ZFS_META_KVER_MIN],
++ ["$ZFS_META_KVER_MIN"],
++ [Define the minimum compatible kernel version.]
++ )
++ AC_SUBST([ZFS_META_KVER_MIN])
++ fi
++
++ ZFS_META_KVER_MAX=_ZFS_AC_META_GETVAL([Linux-Maximum]);
++ if test -n "$ZFS_META_KVER_MAX"; then
++ AC_DEFINE_UNQUOTED([ZFS_META_KVER_MAX],
++ ["$ZFS_META_KVER_MAX"],
++ [Define the maximum compatible kernel version.]
++ )
++ AC_SUBST([ZFS_META_KVER_MAX])
++ fi
++
+ m4_pattern_allow([^LT_(CURRENT|REVISION|AGE)$])
+ ZFS_META_LT_CURRENT=_ZFS_AC_META_GETVAL([LT_Current]);
+ ZFS_META_LT_REVISION=_ZFS_AC_META_GETVAL([LT_Revision]);
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Brian Behlendorf <behlendorf1@llnl.gov>
+Date: Thu, 3 Oct 2019 00:03:20 +0000
+Subject: [PATCH] Linux 4.14, 4.19, 5.0+ compat: SIMD save/restore
+
+Contrary to initial testing we cannot rely on these kernels to
+invalidate the per-cpu FPU state and restore the FPU registers.
+Therefore, the kfpu_begin() and kfpu_end() functions have been
+updated to unconditionally save and restore the FPU state.
+
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Issue #9346
+(cherry picked from commit 813fd014a90229127f80b970a8fef5049fd4c713)
+Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+---
+ config/kernel-fpu.m4 | 82 +++++++++++----------
+ include/linux/simd_x86.h | 152 ++++++++++++++++++++++++++++-----------
+ 2 files changed, 155 insertions(+), 79 deletions(-)
+
+diff --git a/config/kernel-fpu.m4 b/config/kernel-fpu.m4
+index a2c47d65a..9ed9b14ad 100644
+--- a/config/kernel-fpu.m4
++++ b/config/kernel-fpu.m4
+@@ -2,15 +2,9 @@ dnl #
+ dnl # Handle differences in kernel FPU code.
+ dnl #
+ dnl # Kernel
+-dnl # 5.2: The fpu->initialized flag was replaced by TIF_NEED_FPU_LOAD.
+-dnl # HAVE_KERNEL_TIF_NEED_FPU_LOAD
+-dnl #
+-dnl # 5.0: As an optimization SIMD operations performed by kernel
+-dnl # threads can skip saving and restoring their FPU context.
+-dnl # Wrappers have been introduced to determine the running
+-dnl # context and use either the SIMD or generic implementation.
++dnl # 5.0: Wrappers have been introduced to save/restore the FPU state.
+ dnl # This change was made to the 4.19.38 and 4.14.120 LTS kernels.
+-dnl # HAVE_KERNEL_FPU_INITIALIZED
++dnl # HAVE_KERNEL_FPU_INTERNAL
+ dnl #
+ dnl # 4.2: Use __kernel_fpu_{begin,end}()
+ dnl # HAVE_UNDERSCORE_KERNEL_FPU & KERNEL_EXPORTS_X86_FPU
+@@ -61,22 +55,47 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
+ __kernel_fpu_end();
+ ], [], [$ZFS_META_LICENSE])
+
+- ZFS_LINUX_TEST_SRC([fpu_initialized], [
+- #include <linux/module.h>
++ ZFS_LINUX_TEST_SRC([fpu_internal], [
++ #if defined(__x86_64) || defined(__x86_64__) || \
++ defined(__i386) || defined(__i386__)
++ #if !defined(__x86)
++ #define __x86
++ #endif
++ #endif
++
++ #if !defined(__x86)
++ #error Unsupported architecture
++ #endif
++
+ #include <linux/sched.h>
+- ],[
+- struct fpu *fpu = ¤t->thread.fpu;
+- if (fpu->initialized) { return (0); };
+- ])
+
+- ZFS_LINUX_TEST_SRC([tif_need_fpu_load], [
+- #include <linux/module.h>
+- #include <asm/thread_info.h>
++ #if !defined(PF_KTHREAD)
++ #error PF_KTHREAD not defined
++ #endif
+
+- #if !defined(TIF_NEED_FPU_LOAD)
+- #error "TIF_NEED_FPU_LOAD undefined"
++ #ifdef HAVE_KERNEL_FPU_API_HEADER
++ #include <asm/fpu/api.h>
++ #include <asm/fpu/internal.h>
++ #else
++ #include <asm/i387.h>
++ #include <asm/xcr.h>
++ #endif
++
++ #if !defined(XSTATE_XSAVE)
++ #error XSTATE_XSAVE not defined
++ #endif
++
++ #if !defined(XSTATE_XRESTORE)
++ #error XSTATE_XRESTORE not defined
+ #endif
+- ],[])
++ ],[
++ struct fpu *fpu = ¤t->thread.fpu;
++ union fpregs_state *st = &fpu->state;
++ struct fregs_state *fr __attribute__ ((unused)) = &st->fsave;
++ struct fxregs_state *fxr __attribute__ ((unused)) = &st->fxsave;
++ struct xregs_state *xr __attribute__ ((unused)) = &st->xsave;
++ fpu->last_cpu = -1;
++ ])
+ ])
+
+ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
+@@ -104,25 +123,12 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
+ AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1,
+ [kernel exports FPU functions])
+ ],[
+- dnl #
+- dnl # Linux 5.0 kernel
+- dnl #
+- ZFS_LINUX_TEST_RESULT([fpu_initialized], [
+- AC_MSG_RESULT(fpu.initialized)
+- AC_DEFINE(HAVE_KERNEL_FPU_INITIALIZED, 1,
+- [kernel fpu.initialized exists])
++ ZFS_LINUX_TEST_RESULT([fpu_internal], [
++ AC_MSG_RESULT(internal)
++ AC_DEFINE(HAVE_KERNEL_FPU_INTERNAL, 1,
++ [kernel fpu internal])
+ ],[
+- dnl #
+- dnl # Linux 5.2 kernel
+- dnl #
+- ZFS_LINUX_TEST_RESULT([tif_need_fpu_load], [
+- AC_MSG_RESULT(TIF_NEED_FPU_LOAD)
+- AC_DEFINE(
+- HAVE_KERNEL_TIF_NEED_FPU_LOAD, 1,
+- [kernel TIF_NEED_FPU_LOAD exists])
+- ],[
+- AC_MSG_RESULT(unavailable)
+- ])
++ AC_MSG_RESULT(unavailable)
+ ])
+ ])
+ ])
+diff --git a/include/linux/simd_x86.h b/include/linux/simd_x86.h
+index 641f43955..d1ded3af2 100644
+--- a/include/linux/simd_x86.h
++++ b/include/linux/simd_x86.h
+@@ -126,38 +126,68 @@
+ #endif
+
+ #else /* defined(KERNEL_EXPORTS_X86_FPU) */
++
+ /*
+ * When the kernel_fpu_* symbols are unavailable then provide our own
+ * versions which allow the FPU to be safely used in kernel threads.
+ * In practice, this is not a significant restriction for ZFS since the
+ * vast majority of SIMD operations are performed by the IO pipeline.
+ */
++#if defined(HAVE_KERNEL_FPU_INTERNAL)
+
+ /*
+- * Returns non-zero if FPU operations are allowed in the current context.
++ * FPU usage only allowed in dedicated kernel threads.
+ */
+-#if defined(HAVE_KERNEL_TIF_NEED_FPU_LOAD)
+-#define kfpu_allowed() ((current->flags & PF_KTHREAD) && \
+- test_thread_flag(TIF_NEED_FPU_LOAD))
+-#elif defined(HAVE_KERNEL_FPU_INITIALIZED)
+-#define kfpu_allowed() ((current->flags & PF_KTHREAD) && \
+- current->thread.fpu.initialized)
+-#else
+-#define kfpu_allowed() 0
+-#endif
++#define kfpu_allowed() (current->flags & PF_KTHREAD)
++#define ex_handler_fprestore ex_handler_default
++
++/*
++ * FPU save and restore instructions.
++ */
++#define __asm __asm__ __volatile__
++#define kfpu_fxsave(addr) __asm("fxsave %0" : "=m" (*(addr)))
++#define kfpu_fxsaveq(addr) __asm("fxsaveq %0" : "=m" (*(addr)))
++#define kfpu_fnsave(addr) __asm("fnsave %0; fwait" : "=m" (*(addr)))
++#define kfpu_fxrstor(addr) __asm("fxrstor %0" : : "m" (*(addr)))
++#define kfpu_fxrstorq(addr) __asm("fxrstorq %0" : : "m" (*(addr)))
++#define kfpu_frstor(addr) __asm("frstor %0" : : "m" (*(addr)))
++#define kfpu_fxsr_clean(rval) __asm("fnclex; emms; fildl %P[addr]" \
++ : : [addr] "m" (rval));
+
+ static inline void
+ kfpu_initialize(void)
+ {
+ WARN_ON_ONCE(!(current->flags & PF_KTHREAD));
+
+-#if defined(HAVE_KERNEL_TIF_NEED_FPU_LOAD)
+- __fpu_invalidate_fpregs_state(¤t->thread.fpu);
+- set_thread_flag(TIF_NEED_FPU_LOAD);
+-#elif defined(HAVE_KERNEL_FPU_INITIALIZED)
+- __fpu_invalidate_fpregs_state(¤t->thread.fpu);
+- current->thread.fpu.initialized = 1;
+-#endif
++ /* Invalidate the task's FPU state */
++ current->thread.fpu.last_cpu = -1;
++}
++
++static inline void
++kfpu_save_xsave(struct xregs_state *addr, uint64_t mask)
++{
++ uint32_t low, hi;
++ int err;
++
++ low = mask;
++ hi = mask >> 32;
++ XSTATE_XSAVE(addr, low, hi, err);
++ WARN_ON_ONCE(err);
++}
++
++static inline void
++kfpu_save_fxsr(struct fxregs_state *addr)
++{
++ if (IS_ENABLED(CONFIG_X86_32))
++ kfpu_fxsave(addr);
++ else
++ kfpu_fxsaveq(addr);
++}
++
++static inline void
++kfpu_save_fsave(struct fregs_state *addr)
++{
++ kfpu_fnsave(addr);
+ }
+
+ static inline void
+@@ -172,46 +202,86 @@ kfpu_begin(void)
+ preempt_disable();
+ local_irq_disable();
+
+-#if defined(HAVE_KERNEL_TIF_NEED_FPU_LOAD)
+ /*
+ * The current FPU registers need to be preserved by kfpu_begin()
+- * and restored by kfpu_end(). This is required because we can
+- * not call __cpu_invalidate_fpregs_state() to invalidate the
+- * per-cpu FPU state and force them to be restored during a
+- * context switch.
++ * and restored by kfpu_end(). This is always required because we
++ * can not call __cpu_invalidate_fpregs_state() to invalidate the
++ * per-cpu FPU state and force them to be restored. Furthermore,
++ * this implementation relies on the space provided in the task
++ * structure to store the user FPU state. As such, it can only
++ * be used with dedicated kernels which by definition will never
++ * store user FPU state.
+ */
+- copy_fpregs_to_fpstate(¤t->thread.fpu);
+-#elif defined(HAVE_KERNEL_FPU_INITIALIZED)
++ if (static_cpu_has(X86_FEATURE_XSAVE)) {
++ kfpu_save_xsave(¤t->thread.fpu.state.xsave, ~0);
++ } else if (static_cpu_has(X86_FEATURE_FXSR)) {
++ kfpu_save_fxsr(¤t->thread.fpu.state.fxsave);
++ } else {
++ kfpu_save_fsave(¤t->thread.fpu.state.fsave);
++ }
++}
++
++static inline void
++kfpu_restore_xsave(struct xregs_state *addr, uint64_t mask)
++{
++ uint32_t low, hi;
++
++ low = mask;
++ hi = mask >> 32;
++ XSTATE_XRESTORE(addr, low, hi);
++}
++
++static inline void
++kfpu_restore_fxsr(struct fxregs_state *addr)
++{
+ /*
+- * There is no need to preserve and restore the FPU registers.
+- * They will always be restored from the task's stored FPU state
+- * when switching contexts.
++ * On AuthenticAMD K7 and K8 processors the fxrstor instruction only
++ * restores the _x87 FOP, FIP, and FDP registers when an exception
++ * is pending. Clean the _x87 state to force the restore.
+ */
+- WARN_ON_ONCE(current->thread.fpu.initialized == 0);
+-#endif
++ if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK)))
++ kfpu_fxsr_clean(addr);
++
++ if (IS_ENABLED(CONFIG_X86_32)) {
++ kfpu_fxrstor(addr);
++ } else {
++ kfpu_fxrstorq(addr);
++ }
+ }
+
+ static inline void
+-kfpu_end(void)
++kfpu_restore_fsave(struct fregs_state *addr)
+ {
+-#if defined(HAVE_KERNEL_TIF_NEED_FPU_LOAD)
+- union fpregs_state *state = ¤t->thread.fpu.state;
+- int error;
++ kfpu_frstor(addr);
++}
+
+- if (use_xsave()) {
+- error = copy_kernel_to_xregs_err(&state->xsave, -1);
+- } else if (use_fxsr()) {
+- error = copy_kernel_to_fxregs_err(&state->fxsave);
++static inline void
++kfpu_end(void)
++{
++ if (static_cpu_has(X86_FEATURE_XSAVE)) {
++ kfpu_restore_xsave(¤t->thread.fpu.state.xsave, ~0);
++ } else if (static_cpu_has(X86_FEATURE_FXSR)) {
++ kfpu_restore_fxsr(¤t->thread.fpu.state.fxsave);
+ } else {
+- error = copy_kernel_to_fregs_err(&state->fsave);
++ kfpu_restore_fsave(¤t->thread.fpu.state.fsave);
+ }
+- WARN_ON_ONCE(error);
+-#endif
+
+ local_irq_enable();
+ preempt_enable();
+ }
+-#endif /* defined(HAVE_KERNEL_FPU) */
++
++#else
++
++/*
++ * FPU support is unavailable.
++ */
++#define kfpu_allowed() 0
++#define kfpu_initialize(tsk) do {} while (0)
++#define kfpu_begin() do {} while (0)
++#define kfpu_end() do {} while (0)
++
++#endif /* defined(HAVE_KERNEL_FPU_INTERNAL) */
++#endif /* defined(KERNEL_EXPORTS_X86_FPU) */
+
+ #else /* defined(_KERNEL) */
+ /*
+++ /dev/null
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Thomas Lamprecht <t.lamprecht@proxmox.com>
-Date: Wed, 25 Sep 2019 10:48:48 +0200
-Subject: [PATCH] [SIMD]: FPU register save/restore is also required on 5.0
- kernels
-
-NOTE: the kernel needs to have the copy_kernel_to_xregs_err,
-copy_kernel_to_fxregs_err and copy_kernel_to_fregs_err functions
-backported for this to work.
-
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
----
- include/linux/simd_x86.h | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
-
-diff --git a/include/linux/simd_x86.h b/include/linux/simd_x86.h
-index edd456098..98503a29e 100644
---- a/include/linux/simd_x86.h
-+++ b/include/linux/simd_x86.h
-@@ -181,7 +181,6 @@ kfpu_begin(void)
- preempt_disable();
- local_irq_disable();
-
--#if defined(HAVE_KERNEL_TIF_NEED_FPU_LOAD)
- /*
- * The current FPU registers need to be preserved by kfpu_begin()
- * and restored by kfpu_end(). This is required because we can
-@@ -190,11 +189,11 @@ kfpu_begin(void)
- * context switch.
- */
- copy_fpregs_to_fpstate(¤t->thread.fpu);
--#elif defined(HAVE_KERNEL_FPU_INITIALIZED)
-+
-+
-+#if defined(HAVE_KERNEL_FPU_INITIALIZED)
- /*
-- * There is no need to preserve and restore the FPU registers.
-- * They will always be restored from the task's stored FPU state
-- * when switching contexts.
-+ * Was removed with 5.2 as it was always set to 1 there
- */
- WARN_ON_ONCE(current->thread.fpu.initialized == 0);
- #endif
-@@ -203,7 +202,6 @@ kfpu_begin(void)
- static inline void
- kfpu_end(void)
- {
--#if defined(HAVE_KERNEL_TIF_NEED_FPU_LOAD)
- union fpregs_state *state = ¤t->thread.fpu.state;
- int error;
-
-@@ -215,7 +213,6 @@ kfpu_end(void)
- error = copy_kernel_to_fregs_err(&state->fsave);
- }
- WARN_ON_ONCE(error);
--#endif
-
- local_irq_enable();
- preempt_enable();
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Brian Behlendorf <behlendorf1@llnl.gov>
+Date: Wed, 17 Jul 2019 09:14:36 -0700
+Subject: [PATCH] Fix CONFIG_X86_DEBUG_FPU build failure
+
+When CONFIG_X86_DEBUG_FPU is defined the alternatives_patched symbol
+is pulled in as a dependency which results in a build failure. To
+prevent this undefine CONFIG_X86_DEBUG_FPU to disable the WARN_ON_FPU()
+macro and rely on WARN_ON_ONCE debugging checks which were previously
+added.
+
+Reviewed-by: Tony Hutter <hutter2@llnl.gov>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes #9041
+Closes #9049
+Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+---
+ include/linux/simd_x86.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/include/linux/simd_x86.h b/include/linux/simd_x86.h
+index d1ded3af2..b32bccc41 100644
+--- a/include/linux/simd_x86.h
++++ b/include/linux/simd_x86.h
+@@ -84,6 +84,15 @@
+
+ #if defined(_KERNEL)
+
++/*
++ * Disable the WARN_ON_FPU() macro to prevent additional dependencies
++ * when providing the kfpu_* functions. Relevant warnings are included
++ * as appropriate and are unconditionally enabled.
++ */
++#if defined(CONFIG_X86_DEBUG_FPU) && !defined(KERNEL_EXPORTS_X86_FPU)
++#undef CONFIG_X86_DEBUG_FPU
++#endif
++
+ #if defined(HAVE_KERNEL_FPU_API_HEADER)
+ #include <asm/fpu/api.h>
+ #include <asm/fpu/internal.h>
+++ /dev/null
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Brian Behlendorf <behlendorf1@llnl.gov>
-Date: Tue, 1 Oct 2019 12:50:34 -0700
-Subject: [PATCH] Perform KABI checks in parallel
-
-Reduce the time required for ./configure to perform the needed
-KABI checks by allowing kbuild to compile multiple test cases in
-parallel. This was accomplished by splitting each test's source
-code from the logic handling whether that code could be compiled
-or not.
-
-By introducing this split it's possible to minimize the number of
-times kbuild needs to be invoked. As importantly, it means all of
-the tests can be built in parallel. This does require a little extra
-care since we expect some tests to fail, so the --keep-going (-k)
-option must be provided otherwise some tests may not get compiled.
-Furthermore, since a failure during the kbuild modpost phase will
-result in an early exit; the final linking phase is limited to tests
-which passed the initial compilation and produced an object file.
-
-Once everything has been built the configure script proceeds as
-previously. The only significant difference is that it now merely
-needs to test for the existence of a .ko file to determine the
-result of a given test. This vastly speeds up the entire process.
-
-New test cases should use ZFS_LINUX_TEST_SRC to declare their test
-source code and ZFS_LINUX_TEST_RESULT to check the result. All of
-the existing kernel-*.m4 files have been updated accordingly, see
-config/kernel-current-time.m4 for a basic example. The legacy
-ZFS_LINUX_TRY_COMPILE macro has been kept to handle special cases
-but it's use is not encouraged.
-
- master (secs) patched (secs)
- ------------- ----------------
-autogen.sh 61 68
-configure 137 24 (~17% of current run time)
-make -j $(nproc) 44 44
-make rpms 287 150
-
-Reviewed-by: Tony Hutter <hutter2@llnl.gov>
-Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Closes #8547
-Closes #9132
-Closes #9341
-(cherry picked from commit 608f8749a1055e6769899788e11bd51fd396f9e5)
-Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
----
- .gitignore | 1 +
- Makefile.am | 6 +-
- config/iconv.m4 | 3 +-
- config/kernel-access-ok-type.m4 | 18 +-
- config/kernel-acl.m4 | 253 ++++--
- config/kernel-aio-fsync.m4 | 14 +-
- config/kernel-automount.m4 | 13 +-
- config/kernel-bdev-logical-size.m4 | 17 +-
- config/kernel-bdev-physical-size.m4 | 17 +-
- config/kernel-bdi.m4 | 78 +-
- config/kernel-bio-bvec-iter.m4 | 13 +-
- config/kernel-bio-end-io-t-args.m4 | 34 +-
- config/kernel-bio-failfast.m4 | 39 +-
- config/kernel-bio-op.m4 | 74 +-
- config/kernel-bio-rw-barrier.m4 | 15 +-
- config/kernel-bio-rw-discard.m4 | 15 +-
- config/kernel-bio_set_dev.m4 | 51 +-
- config/kernel-blk-queue-bdi.m4 | 12 +-
- config/kernel-blk-queue-discard.m4 | 41 +-
- config/kernel-blk-queue-flags.m4 | 40 +-
- config/kernel-blk-queue-flush.m4 | 64 +-
- config/kernel-blk-queue-max-hw-sectors.m4 | 19 +-
- config/kernel-blk-queue-max-segments.m4 | 21 +-
- config/kernel-blk-queue-unplug.m4 | 48 +-
- config/kernel-blkdev-get-by-path.m4 | 15 +-
- config/kernel-blkdev-reread-part.m4 | 12 +-
- config/kernel-block-device-operations.m4 | 46 +-
- config/kernel-clear-inode.m4 | 13 +-
- config/kernel-commit-metadata.m4 | 15 +-
- config/kernel-config-defined.m4 | 183 ++++
- config/kernel-create-nameidata.m4 | 15 +-
- config/kernel-ctl-table-name.m4 | 12 +-
- config/kernel-current-time.m4 | 13 +-
- config/kernel-current_bio_tail.m4 | 30 +-
- config/kernel-d-make-root.m4 | 17 -
- config/kernel-d-obtain-alias.m4 | 18 -
- config/kernel-d-prune-aliases.m4 | 19 -
- config/kernel-declare-event-class.m4 | 8 +-
- config/kernel-dentry-operations.m4 | 174 +++-
- config/kernel-dirty-inode.m4 | 15 +-
- config/kernel-discard-granularity.m4 | 15 +-
- config/kernel-elevator-change.m4 | 21 +-
- config/kernel-encode-fh-inode.m4 | 15 +-
- config/kernel-evict-inode.m4 | 13 +-
- config/kernel-fallocate-pax.m4 | 19 -
- config/kernel-fallocate.m4 | 50 +-
- config/kernel-file-dentry.m4 | 12 +-
- config/kernel-file-inode.m4 | 12 +-
- config/kernel-fmode-t.m4 | 15 +-
- config/kernel-follow-down-one.m4 | 12 +-
- config/kernel-fpu.m4 | 99 ++-
- config/kernel-fst-mount.m4 | 13 +-
- config/kernel-fsync.m4 | 83 +-
- config/kernel-generic_io_acct.m4 | 63 +-
- config/kernel-generic_readlink.m4 | 15 +-
- config/kernel-get-disk-and-module.m4 | 13 +-
- config/kernel-get-disk-ro.m4 | 18 +-
- config/kernel-get-link.m4 | 126 +--
- config/kernel-global_page_state.m4 | 72 +-
- config/kernel-group-info.m4 | 15 +-
- config/kernel-in-compat-syscall.m4 | 12 +-
- config/kernel-inode-getattr.m4 | 56 +-
- config/kernel-inode-lock.m4 | 15 +-
- config/kernel-inode-set-flags.m4 | 12 +-
- config/kernel-inode-set-iversion.m4 | 12 +-
- config/kernel-inode-times.m4 | 15 +-
- config/kernel-insert-inode-locked.m4 | 15 +-
- config/kernel-invalidate-bdev-args.m4 | 14 +-
- config/kernel-is_owner_or_cap.m4 | 31 +-
- config/kernel-kmap-atomic-args.m4 | 14 +-
- config/kernel-kmem-cache.m4 | 62 +-
- config/kernel-kstrtoul.m4 | 14 +-
- config/kernel-ktime_get_coarse_real_ts64.m4 | 15 +-
- config/kernel-kuid-helpers.m4 | 12 +-
- config/kernel-kuidgid.m4 | 26 +-
- config/kernel-lookup-bdev.m4 | 32 +-
- config/kernel-lookup-nameidata.m4 | 15 +-
- config/kernel-lseek-execute.m4 | 16 +-
- config/kernel-make-request-fn.m4 | 77 ++
- config/kernel-misc-minor.m4 | 2 +-
- config/kernel-mk-request-fn.m4 | 65 --
- config/kernel-mkdir-umode-t.m4 | 13 +-
- config/kernel-mod-param.m4 | 13 +-
- config/kernel-objtool.m4 | 47 +-
- config/kernel-open-bdev-exclusive.m4 | 15 +-
- config/kernel-pde-data.m4 | 14 +-
- config/kernel-put-link.m4 | 57 +-
- config/kernel-rename.m4 | 16 +-
- config/kernel-rw.m4 | 40 +-
- config/kernel-rwsem.m4 | 65 +-
- config/kernel-sched.m4 | 53 +-
- config/kernel-security-inode-init.m4 | 38 +-
- config/kernel-set-nlink.m4 | 15 +-
- config/kernel-setattr-prepare.m4 | 16 +-
- config/kernel-sget-args.m4 | 13 +-
- config/kernel-show-options.m4 | 21 +-
- config/kernel-shrink.m4 | 219 +++--
- config/kernel-submit_bio.m4 | 12 +-
- config/kernel-super-userns.m4 | 14 +-
- config/kernel-timer.m4 | 52 +-
- config/kernel-tmpfile.m4 | 16 +-
- config/kernel-totalhigh_pages.m4 | 14 +-
- config/kernel-totalram-pages-func.m4 | 15 +-
- config/kernel-truncate-range.m4 | 13 +-
- config/kernel-truncate-setsize.m4 | 15 +-
- config/kernel-userns-capabilities.m4 | 48 +-
- ...urange-sleep.m4 => kernel-usleep_range.m4} | 19 +-
- config/kernel-vfs-direct_IO.m4 | 145 ++--
- config/kernel-vfs-fsync.m4 | 12 +-
- config/kernel-vfs-getattr.m4 | 54 +-
- config/kernel-vfs-iterate.m4 | 84 +-
- config/kernel-vfs-rw-iterate.m4 | 76 +-
- config/kernel-wait.m4 | 73 +-
- config/kernel-xattr-handler.m4 | 442 +++++-----
- config/kernel-zlib.m4 | 57 +-
- config/kernel.m4 | 783 +++++++++++-------
- config/zfs-build.m4 | 11 +
- config/zfs-meta.m4 | 18 +
- 118 files changed, 3245 insertions(+), 2127 deletions(-)
- create mode 100644 config/kernel-config-defined.m4
- delete mode 100644 config/kernel-d-make-root.m4
- delete mode 100644 config/kernel-d-obtain-alias.m4
- delete mode 100644 config/kernel-d-prune-aliases.m4
- delete mode 100644 config/kernel-fallocate-pax.m4
- create mode 100644 config/kernel-make-request-fn.m4
- delete mode 100644 config/kernel-mk-request-fn.m4
- rename config/{kernel-urange-sleep.m4 => kernel-usleep_range.m4} (60%)
-
-diff --git a/.gitignore b/.gitignore
-index ae9e22dfa..19377a7b1 100644
---- a/.gitignore
-+++ b/.gitignore
-@@ -36,6 +36,7 @@ Makefile.in
- # Top level generated files specific to this top level dir
- #
- /bin
-+/build
- /configure
- /config.log
- /config.status
-diff --git a/Makefile.am b/Makefile.am
-index 9afe22954..5ee7c20be 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -40,7 +40,7 @@ gitrev:
- BUILT_SOURCES = gitrev
-
- distclean-local::
-- -$(RM) -R autom4te*.cache
-+ -$(RM) -R autom4te*.cache build
- -find . \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
- -o -name .pc -o -name .hg -o -name .git \) -prune -o \
- \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
-@@ -87,8 +87,8 @@ commitcheck:
- fi
-
- cstyle:
-- @find ${top_srcdir} -name '*.[hc]' ! -name 'zfs_config.*' \
-- ! -name '*.mod.c' -type f \
-+ @find ${top_srcdir} -name build -prune -o -name '*.[hc]' \
-+ ! -name 'zfs_config.*' ! -name '*.mod.c' -type f \
- -exec ${top_srcdir}/scripts/cstyle.pl -cpP {} \+
-
- shellcheck:
-diff --git a/config/iconv.m4 b/config/iconv.m4
-index a285e9daa..fc915fde6 100644
---- a/config/iconv.m4
-+++ b/config/iconv.m4
-@@ -269,8 +269,7 @@ size_t iconv();
- [am_cv_proto_iconv_arg1="const"])
- am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
- am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
-- AC_MSG_RESULT([
-- $am_cv_proto_iconv])
-+ AC_MSG_RESULT([$am_cv_proto_iconv])
- else
- dnl When compiling GNU libiconv on a system that does not have iconv yet,
- dnl pick the POSIX compliant declaration without 'const'.
-diff --git a/config/kernel-access-ok-type.m4 b/config/kernel-access-ok-type.m4
-index 3b2878a55..dc9433458 100644
---- a/config/kernel-access-ok-type.m4
-+++ b/config/kernel-access-ok-type.m4
-@@ -4,17 +4,23 @@ dnl #
- dnl # - access_ok(type, addr, size)
- dnl # + access_ok(addr, size)
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_ACCESS_OK_TYPE], [
-- AC_MSG_CHECKING([whether access_ok() has 'type' parameter])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE], [
-+ ZFS_LINUX_TEST_SRC([access_ok_type], [
- #include <linux/uaccess.h>
- ],[
-- const void __user __attribute__((unused)) *addr = (void *) 0xdeadbeef;
-+ const void __user __attribute__((unused)) *addr =
-+ (void *) 0xdeadbeef;
- unsigned long __attribute__((unused)) size = 1;
- int error __attribute__((unused)) = access_ok(0, addr, size);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_ACCESS_OK_TYPE], [
-+ AC_MSG_CHECKING([whether access_ok() has 'type' parameter])
-+ ZFS_LINUX_TEST_RESULT([access_ok_type], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_ACCESS_OK_TYPE, 1, [kernel has access_ok with 'type' parameter])
-+ AC_DEFINE(HAVE_ACCESS_OK_TYPE, 1,
-+ [kernel has access_ok with 'type' parameter])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-acl.m4 b/config/kernel-acl.m4
-index 02cc020e5..68a72872d 100644
---- a/config/kernel-acl.m4
-+++ b/config/kernel-acl.m4
-@@ -3,32 +3,26 @@ dnl # Check if posix_acl_release can be used from a ZFS_META_LICENSED
- dnl # module. The is_owner_or_cap macro was replaced by
- dnl # inode_owner_or_capable
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_RELEASE], [
-- AC_MSG_CHECKING([whether posix_acl_release() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_RELEASE], [
-+ ZFS_LINUX_TEST_SRC([posix_acl_release], [
- #include <linux/cred.h>
- #include <linux/fs.h>
- #include <linux/posix_acl.h>
-- ],[
-- struct posix_acl* tmp = posix_acl_alloc(1, 0);
-+ ], [
-+ struct posix_acl *tmp = posix_acl_alloc(1, 0);
- posix_acl_release(tmp);
-- ],[
-+ ], [], [$ZFS_META_LICENSE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_RELEASE], [
-+ AC_MSG_CHECKING([whether posix_acl_release() is available])
-+ ZFS_LINUX_TEST_RESULT([posix_acl_release], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_POSIX_ACL_RELEASE, 1,
- [posix_acl_release() is available])
-
- AC_MSG_CHECKING([whether posix_acl_release() is GPL-only])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/module.h>
-- #include <linux/cred.h>
-- #include <linux/fs.h>
-- #include <linux/posix_acl.h>
--
-- MODULE_LICENSE("$ZFS_META_LICENSE");
-- ],[
-- struct posix_acl* tmp = posix_acl_alloc(1, 0);
-- posix_acl_release(tmp);
-- ],[
-+ ZFS_LINUX_TEST_RESULT([posix_acl_release_license], [
- AC_MSG_RESULT(no)
- ],[
- AC_MSG_RESULT(yes)
-@@ -46,24 +40,25 @@ dnl # set_cached_acl() and forget_cached_acl() changed from inline to
- dnl # EXPORT_SYMBOL. In the former case, they may not be usable because of
- dnl # posix_acl_release. In the latter case, we can always use them.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE], [
-- AC_MSG_CHECKING([whether set_cached_acl() is usable])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/module.h>
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_CACHED_ACL_USABLE], [
-+ ZFS_LINUX_TEST_SRC([set_cached_acl], [
- #include <linux/cred.h>
- #include <linux/fs.h>
- #include <linux/posix_acl.h>
--
-- MODULE_LICENSE("$ZFS_META_LICENSE");
-- ],[
-+ ], [
- struct inode *ip = NULL;
- struct posix_acl *acl = posix_acl_alloc(1, 0);
- set_cached_acl(ip, ACL_TYPE_ACCESS, acl);
- forget_cached_acl(ip, ACL_TYPE_ACCESS);
-- ],[
-+ ], [], [$ZFS_META_LICENSE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE], [
-+ AC_MSG_CHECKING([whether set_cached_acl() is usable])
-+ ZFS_LINUX_TEST_RESULT([set_cached_acl_license], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SET_CACHED_ACL_USABLE, 1,
-- [posix_acl_release() is usable])
-+ [set_cached_acl() is usable])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -77,14 +72,25 @@ dnl #
- dnl # 3.14 API change,
- dnl # posix_acl_chmod() is changed to __posix_acl_chmod()
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
-- AC_MSG_CHECKING([whether posix_acl_chmod exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_CHMOD], [
-+ ZFS_LINUX_TEST_SRC([posix_acl_chmod], [
- #include <linux/fs.h>
- #include <linux/posix_acl.h>
- ],[
- posix_acl_chmod(NULL, 0, 0)
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([__posix_acl_chmod], [
-+ #include <linux/fs.h>
-+ #include <linux/posix_acl.h>
- ],[
-+ __posix_acl_chmod(NULL, 0, 0)
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
-+ AC_MSG_CHECKING([whether posix_acl_chmod exists])
-+ ZFS_LINUX_TEST_RESULT([posix_acl_chmod], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_POSIX_ACL_CHMOD, 1, [posix_acl_chmod() exists])
- ],[
-@@ -92,14 +98,10 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
- ])
-
- AC_MSG_CHECKING([whether __posix_acl_chmod exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- #include <linux/posix_acl.h>
-- ],[
-- __posix_acl_chmod(NULL, 0, 0)
-- ],[
-+ ZFS_LINUX_TEST_RESULT([__posix_acl_chmod], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE___POSIX_ACL_CHMOD, 1, [__posix_acl_chmod() exists])
-+ AC_DEFINE(HAVE___POSIX_ACL_CHMOD, 1,
-+ [__posix_acl_chmod() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -109,18 +111,22 @@ dnl #
- dnl # 3.1 API change,
- dnl # posix_acl_equiv_mode now wants an umode_t* instead of a mode_t*
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
-- AC_MSG_CHECKING([whether posix_acl_equiv_mode() wants umode_t])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
-+ ZFS_LINUX_TEST_SRC([posix_acl_equiv_mode], [
- #include <linux/fs.h>
- #include <linux/posix_acl.h>
- ],[
- umode_t tmp;
- posix_acl_equiv_mode(NULL,&tmp);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
-+ AC_MSG_CHECKING([whether posix_acl_equiv_mode() wants umode_t])
-+ ZFS_LINUX_TEST_RESULT([posix_acl_equiv_mode], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T, 1,
-- [ posix_acl_equiv_mode wants umode_t*])
-+ [posix_acl_equiv_mode wants umode_t*])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -130,9 +136,8 @@ dnl #
- dnl # 4.8 API change,
- dnl # The function posix_acl_valid now must be passed a namespace.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [
-- AC_MSG_CHECKING([whether posix_acl_valid() wants user namespace])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS], [
-+ ZFS_LINUX_TEST_SRC([posix_acl_valid_with_ns], [
- #include <linux/fs.h>
- #include <linux/posix_acl.h>
- ],[
-@@ -141,7 +146,12 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [
- int error;
-
- error = posix_acl_valid(user_ns, acl);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [
-+ AC_MSG_CHECKING([whether posix_acl_valid() wants user namespace])
-+ ZFS_LINUX_TEST_RESULT([posix_acl_valid_with_ns], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_POSIX_ACL_VALID_WITH_NS, 1,
- [posix_acl_valid() wants user namespace])
-@@ -155,9 +165,8 @@ dnl # 2.6.27 API change,
- dnl # Check if inode_operations contains the function permission
- dnl # and expects the nameidata structure to have been removed.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION], [
-- AC_MSG_CHECKING([whether iops->permission() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_permission], [
- #include <linux/fs.h>
-
- int permission_fn(struct inode *inode, int mask) { return 0; }
-@@ -166,8 +175,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION], [
- iops __attribute__ ((unused)) = {
- .permission = permission_fn,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION], [
-+ AC_MSG_CHECKING([whether iops->permission() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_permission], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
- ],[
-@@ -180,9 +193,8 @@ dnl # 2.6.26 API change,
- dnl # Check if inode_operations contains the function permission
- dnl # and expects the nameidata structure to be passed.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
-- AC_MSG_CHECKING([whether iops->permission() wants nameidata])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_permission_with_nameidata], [
- #include <linux/fs.h>
- #include <linux/sched.h>
-
-@@ -193,8 +205,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
- iops __attribute__ ((unused)) = {
- .permission = permission_fn,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [
-+ AC_MSG_CHECKING([whether iops->permission() wants nameidata])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_permission_with_nameidata], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_PERMISSION, 1, [iops->permission() exists])
- AC_DEFINE(HAVE_PERMISSION_WITH_NAMEIDATA, 1,
-@@ -208,9 +224,8 @@ dnl #
- dnl # 2.6.32 API change,
- dnl # Check if inode_operations contains the function check_acl
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL], [
-- AC_MSG_CHECKING([whether iops->check_acl() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_check_acl], [
- #include <linux/fs.h>
-
- int check_acl_fn(struct inode *inode, int mask) { return 0; }
-@@ -219,8 +234,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL], [
- iops __attribute__ ((unused)) = {
- .check_acl = check_acl_fn,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL], [
-+ AC_MSG_CHECKING([whether iops->check_acl() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_check_acl], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
- ],[
-@@ -232,9 +251,8 @@ dnl #
- dnl # 2.6.38 API change,
- dnl # The function check_acl gained a new parameter: flags
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
-- AC_MSG_CHECKING([whether iops->check_acl() wants flags])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_check_acl_with_flags], [
- #include <linux/fs.h>
-
- int check_acl_fn(struct inode *inode, int mask,
-@@ -244,8 +262,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
- iops __attribute__ ((unused)) = {
- .check_acl = check_acl_fn,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS], [
-+ AC_MSG_CHECKING([whether iops->check_acl() wants flags])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_check_acl_with_flags], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_CHECK_ACL, 1, [iops->check_acl() exists])
- AC_DEFINE(HAVE_CHECK_ACL_WITH_FLAGS, 1,
-@@ -259,9 +281,8 @@ dnl #
- dnl # 3.1 API change,
- dnl # Check if inode_operations contains the function get_acl
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
-- AC_MSG_CHECKING([whether iops->get_acl() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
- #include <linux/fs.h>
-
- struct posix_acl *get_acl_fn(struct inode *inode, int type)
-@@ -271,8 +292,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
- iops __attribute__ ((unused)) = {
- .get_acl = get_acl_fn,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
-+ AC_MSG_CHECKING([whether iops->get_acl() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
- ],[
-@@ -284,20 +309,23 @@ dnl #
- dnl # 3.14 API change,
- dnl # Check if inode_operations contains the function set_acl
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
-- AC_MSG_CHECKING([whether iops->set_acl() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
- #include <linux/fs.h>
-
-- int set_acl_fn(struct inode *inode, struct posix_acl *acl, int type)
-- { return 0; }
-+ int set_acl_fn(struct inode *inode, struct posix_acl *acl,
-+ int type) { return 0; }
-
- static const struct inode_operations
- iops __attribute__ ((unused)) = {
- .set_acl = set_acl_fn,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
-+ AC_MSG_CHECKING([whether iops->set_acl() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
- ],[
-@@ -311,16 +339,79 @@ dnl # The kernel get_acl will now check cache before calling i_op->get_acl and
- dnl # do set_cached_acl after that, so i_op->get_acl don't need to do that
- dnl # anymore.
- dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_ACL_HANDLE_CACHE], [
-+ ZFS_LINUX_TEST_SRC([get_acl_handle_cache], [
-+ #include <linux/fs.h>
-+ ],[
-+ void *sentinel __attribute__ ((unused)) =
-+ uncached_acl_sentinel(NULL);
-+ ])
-+])
-+
- AC_DEFUN([ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE], [
- AC_MSG_CHECKING([whether uncached_acl_sentinel() exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-+ ZFS_LINUX_TEST_RESULT([get_acl_handle_cache], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_KERNEL_GET_ACL_HANDLE_CACHE, 1,
-+ [uncached_acl_sentinel() exists])
- ],[
-- void *sentinel __attribute__ ((unused)) = uncached_acl_sentinel(NULL);
-+ AC_MSG_RESULT(no)
-+ ])
-+])
-+
-+dnl #
-+dnl # 4.16 kernel: check if struct posix_acl acl.a_refcount is a refcount_t.
-+dnl # It's an atomic_t on older kernels.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL_HAS_REFCOUNT], [
-+ ZFS_LINUX_TEST_SRC([acl_refcount], [
-+ #include <linux/backing-dev.h>
-+ #include <linux/refcount.h>
-+ #include <linux/posix_acl.h>
- ],[
-+ struct posix_acl acl;
-+ refcount_t *r __attribute__ ((unused)) = &acl.a_refcount;
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_ACL_HAS_REFCOUNT], [
-+ AC_MSG_CHECKING([whether posix_acl has refcount_t])
-+ ZFS_LINUX_TEST_RESULT([acl_refcount], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_KERNEL_GET_ACL_HANDLE_CACHE, 1, [uncached_acl_sentinel() exists])
-+ AC_DEFINE(HAVE_ACL_REFCOUNT, 1, [posix_acl has refcount_t])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL], [
-+ ZFS_AC_KERNEL_SRC_POSIX_ACL_RELEASE
-+ ZFS_AC_KERNEL_SRC_SET_CACHED_ACL_USABLE
-+ ZFS_AC_KERNEL_SRC_POSIX_ACL_CHMOD
-+ ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
-+ ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS
-+ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION
-+ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
-+ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL
-+ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
-+ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL
-+ ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL
-+ ZFS_AC_KERNEL_SRC_GET_ACL_HANDLE_CACHE
-+ ZFS_AC_KERNEL_SRC_ACL_HAS_REFCOUNT
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_ACL], [
-+ ZFS_AC_KERNEL_POSIX_ACL_RELEASE
-+ ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE
-+ ZFS_AC_KERNEL_POSIX_ACL_CHMOD
-+ ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
-+ ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS
-+ ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION
-+ ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
-+ ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
-+ ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
-+ ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
-+ ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
-+ ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE
-+ ZFS_AC_KERNEL_ACL_HAS_REFCOUNT
-+])
-diff --git a/config/kernel-aio-fsync.m4 b/config/kernel-aio-fsync.m4
-index 41b7a98a6..b4dbf29ba 100644
---- a/config/kernel-aio-fsync.m4
-+++ b/config/kernel-aio-fsync.m4
-@@ -1,21 +1,23 @@
- dnl #
- dnl # Linux 4.9-rc5+ ABI, removal of the .aio_fsync field
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_AIO_FSYNC], [
-- AC_MSG_CHECKING([whether fops->aio_fsync() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_AIO_FSYNC], [
-+ ZFS_LINUX_TEST_SRC([aio_fsync], [
- #include <linux/fs.h>
-
- static const struct file_operations
- fops __attribute__ ((unused)) = {
- .aio_fsync = NULL,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_AIO_FSYNC], [
-+ AC_MSG_CHECKING([whether fops->aio_fsync() exists])
-+ ZFS_LINUX_TEST_RESULT([aio_fsync], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_FILE_AIO_FSYNC, 1, [fops->aio_fsync() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
--
-diff --git a/config/kernel-automount.m4 b/config/kernel-automount.m4
-index 1ee4c168d..93e14fa8d 100644
---- a/config/kernel-automount.m4
-+++ b/config/kernel-automount.m4
-@@ -5,16 +5,19 @@ dnl # solution to handling automounts. Prior to this cifs/nfs clients
- dnl # which required automount support would abuse the follow_link()
- dnl # operation on directories for this purpose.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
-- AC_MSG_CHECKING([whether dops->d_automount() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
-+ ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [
- #include <linux/dcache.h>
- struct vfsmount *d_automount(struct path *p) { return NULL; }
- struct dentry_operations dops __attribute__ ((unused)) = {
- .d_automount = d_automount,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
-+ AC_MSG_CHECKING([whether dops->d_automount() exists])
-+ ZFS_LINUX_TEST_RESULT([dentry_operations_d_automount], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_AUTOMOUNT, 1, [dops->automount() exists])
- ],[
-diff --git a/config/kernel-bdev-logical-size.m4 b/config/kernel-bdev-logical-size.m4
-index a6194577a..0de9afd88 100644
---- a/config/kernel-bdev-logical-size.m4
-+++ b/config/kernel-bdev-logical-size.m4
-@@ -5,21 +5,22 @@ dnl # it has been true for a while that there was no strict 1:1 mapping
- dnl # between physical sector size and logical block size this change makes
- dnl # it explicit.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE], [
-- AC_MSG_CHECKING([whether bdev_logical_block_size() is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_LOGICAL_BLOCK_SIZE], [
-+ ZFS_LINUX_TEST_SRC([bdev_logical_block_size], [
- #include <linux/blkdev.h>
- ],[
- struct block_device *bdev = NULL;
- bdev_logical_block_size(bdev);
-- ],[
-+ ], [$NO_UNUSED_BUT_SET_VARIABLE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE], [
-+ AC_MSG_CHECKING([whether bdev_logical_block_size() is available])
-+ ZFS_LINUX_TEST_RESULT([bdev_logical_block_size], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BDEV_LOGICAL_BLOCK_SIZE, 1,
-- [bdev_logical_block_size() is available])
-+ [bdev_logical_block_size() is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-bdev-physical-size.m4 b/config/kernel-bdev-physical-size.m4
-index 77746ee91..94d8172d3 100644
---- a/config/kernel-bdev-physical-size.m4
-+++ b/config/kernel-bdev-physical-size.m4
-@@ -19,21 +19,22 @@ dnl #
- dnl # Unfortunately, this interface isn't entirely reliable because
- dnl # drives are sometimes known to misreport this value.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BDEV_PHYSICAL_BLOCK_SIZE], [
-- AC_MSG_CHECKING([whether bdev_physical_block_size() is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_PHYSICAL_BLOCK_SIZE], [
-+ ZFS_LINUX_TEST_SRC([bdev_physical_block_size], [
- #include <linux/blkdev.h>
- ],[
- struct block_device *bdev = NULL;
- bdev_physical_block_size(bdev);
-- ],[
-+ ], [$NO_UNUSED_BUT_SET_VARIABLE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BDEV_PHYSICAL_BLOCK_SIZE], [
-+ AC_MSG_CHECKING([whether bdev_physical_block_size() is available])
-+ ZFS_LINUX_TEST_RESULT([bdev_physical_block_size], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BDEV_PHYSICAL_BLOCK_SIZE, 1,
-- [bdev_physical_block_size() is available])
-+ [bdev_physical_block_size() is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-bdi.m4 b/config/kernel-bdi.m4
-index cb7479ee9..51516332a 100644
---- a/config/kernel-bdi.m4
-+++ b/config/kernel-bdi.m4
-@@ -1,55 +1,81 @@
- dnl #
--dnl # 2.6.32 - 2.6.33, bdi_setup_and_register() is not exported.
--dnl # 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments.
--dnl # 4.0 - 4.11, bdi_setup_and_register() takes 2 arguments.
--dnl # 4.12 - x.y, super_setup_bdi_name() new interface.
-+dnl # Check available BDI interfaces.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BDI], [
-- AC_MSG_CHECKING([whether super_setup_bdi_name() exists])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BDI], [
-+ ZFS_LINUX_TEST_SRC([super_setup_bdi_name], [
- #include <linux/fs.h>
- struct super_block sb;
- ], [
- char *name = "bdi";
- atomic_long_t zfs_bdi_seq;
- int error __attribute__((unused)) =
-- super_setup_bdi_name(&sb, "%.28s-%ld", name, atomic_long_inc_return(&zfs_bdi_seq));
-- ], [super_setup_bdi_name], [fs/super.c], [
-+ super_setup_bdi_name(&sb, "%.28s-%ld", name,
-+ atomic_long_inc_return(&zfs_bdi_seq));
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([bdi_setup_and_register], [
-+ #include <linux/backing-dev.h>
-+ struct backing_dev_info bdi;
-+ ], [
-+ char *name = "bdi";
-+ int error __attribute__((unused)) =
-+ bdi_setup_and_register(&bdi, name);
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([bdi_setup_and_register_3args], [
-+ #include <linux/backing-dev.h>
-+ struct backing_dev_info bdi;
-+ ], [
-+ char *name = "bdi";
-+ unsigned int cap = BDI_CAP_MAP_COPY;
-+ int error __attribute__((unused)) =
-+ bdi_setup_and_register(&bdi, name, cap);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BDI], [
-+ dnl #
-+ dnl # 4.12, super_setup_bdi_name() introduced.
-+ dnl #
-+ AC_MSG_CHECKING([whether super_setup_bdi_name() exists])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([super_setup_bdi_name],
-+ [super_setup_bdi_name], [fs/super.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SUPER_SETUP_BDI_NAME, 1,
- [super_setup_bdi_name() exits])
- ], [
- AC_MSG_RESULT(no)
-+
-+ dnl #
-+ dnl # 4.0 - 4.11, bdi_setup_and_register() takes 2 arguments.
-+ dnl #
- AC_MSG_CHECKING(
- [whether bdi_setup_and_register() wants 2 args])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-- #include <linux/backing-dev.h>
-- struct backing_dev_info bdi;
-- ], [
-- char *name = "bdi";
-- int error __attribute__((unused)) =
-- bdi_setup_and_register(&bdi, name);
-- ], [bdi_setup_and_register], [mm/backing-dev.c], [
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([bdi_setup_and_register],
-+ [bdi_setup_and_register], [mm/backing-dev.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_2ARGS_BDI_SETUP_AND_REGISTER, 1,
- [bdi_setup_and_register() wants 2 args])
- ], [
- AC_MSG_RESULT(no)
-+
-+ dnl #
-+ dnl # 2.6.34 - 3.19, bdi_setup_and_register()
-+ dnl # takes 3 arguments.
-+ dnl #
- AC_MSG_CHECKING(
- [whether bdi_setup_and_register() wants 3 args])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-- #include <linux/backing-dev.h>
-- struct backing_dev_info bdi;
-- ], [
-- char *name = "bdi";
-- unsigned int cap = BDI_CAP_MAP_COPY;
-- int error __attribute__((unused)) =
-- bdi_setup_and_register(&bdi, name, cap);
-- ], [bdi_setup_and_register], [mm/backing-dev.c], [
-+ ZFS_LINUX_TEST_RESULT_SYMBOL(
-+ [bdi_setup_and_register_3args],
-+ [bdi_setup_and_register], [mm/backing-dev.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_3ARGS_BDI_SETUP_AND_REGISTER, 1,
- [bdi_setup_and_register() wants 3 args])
- ], [
-+ dnl #
-+ dnl # 2.6.32 - 2.6.33, bdi_setup_and_register()
-+ dnl # is not exported.
-+ dnl #
- AC_MSG_RESULT(no)
- ])
- ])
-diff --git a/config/kernel-bio-bvec-iter.m4 b/config/kernel-bio-bvec-iter.m4
-index 64c989386..f9a99cee6 100644
---- a/config/kernel-bio-bvec-iter.m4
-+++ b/config/kernel-bio-bvec-iter.m4
-@@ -3,18 +3,21 @@ dnl # 3.14 API change,
- dnl # Immutable biovecs. A number of fields of struct bio are moved to
- dnl # struct bvec_iter.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BIO_BVEC_ITER], [
-- AC_MSG_CHECKING([whether bio has bi_iter])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_BVEC_ITER], [
-+ ZFS_LINUX_TEST_SRC([bio_bvec_iter], [
- #include <linux/bio.h>
- ],[
- struct bio bio;
- bio.bi_iter.bi_sector = 0;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BIO_BVEC_ITER], [
-+ AC_MSG_CHECKING([whether bio has bi_iter])
-+ ZFS_LINUX_TEST_RESULT([bio_bvec_iter], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BIO_BVEC_ITER, 1, [bio has bi_iter])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
--
-diff --git a/config/kernel-bio-end-io-t-args.m4 b/config/kernel-bio-end-io-t-args.m4
-index 3c420cc0c..80a1fbeda 100644
---- a/config/kernel-bio-end-io-t-args.m4
-+++ b/config/kernel-bio-end-io-t-args.m4
-@@ -5,20 +5,21 @@ dnl # bio->bi_error. This also replaces bio->bi_flags value BIO_UPTODATE.
- dnl # Introduced by torvalds/linux@4246a0b63bd8f56a1469b12eafeb875b1041a451
- dnl # ("block: add a bi_error field to struct bio").
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BIO_END_IO_T_ARGS], [
-- AC_MSG_CHECKING([whether bio_end_io_t wants 1 arg])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS], [
-+ ZFS_LINUX_TEST_SRC([bio_end_io_t_args], [
- #include <linux/bio.h>
--
- void wanted_end_io(struct bio *bio) { return; }
--
- bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io;
-- ],[
-- ],[
-+ ], [])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BIO_END_IO_T_ARGS], [
-+ AC_MSG_CHECKING([whether bio_end_io_t wants 1 arg])
-+ ZFS_LINUX_TEST_RESULT([bio_end_io_t_args], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_1ARG_BIO_END_IO_T, 1,
-- [bio_end_io_t wants 1 arg])
-- ],[
-+ [bio_end_io_t wants 1 arg])
-+ ], [
- AC_MSG_RESULT(no)
- ])
- ])
-@@ -28,16 +29,19 @@ dnl # 4.13 API change
- dnl # The bio->bi_error field was replaced with bio->bi_status which is an
- dnl # enum which describes all possible error types.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_STATUS], [
-- AC_MSG_CHECKING([whether bio->bi_status exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_BI_STATUS], [
-+ ZFS_LINUX_TEST_SRC([bio_bi_status], [
- #include <linux/bio.h>
-- ],[
-+ ], [
- struct bio bio __attribute__ ((unused));
- blk_status_t status __attribute__ ((unused)) = BLK_STS_OK;
--
- bio.bi_status = status;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_STATUS], [
-+ AC_MSG_CHECKING([whether bio->bi_status exists])
-+ ZFS_LINUX_TEST_RESULT([bio_bi_status], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BIO_BI_STATUS, 1, [bio->bi_status exists])
- ],[
-diff --git a/config/kernel-bio-failfast.m4 b/config/kernel-bio-failfast.m4
-index cfbec0523..0c636f08c 100644
---- a/config/kernel-bio-failfast.m4
-+++ b/config/kernel-bio-failfast.m4
-@@ -3,37 +3,54 @@ dnl # Preferred interface for setting FAILFAST on a bio:
- dnl # 2.6.28-2.6.35: BIO_RW_FAILFAST_{DEV|TRANSPORT|DRIVER}
- dnl # >= 2.6.36: REQ_FAILFAST_{DEV|TRANSPORT|DRIVER}
- dnl #
--
--AC_DEFUN([ZFS_AC_KERNEL_BIO_FAILFAST_DTD], [
-- AC_MSG_CHECKING([whether BIO_RW_FAILFAST_* are defined])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_FAILFAST_DTD], [
-+ ZFS_LINUX_TEST_SRC([bio_failfast_dtd], [
- #include <linux/bio.h>
- ],[
- int flags __attribute__ ((unused));
- flags = ((1 << BIO_RW_FAILFAST_DEV) |
- (1 << BIO_RW_FAILFAST_TRANSPORT) |
- (1 << BIO_RW_FAILFAST_DRIVER));
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BIO_FAILFAST_DTD], [
-+ AC_MSG_CHECKING([whether BIO_RW_FAILFAST_* are defined])
-+ ZFS_LINUX_TEST_RESULT([bio_failfast_dtd], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BIO_RW_FAILFAST_DTD, 1,
-- [BIO_RW_FAILFAST_* are defined])
-+ [BIO_RW_FAILFAST_* are defined])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-
--AC_DEFUN([ZFS_AC_KERNEL_REQ_FAILFAST_MASK], [
-- AC_MSG_CHECKING([whether REQ_FAILFAST_MASK is defined])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_REQ_FAILFAST_MASK], [
-+ ZFS_LINUX_TEST_SRC([bio_failfast_mask], [
- #include <linux/bio.h>
- ],[
- int flags __attribute__ ((unused));
- flags = REQ_FAILFAST_MASK;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_REQ_FAILFAST_MASK], [
-+ AC_MSG_CHECKING([whether REQ_FAILFAST_MASK is defined])
-+ ZFS_LINUX_TEST_RESULT([bio_failfast_mask], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_REQ_FAILFAST_MASK, 1,
-- [REQ_FAILFAST_MASK is defined])
-+ [REQ_FAILFAST_MASK is defined])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_FAILFAST], [
-+ ZFS_AC_KERNEL_SRC_BIO_FAILFAST_DTD
-+ ZFS_AC_KERNEL_SRC_REQ_FAILFAST_MASK
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BIO_FAILFAST], [
-+ ZFS_AC_KERNEL_BIO_FAILFAST_DTD
-+ ZFS_AC_KERNEL_REQ_FAILFAST_MASK
-+])
-diff --git a/config/kernel-bio-op.m4 b/config/kernel-bio-op.m4
-index 8299e490c..1f2d23791 100644
---- a/config/kernel-bio-op.m4
-+++ b/config/kernel-bio-op.m4
-@@ -5,13 +5,43 @@ dnl # The bio_op() helper was introduced as a replacement for explicitly
- dnl # checking the bio->bi_rw flags. The following checks are used to
- dnl # detect if a specific operation is supported.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_DISCARD], [
-- AC_MSG_CHECKING([whether REQ_OP_DISCARD is defined])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_OPS], [
-+ ZFS_LINUX_TEST_SRC([req_op_discard], [
- #include <linux/blk_types.h>
- ],[
- int op __attribute__ ((unused)) = REQ_OP_DISCARD;
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([req_op_secure_erase], [
-+ #include <linux/blk_types.h>
- ],[
-+ int op __attribute__ ((unused)) = REQ_OP_SECURE_ERASE;
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([req_op_flush], [
-+ #include <linux/blk_types.h>
-+ ],[
-+ int op __attribute__ ((unused)) = REQ_OP_FLUSH;
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([bio_bi_opf], [
-+ #include <linux/bio.h>
-+ ],[
-+ struct bio bio __attribute__ ((unused));
-+ bio.bi_opf = 0;
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([bio_set_op_attrs], [
-+ #include <linux/bio.h>
-+ ],[
-+ struct bio *bio __attribute__ ((unused)) = NULL;
-+ bio_set_op_attrs(bio, 0, 0);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_DISCARD], [
-+ AC_MSG_CHECKING([whether REQ_OP_DISCARD is defined])
-+ ZFS_LINUX_TEST_RESULT([req_op_discard], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_REQ_OP_DISCARD, 1,
- [REQ_OP_DISCARD is defined])
-@@ -22,11 +52,7 @@ AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_DISCARD], [
-
- AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE], [
- AC_MSG_CHECKING([whether REQ_OP_SECURE_ERASE is defined])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/blk_types.h>
-- ],[
-- int op __attribute__ ((unused)) = REQ_OP_SECURE_ERASE;
-- ],[
-+ ZFS_LINUX_TEST_RESULT([req_op_secure_erase], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_REQ_OP_SECURE_ERASE, 1,
- [REQ_OP_SECURE_ERASE is defined])
-@@ -38,14 +64,9 @@ AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE], [
-
- AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_FLUSH], [
- AC_MSG_CHECKING([whether REQ_OP_FLUSH is defined])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/blk_types.h>
-- ],[
-- int op __attribute__ ((unused)) = REQ_OP_FLUSH;
-- ],[
-+ ZFS_LINUX_TEST_RESULT([req_op_flush], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_REQ_OP_FLUSH, 1,
-- [REQ_OP_FLUSH is defined])
-+ AC_DEFINE(HAVE_REQ_OP_FLUSH, 1, [REQ_OP_FLUSH is defined])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -53,12 +74,7 @@ AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_FLUSH], [
-
- AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_OPF], [
- AC_MSG_CHECKING([whether bio->bi_opf is defined])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/bio.h>
-- ],[
-- struct bio bio __attribute__ ((unused));
-- bio.bi_opf = 0;
-- ],[
-+ ZFS_LINUX_TEST_RESULT([bio_bi_opf], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BIO_BI_OPF, 1, [bio->bi_opf is defined])
- ],[
-@@ -68,13 +84,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_OPF], [
-
- AC_DEFUN([ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS], [
- AC_MSG_CHECKING([whether bio_set_op_attrs is available])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/bio.h>
-- ],[
-- struct bio *bio __attribute__ ((unused)) = NULL;
--
-- bio_set_op_attrs(bio, 0, 0);
-- ],[
-+ ZFS_LINUX_TEST_RESULT([bio_set_op_attrs], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BIO_SET_OP_ATTRS, 1,
- [bio_set_op_attrs is available])
-@@ -82,3 +92,11 @@ AC_DEFUN([ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS], [
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BIO_OPS], [
-+ ZFS_AC_KERNEL_REQ_OP_DISCARD
-+ ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE
-+ ZFS_AC_KERNEL_REQ_OP_FLUSH
-+ ZFS_AC_KERNEL_BIO_BI_OPF
-+ ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS
-+])
-diff --git a/config/kernel-bio-rw-barrier.m4 b/config/kernel-bio-rw-barrier.m4
-index bcf0f7ea0..f667d4884 100644
---- a/config/kernel-bio-rw-barrier.m4
-+++ b/config/kernel-bio-rw-barrier.m4
-@@ -3,20 +3,25 @@ dnl # Interface for issuing a discard bio:
- dnl # 2.6.28-2.6.35: BIO_RW_BARRIER
- dnl # 2.6.36-3.x: REQ_BARRIER
- dnl #
--
-+dnl #
- dnl # Since REQ_BARRIER is a preprocessor definition, there is no need for an
- dnl # autotools check for it. Also, REQ_BARRIER existed in the request layer
- dnl # until torvalds/linux@7b6d91daee5cac6402186ff224c3af39d79f4a0e unified the
- dnl # request layer and bio layer flags, so it would be wrong to assume that
- dnl # the APIs are mutually exclusive contrary to the typical case.
--AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_BARRIER], [
-- AC_MSG_CHECKING([whether BIO_RW_BARRIER is defined])
-- ZFS_LINUX_TRY_COMPILE([
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_RW_BARRIER], [
-+ ZFS_LINUX_TEST_SRC([bio_rw_barrier], [
- #include <linux/bio.h>
- ],[
- int flags __attribute__ ((unused));
- flags = BIO_RW_BARRIER;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_BARRIER], [
-+ AC_MSG_CHECKING([whether BIO_RW_BARRIER is defined])
-+ ZFS_LINUX_TEST_RESULT([bio_rw_barrier], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BIO_RW_BARRIER, 1, [BIO_RW_BARRIER is defined])
- ],[
-diff --git a/config/kernel-bio-rw-discard.m4 b/config/kernel-bio-rw-discard.m4
-index 0554b9a9d..34a89279c 100644
---- a/config/kernel-bio-rw-discard.m4
-+++ b/config/kernel-bio-rw-discard.m4
-@@ -3,20 +3,25 @@ dnl # Interface for issuing a discard bio:
- dnl # 2.6.28-2.6.35: BIO_RW_DISCARD
- dnl # 2.6.36-3.x: REQ_DISCARD
- dnl #
--
-+dnl #
- dnl # Since REQ_DISCARD is a preprocessor definition, there is no need for an
- dnl # autotools check for it. Also, REQ_DISCARD existed in the request layer
- dnl # until torvalds/linux@7b6d91daee5cac6402186ff224c3af39d79f4a0e unified the
- dnl # request layer and bio layer flags, so it would be wrong to assume that
- dnl # the APIs are mutually exclusive contrary to the typical case.
--AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_DISCARD], [
-- AC_MSG_CHECKING([whether BIO_RW_DISCARD is defined])
-- ZFS_LINUX_TRY_COMPILE([
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_RW_DISCARD], [
-+ ZFS_LINUX_TEST_SRC([bio_rw_discard], [
- #include <linux/bio.h>
- ],[
- int flags __attribute__ ((unused));
- flags = BIO_RW_DISCARD;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_DISCARD], [
-+ AC_MSG_CHECKING([whether BIO_RW_DISCARD is defined])
-+ ZFS_LINUX_TEST_RESULT([bio_rw_discard], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BIO_RW_DISCARD, 1, [BIO_RW_DISCARD is defined])
- ],[
-diff --git a/config/kernel-bio_set_dev.m4 b/config/kernel-bio_set_dev.m4
-index 71d47a893..b8e13f35a 100644
---- a/config/kernel-bio_set_dev.m4
-+++ b/config/kernel-bio_set_dev.m4
-@@ -3,51 +3,38 @@ dnl # Linux 4.14 API,
- dnl #
- dnl # The bio_set_dev() helper macro was introduced as part of the transition
- dnl # to have struct gendisk in struct bio.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV_MACRO], [
-- AC_MSG_CHECKING([whether bio_set_dev() exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/bio.h>
-- #include <linux/fs.h>
-- ],[
-- struct block_device *bdev = NULL;
-- struct bio *bio = NULL;
-- bio_set_dev(bio, bdev);
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_BIO_SET_DEV, 1, [bio_set_dev() exists])
-- ],[
-- AC_MSG_RESULT(no)
-- ])
--])
--
- dnl #
- dnl # Linux 5.0 API,
- dnl #
- dnl # The bio_set_dev() helper macro was updated to internally depend on
- dnl # bio_associate_blkg() symbol which is exported GPL-only.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV_GPL_ONLY], [
-- AC_MSG_CHECKING([whether bio_set_dev() is GPL-only])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/module.h>
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SET_DEV], [
-+ ZFS_LINUX_TEST_SRC([bio_set_dev], [
- #include <linux/bio.h>
- #include <linux/fs.h>
-- MODULE_LICENSE("$ZFS_META_LICENSE");
- ],[
- struct block_device *bdev = NULL;
- struct bio *bio = NULL;
- bio_set_dev(bio, bdev);
-- ],[
-- AC_MSG_RESULT(no)
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_BIO_SET_DEV_GPL_ONLY, 1,
-- [bio_set_dev() GPL-only])
-- ])
-+ ], [], [$ZFS_META_LICENSE])
- ])
-
- AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV], [
-- ZFS_AC_KERNEL_BIO_SET_DEV_MACRO
-- ZFS_AC_KERNEL_BIO_SET_DEV_GPL_ONLY
-+ AC_MSG_CHECKING([whether bio_set_dev() is available])
-+ ZFS_LINUX_TEST_RESULT([bio_set_dev], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_BIO_SET_DEV, 1, [bio_set_dev() is available])
-+
-+ AC_MSG_CHECKING([whether bio_set_dev() is GPL-only])
-+ ZFS_LINUX_TEST_RESULT([bio_set_dev_license], [
-+ AC_MSG_RESULT(no)
-+ ],[
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_BIO_SET_DEV_GPL_ONLY, 1,
-+ [bio_set_dev() GPL-only])
-+ ])
-+ ],[
-+ AC_MSG_RESULT(no)
-+ ])
- ])
-diff --git a/config/kernel-blk-queue-bdi.m4 b/config/kernel-blk-queue-bdi.m4
-index 816471166..28241c494 100644
---- a/config/kernel-blk-queue-bdi.m4
-+++ b/config/kernel-blk-queue-bdi.m4
-@@ -2,15 +2,19 @@ dnl #
- dnl # 2.6.32 - 4.11, statically allocated bdi in request_queue
- dnl # 4.12 - x.y, dynamically allocated bdi in request_queue
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [
-- AC_MSG_CHECKING([whether blk_queue bdi is dynamic])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI], [
-+ ZFS_LINUX_TEST_SRC([blk_queue_bdi], [
- #include <linux/blkdev.h>
- ],[
- struct request_queue q;
- struct backing_dev_info bdi;
- q.backing_dev_info = &bdi;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [
-+ AC_MSG_CHECKING([whether blk_queue bdi is dynamic])
-+ ZFS_LINUX_TEST_RESULT([blk_queue_bdi], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_BDI_DYNAMIC, 1,
- [blk queue backing_dev_info is dynamic])
-diff --git a/config/kernel-blk-queue-discard.m4 b/config/kernel-blk-queue-discard.m4
-index addbba814..85a29356d 100644
---- a/config/kernel-blk-queue-discard.m4
-+++ b/config/kernel-blk-queue-discard.m4
-@@ -2,16 +2,19 @@ dnl #
- dnl # 2.6.32 - 4.x API,
- dnl # blk_queue_discard()
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISCARD], [
-- AC_MSG_CHECKING([whether blk_queue_discard() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [
-+ ZFS_LINUX_TEST_SRC([blk_queue_discard], [
- #include <linux/blkdev.h>
- ],[
- struct request_queue *q __attribute__ ((unused)) = NULL;
- int value __attribute__ ((unused));
--
- value = blk_queue_discard(q);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISCARD], [
-+ AC_MSG_CHECKING([whether blk_queue_discard() is available])
-+ ZFS_LINUX_TEST_RESULT([blk_queue_discard], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_DISCARD, 1,
- [blk_queue_discard() is available])
-@@ -30,16 +33,27 @@ dnl #
- dnl # 2.6.x - 2.6.35 API,
- dnl # Unsupported by kernel
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
-- AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE], [
-+ ZFS_LINUX_TEST_SRC([blk_queue_secure_erase], [
- #include <linux/blkdev.h>
- ],[
- struct request_queue *q __attribute__ ((unused)) = NULL;
- int value __attribute__ ((unused));
--
- value = blk_queue_secure_erase(q);
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([blk_queue_secdiscard], [
-+ #include <linux/blkdev.h>
- ],[
-+ struct request_queue *q __attribute__ ((unused)) = NULL;
-+ int value __attribute__ ((unused));
-+ value = blk_queue_secdiscard(q);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
-+ AC_MSG_CHECKING([whether blk_queue_secure_erase() is available])
-+ ZFS_LINUX_TEST_RESULT([blk_queue_secure_erase], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_SECURE_ERASE, 1,
- [blk_queue_secure_erase() is available])
-@@ -47,14 +61,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [
- AC_MSG_RESULT(no)
-
- AC_MSG_CHECKING([whether blk_queue_secdiscard() is available])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/blkdev.h>
-- ],[
-- struct request_queue *q __attribute__ ((unused)) = NULL;
-- int value __attribute__ ((unused));
--
-- value = blk_queue_secdiscard(q);
-- ],[
-+ ZFS_LINUX_TEST_RESULT([blk_queue_secdiscard], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_SECDISCARD, 1,
- [blk_queue_secdiscard() is available])
-diff --git a/config/kernel-blk-queue-flags.m4 b/config/kernel-blk-queue-flags.m4
-index b570245c7..9d4dfc159 100644
---- a/config/kernel-blk-queue-flags.m4
-+++ b/config/kernel-blk-queue-flags.m4
-@@ -3,36 +3,54 @@ dnl # API change
- dnl # https://github.com/torvalds/linux/commit/8814ce8
- dnl # Introduction of blk_queue_flag_set and blk_queue_flag_clear
- dnl #
--
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET], [
-- AC_MSG_CHECKING([whether blk_queue_flag_set() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET], [
-+ ZFS_LINUX_TEST_SRC([blk_queue_flag_set], [
- #include <linux/kernel.h>
- #include <linux/blkdev.h>
- ],[
- struct request_queue *q = NULL;
- blk_queue_flag_set(0, q);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET], [
-+ AC_MSG_CHECKING([whether blk_queue_flag_set() exists])
-+ ZFS_LINUX_TEST_RESULT([blk_queue_flag_set], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_BLK_QUEUE_FLAG_SET, 1, [blk_queue_flag_set() exists])
-+ AC_DEFINE(HAVE_BLK_QUEUE_FLAG_SET, 1,
-+ [blk_queue_flag_set() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR], [
-- AC_MSG_CHECKING([whether blk_queue_flag_clear() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_CLEAR], [
-+ ZFS_LINUX_TEST_SRC([blk_queue_flag_clear], [
- #include <linux/kernel.h>
- #include <linux/blkdev.h>
- ],[
- struct request_queue *q = NULL;
- blk_queue_flag_clear(0, q);
-- ],[
-+ ])
-+])
-
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR], [
-+ AC_MSG_CHECKING([whether blk_queue_flag_clear() exists])
-+ ZFS_LINUX_TEST_RESULT([blk_queue_flag_clear], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_BLK_QUEUE_FLAG_CLEAR, 1, [blk_queue_flag_clear() exists])
-+ AC_DEFINE(HAVE_BLK_QUEUE_FLAG_CLEAR, 1,
-+ [blk_queue_flag_clear() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAGS], [
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_CLEAR
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAGS], [
-+ ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET
-+ ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR
-+])
-diff --git a/config/kernel-blk-queue-flush.m4 b/config/kernel-blk-queue-flush.m4
-index 1baab83a4..b546d9400 100644
---- a/config/kernel-blk-queue-flush.m4
-+++ b/config/kernel-blk-queue-flush.m4
-@@ -9,35 +9,37 @@ dnl # there we implement our own compatibility function, otherwise
- dnl # we use the function. The hope is that long term this function
- dnl # will be opened up.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
-- AC_MSG_CHECKING([whether blk_queue_flush() is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLUSH], [
-+ ZFS_LINUX_TEST_SRC([blk_queue_flush], [
- #include <linux/blkdev.h>
-- ],[
-+ ], [
- struct request_queue *q = NULL;
- (void) blk_queue_flush(q, REQ_FLUSH);
-- ],[
-+ ], [$NO_UNUSED_BUT_SET_VARIABLE], [$ZFS_META_LICENSE])
-+
-+ ZFS_LINUX_TEST_SRC([blk_queue_write_cache], [
-+ #include <linux/kernel.h>
-+ #include <linux/blkdev.h>
-+ ], [
-+ struct request_queue *q = NULL;
-+ blk_queue_write_cache(q, true, true);
-+ ], [$NO_UNUSED_BUT_SET_VARIABLE], [$ZFS_META_LICENSE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
-+ AC_MSG_CHECKING([whether blk_queue_flush() is available])
-+ ZFS_LINUX_TEST_RESULT([blk_queue_flush], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1,
-- [blk_queue_flush() is available])
-+ [blk_queue_flush() is available])
-
- AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/module.h>
-- #include <linux/blkdev.h>
--
-- MODULE_LICENSE("$ZFS_META_LICENSE");
-- ],[
-- struct request_queue *q = NULL;
-- (void) blk_queue_flush(q, REQ_FLUSH);
-- ],[
-+ ZFS_LINUX_TEST_RESULT([blk_queue_flush_license], [
- AC_MSG_RESULT(no)
- ],[
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
-- [blk_queue_flush() is GPL-only])
-+ [blk_queue_flush() is GPL-only])
- ])
- ],[
- AC_MSG_RESULT(no)
-@@ -48,38 +50,20 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
- dnl # Replace blk_queue_flush with blk_queue_write_cache
- dnl #
- AC_MSG_CHECKING([whether blk_queue_write_cache() exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/kernel.h>
-- #include <linux/blkdev.h>
--
-- ],[
-- struct request_queue *q = NULL;
-- blk_queue_write_cache(q, true, true);
-- ],[
-+ ZFS_LINUX_TEST_RESULT([blk_queue_write_cache], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE, 1,
-- [blk_queue_write_cache() exists])
-+ [blk_queue_write_cache() exists])
-
- AC_MSG_CHECKING([whether blk_queue_write_cache() is GPL-only])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/kernel.h>
-- #include <linux/module.h>
-- #include <linux/blkdev.h>
--
-- MODULE_LICENSE("$ZFS_META_LICENSE");
-- ],[
-- struct request_queue *q = NULL;
-- blk_queue_write_cache(q, true, true);
-- ],[
-+ ZFS_LINUX_TEST_RESULT([blk_queue_write_cache_license], [
- AC_MSG_RESULT(no)
- ],[
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY, 1,
-- [blk_queue_write_cache() is GPL-only])
-+ [blk_queue_write_cache() is GPL-only])
- ])
- ],[
- AC_MSG_RESULT(no)
- ])
--
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-blk-queue-max-hw-sectors.m4 b/config/kernel-blk-queue-max-hw-sectors.m4
-index 2f5515dc6..7387f84de 100644
---- a/config/kernel-blk-queue-max-hw-sectors.m4
-+++ b/config/kernel-blk-queue-max-hw-sectors.m4
-@@ -2,21 +2,22 @@ dnl #
- dnl # 2.6.34 API change
- dnl # blk_queue_max_hw_sectors() replaces blk_queue_max_sectors().
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS], [
-- AC_MSG_CHECKING([whether blk_queue_max_hw_sectors() is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_HW_SECTORS], [
-+ ZFS_LINUX_TEST_SRC([blk_queue_max_hw_sectors], [
- #include <linux/blkdev.h>
-- ],[
-+ ], [
- struct request_queue *q = NULL;
- (void) blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
-- ],[
-+ ], [$NO_UNUSED_BUT_SET_VARIABLE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS], [
-+ AC_MSG_CHECKING([whether blk_queue_max_hw_sectors() is available])
-+ ZFS_LINUX_TEST_RESULT([blk_queue_max_hw_sectors], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_MAX_HW_SECTORS, 1,
-- [blk_queue_max_hw_sectors() is available])
-+ [blk_queue_max_hw_sectors() is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-blk-queue-max-segments.m4 b/config/kernel-blk-queue-max-segments.m4
-index b2a40423a..1e4092df9 100644
---- a/config/kernel-blk-queue-max-segments.m4
-+++ b/config/kernel-blk-queue-max-segments.m4
-@@ -3,21 +3,22 @@ dnl # 2.6.34 API change
- dnl # blk_queue_max_segments() consolidates blk_queue_max_hw_segments()
- dnl # and blk_queue_max_phys_segments().
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
-- AC_MSG_CHECKING([whether blk_queue_max_segments() is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_SEGMENTS], [
-+ ZFS_LINUX_TEST_SRC([blk_queue_max_segments], [
- #include <linux/blkdev.h>
-- ],[
-+ ], [
- struct request_queue *q = NULL;
- (void) blk_queue_max_segments(q, BLK_MAX_SEGMENTS);
-- ],[
-+ ], [$NO_UNUSED_BUT_SET_VARIABLE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [
-+ AC_MSG_CHECKING([whether blk_queue_max_segments() is available])
-+ ZFS_LINUX_TEST_RESULT([blk_queue_max_segments], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_MAX_SEGMENTS, 1,
-- [blk_queue_max_segments() is available])
-- ],[
-+ [blk_queue_max_segments() is available])
-+ ], [
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-blk-queue-unplug.m4 b/config/kernel-blk-queue-unplug.m4
-index 075fbccd1..f5d1814b8 100644
---- a/config/kernel-blk-queue-unplug.m4
-+++ b/config/kernel-blk-queue-unplug.m4
-@@ -2,43 +2,53 @@ dnl #
- dnl # 2.6.32-2.6.35 API - The BIO_RW_UNPLUG enum can be used as a hint
- dnl # to unplug the queue.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG], [
-- AC_MSG_CHECKING([whether the BIO_RW_UNPLUG enum is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_RW_UNPLUG], [
-+ ZFS_LINUX_TEST_SRC([blk_queue_bio_rw_unplug], [
- #include <linux/blkdev.h>
- ],[
-- extern enum bio_rw_flags rw;
-+ enum bio_rw_flags rw __attribute__ ((unused)) = BIO_RW_UNPLUG;
-+ ])
-+])
-
-- rw = BIO_RW_UNPLUG;
-- ],[
-+AC_DEFUN([ZFS_AC_KERNEL_BIO_RW_UNPLUG], [
-+ AC_MSG_CHECKING([whether the BIO_RW_UNPLUG enum is available])
-+ ZFS_LINUX_TEST_RESULT([blk_queue_bio_rw_unplug], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG, 1,
-- [BIO_RW_UNPLUG is available])
-+ [BIO_RW_UNPLUG is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-
--AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BLK_PLUG], [
-- AC_MSG_CHECKING([whether struct blk_plug is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_PLUG], [
-+ ZFS_LINUX_TEST_SRC([blk_plug], [
- #include <linux/blkdev.h>
- ],[
-- struct blk_plug plug;
-+ struct blk_plug plug __attribute__ ((unused));
-
- blk_start_plug(&plug);
- blk_finish_plug(&plug);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_PLUG], [
-+ AC_MSG_CHECKING([whether struct blk_plug is available])
-+ ZFS_LINUX_TEST_RESULT([blk_plug], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLK_QUEUE_HAVE_BLK_PLUG, 1,
-- [struct blk_plug is available])
-+ [struct blk_plug is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG], [
-+ ZFS_AC_KERNEL_SRC_BIO_RW_UNPLUG
-+ ZFS_AC_KERNEL_SRC_BLK_PLUG
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_PLUG], [
-+ ZFS_AC_KERNEL_BIO_RW_UNPLUG
-+ ZFS_AC_KERNEL_BLK_PLUG
- ])
-diff --git a/config/kernel-blkdev-get-by-path.m4 b/config/kernel-blkdev-get-by-path.m4
-index 40ecc06b6..fb0cea6af 100644
---- a/config/kernel-blkdev-get-by-path.m4
-+++ b/config/kernel-blkdev-get-by-path.m4
-@@ -3,16 +3,21 @@ dnl # 2.6.38 API change
- dnl # open_bdev_exclusive() changed to blkdev_get_by_path()
- dnl # close_bdev_exclusive() changed to blkdev_put()
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH],
-- [AC_MSG_CHECKING([whether blkdev_get_by_path() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH], [
-+ ZFS_LINUX_TEST_SRC([blkdev_get_by_path], [
- #include <linux/fs.h>
- ], [
- blkdev_get_by_path(NULL, 0, NULL);
-- ], [blkdev_get_by_path], [fs/block_dev.c], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
-+ AC_MSG_CHECKING([whether blkdev_get_by_path() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([blkdev_get_by_path],
-+ [blkdev_get_by_path], [fs/block_dev.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLKDEV_GET_BY_PATH, 1,
-- [blkdev_get_by_path() is available])
-+ [blkdev_get_by_path() is available])
- ], [
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-blkdev-reread-part.m4 b/config/kernel-blkdev-reread-part.m4
-index 5664769a3..1bf1e7c3a 100644
---- a/config/kernel-blkdev-reread-part.m4
-+++ b/config/kernel-blkdev-reread-part.m4
-@@ -2,16 +2,20 @@ dnl #
- dnl # 4.1 API, exported blkdev_reread_part() symbol, backported to the
- dnl # 3.10.0 CentOS 7.x enterprise kernels.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_REREAD_PART], [
-- AC_MSG_CHECKING([whether blkdev_reread_part() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART], [
-+ ZFS_LINUX_TEST_SRC([blkdev_reread_part], [
- #include <linux/fs.h>
- ], [
- struct block_device *bdev = NULL;
- int error;
-
- error = blkdev_reread_part(bdev);
-- ], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_REREAD_PART], [
-+ AC_MSG_CHECKING([whether blkdev_reread_part() is available])
-+ ZFS_LINUX_TEST_RESULT([blkdev_reread_part], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLKDEV_REREAD_PART, 1,
- [blkdev_reread_part() is available])
-diff --git a/config/kernel-block-device-operations.m4 b/config/kernel-block-device-operations.m4
-index 5f2811c15..c3d5eec52 100644
---- a/config/kernel-block-device-operations.m4
-+++ b/config/kernel-block-device-operations.m4
-@@ -1,11 +1,8 @@
- dnl #
- dnl # 2.6.38 API change
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
-- AC_MSG_CHECKING([whether bops->check_events() exists])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
-+ ZFS_LINUX_TEST_SRC([block_device_operations_check_events], [
- #include <linux/blkdev.h>
-
- unsigned int blk_check_events(struct gendisk *disk,
-@@ -15,25 +12,25 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
- bops __attribute__ ((unused)) = {
- .check_events = blk_check_events,
- };
-- ],[
-- ],[
-+ ], [], [$NO_UNUSED_BUT_SET_VARIABLE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
-+ AC_MSG_CHECKING([whether bops->check_events() exists])
-+ ZFS_LINUX_TEST_RESULT([block_device_operations_check_events], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS, 1,
- [bops->check_events() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-
- dnl #
- dnl # 3.10.x API change
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
-- AC_MSG_CHECKING([whether bops->release() is void])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
-+ ZFS_LINUX_TEST_SRC([block_device_operations_release_void], [
- #include <linux/blkdev.h>
-
- void blk_release(struct gendisk *g, fmode_t mode) { return; }
-@@ -45,13 +42,26 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
- .ioctl = NULL,
- .compat_ioctl = NULL,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT(void)
-+ ], [], [$NO_UNUSED_BUT_SET_VARIABLE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
-+ AC_MSG_CHECKING([whether bops->release() is void])
-+ ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [
-+ AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID, 1,
- [bops->release() returns void])
- ],[
-- AC_MSG_RESULT(int)
-+ AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [
-+ ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
-+ ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS], [
-+ ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
-+ ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
- ])
-diff --git a/config/kernel-clear-inode.m4 b/config/kernel-clear-inode.m4
-index 8d880fcd8..3f454d7ec 100644
---- a/config/kernel-clear-inode.m4
-+++ b/config/kernel-clear-inode.m4
-@@ -19,13 +19,18 @@ dnl # Therefore, to ensure we have the correct API we only allow the
- dnl # clear_inode() compatibility code to be defined iff the evict_inode()
- dnl # functionality is also detected.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CLEAR_INODE],
-- [AC_MSG_CHECKING([whether clear_inode() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CLEAR_INODE], [
-+ ZFS_LINUX_TEST_SRC([clear_inode], [
- #include <linux/fs.h>
- ], [
- clear_inode(NULL);
-- ], [clear_inode], [fs/inode.c], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CLEAR_INODE], [
-+ AC_MSG_CHECKING([whether clear_inode() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([clear_inode],
-+ [clear_inode], [fs/inode.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_CLEAR_INODE, 1, [clear_inode() is available])
- ], [
-diff --git a/config/kernel-commit-metadata.m4 b/config/kernel-commit-metadata.m4
-index b66a16fd2..9bc3b6622 100644
---- a/config/kernel-commit-metadata.m4
-+++ b/config/kernel-commit-metadata.m4
-@@ -4,19 +4,22 @@ dnl # Added eops->commit_metadata() callback to allow the underlying
- dnl # filesystem to determine the most efficient way to commit the inode.
- dnl # Prior to this the nfs server would issue an explicit fsync().
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_COMMIT_METADATA], [
-- AC_MSG_CHECKING([whether eops->commit_metadata() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_COMMIT_METADATA], [
-+ ZFS_LINUX_TEST_SRC([export_operations_commit_metadata], [
- #include <linux/exportfs.h>
- int commit_metadata(struct inode *inode) { return 0; }
- static struct export_operations eops __attribute__ ((unused))={
- .commit_metadata = commit_metadata,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_COMMIT_METADATA], [
-+ AC_MSG_CHECKING([whether eops->commit_metadata() exists])
-+ ZFS_LINUX_TEST_RESULT([export_operations_commit_metadata], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_COMMIT_METADATA, 1,
-- [eops->commit_metadata() exists])
-+ [eops->commit_metadata() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-config-defined.m4 b/config/kernel-config-defined.m4
-new file mode 100644
-index 000000000..0ee4231cc
---- /dev/null
-+++ b/config/kernel-config-defined.m4
-@@ -0,0 +1,183 @@
-+dnl #
-+dnl # Certain kernel build options are not supported. These must be
-+dnl # detected at configure time and cause a build failure. Otherwise
-+dnl # modules may be successfully built that behave incorrectly.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEFINED], [
-+ AS_IF([test "x$cross_compiling" != xyes], [
-+ AC_RUN_IFELSE([
-+ AC_LANG_PROGRAM([
-+ #include "$LINUX/include/linux/license.h"
-+ ], [
-+ return !license_is_gpl_compatible(
-+ "$ZFS_META_LICENSE");
-+ ])
-+ ], [
-+ AC_DEFINE([ZFS_IS_GPL_COMPATIBLE], [1],
-+ [Define to 1 if GPL-only symbols can be used])
-+ ], [
-+ ])
-+ ])
-+
-+ ZFS_AC_KERNEL_SRC_CONFIG_THREAD_SIZE
-+ ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC
-+ ZFS_AC_KERNEL_SRC_CONFIG_TRIM_UNUSED_KSYMS
-+ ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_INFLATE
-+ ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE
-+
-+ AC_MSG_CHECKING([for kernel config option compatibility])
-+ ZFS_LINUX_TEST_COMPILE_ALL([config])
-+ AC_MSG_RESULT([done])
-+
-+ ZFS_AC_KERNEL_CONFIG_THREAD_SIZE
-+ ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC
-+ ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS
-+ ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE
-+ ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE
-+])
-+
-+dnl #
-+dnl # Check configured THREAD_SIZE
-+dnl #
-+dnl # The stack size will vary by architecture, but as of Linux 3.15 on x86_64
-+dnl # the default thread stack size was increased to 16K from 8K. Therefore,
-+dnl # on newer kernels and some architectures stack usage optimizations can be
-+dnl # conditionally applied to improve performance without negatively impacting
-+dnl # stability.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_THREAD_SIZE], [
-+ ZFS_LINUX_TEST_SRC([config_thread_size], [
-+ #include <linux/module.h>
-+ ],[
-+ #if (THREAD_SIZE < 16384)
-+ #error "THREAD_SIZE is less than 16K"
-+ #endif
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CONFIG_THREAD_SIZE], [
-+ AC_MSG_CHECKING([whether kernel was built with 16K or larger stacks])
-+ ZFS_LINUX_TEST_RESULT([config_thread_size], [
-+ AC_MSG_RESULT([yes])
-+ AC_DEFINE(HAVE_LARGE_STACKS, 1, [kernel has large stacks])
-+ ],[
-+ AC_MSG_RESULT([no])
-+ ])
-+])
-+
-+dnl #
-+dnl # Check CONFIG_DEBUG_LOCK_ALLOC
-+dnl #
-+dnl # This is typically only set for debug kernels because it comes with
-+dnl # a performance penalty. However, when it is set it maps the non-GPL
-+dnl # symbol mutex_lock() to the GPL-only mutex_lock_nested() symbol.
-+dnl # This will cause a failure at link time which we'd rather know about
-+dnl # at compile time.
-+dnl #
-+dnl # Since we plan to pursue making mutex_lock_nested() a non-GPL symbol
-+dnl # with the upstream community we add a check to detect this case.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC], [
-+ ZFS_LINUX_TEST_SRC([config_debug_lock_alloc], [
-+ #include <linux/mutex.h>
-+ ],[
-+ struct mutex lock;
-+
-+ mutex_init(&lock);
-+ mutex_lock(&lock);
-+ mutex_unlock(&lock);
-+ ], [], [$ZFS_META_LICENSE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [
-+ AC_MSG_CHECKING([whether mutex_lock() is GPL-only])
-+ ZFS_LINUX_TEST_RESULT([config_debug_lock_alloc], [
-+ AC_MSG_RESULT(no)
-+ ],[
-+ AC_MSG_RESULT(yes)
-+ AC_MSG_ERROR([
-+ *** Kernel built with CONFIG_DEBUG_LOCK_ALLOC which is incompatible
-+ *** with the CDDL license and will prevent the module linking stage
-+ *** from succeeding. You must rebuild your kernel without this
-+ *** option enabled.])
-+ ])
-+])
-+
-+dnl #
-+dnl # Check CONFIG_TRIM_UNUSED_KSYMS
-+dnl #
-+dnl # Verify the kernel has CONFIG_TRIM_UNUSED_KSYMS disabled.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_TRIM_UNUSED_KSYMS], [
-+ ZFS_LINUX_TEST_SRC([config_trim_unusued_ksyms], [
-+ #if defined(CONFIG_TRIM_UNUSED_KSYMS)
-+ #error CONFIG_TRIM_UNUSED_KSYMS not defined
-+ #endif
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS], [
-+ AC_MSG_CHECKING([whether CONFIG_TRIM_UNUSED_KSYM is disabled])
-+ ZFS_LINUX_TEST_RESULT([config_trim_unusued_ksyms], [
-+ AC_MSG_RESULT([yes])
-+ ],[
-+ AC_MSG_RESULT([no])
-+ AS_IF([test "x$enable_linux_builtin" != xyes], [
-+ AC_MSG_ERROR([
-+ *** This kernel has unused symbols trimming enabled, please disable.
-+ *** Rebuild the kernel with CONFIG_TRIM_UNUSED_KSYMS=n set.])
-+ ])
-+ ])
-+])
-+
-+dnl #
-+dnl # Check CONFIG_ZLIB_INFLATE
-+dnl #
-+dnl # Verify the kernel has CONFIG_ZLIB_INFLATE support enabled.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_INFLATE], [
-+ ZFS_LINUX_TEST_SRC([config_zlib_inflate], [
-+ #if !defined(CONFIG_ZLIB_INFLATE) && \
-+ !defined(CONFIG_ZLIB_INFLATE_MODULE)
-+ #error CONFIG_ZLIB_INFLATE not defined
-+ #endif
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE], [
-+ AC_MSG_CHECKING([whether CONFIG_ZLIB_INFLATE is defined])
-+ ZFS_LINUX_TEST_RESULT([config_zlib_inflate], [
-+ AC_MSG_RESULT([yes])
-+ ],[
-+ AC_MSG_RESULT([no])
-+ AC_MSG_ERROR([
-+ *** This kernel does not include the required zlib inflate support.
-+ *** Rebuild the kernel with CONFIG_ZLIB_INFLATE=y|m set.])
-+ ])
-+])
-+
-+dnl #
-+dnl # Check CONFIG_ZLIB_DEFLATE
-+dnl #
-+dnl # Verify the kernel has CONFIG_ZLIB_DEFLATE support enabled.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE], [
-+ ZFS_LINUX_TEST_SRC([config_zlib_deflate], [
-+ #if !defined(CONFIG_ZLIB_DEFLATE) && \
-+ !defined(CONFIG_ZLIB_DEFLATE_MODULE)
-+ #error CONFIG_ZLIB_DEFLATE not defined
-+ #endif
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE], [
-+ AC_MSG_CHECKING([whether CONFIG_ZLIB_DEFLATE is defined])
-+ ZFS_LINUX_TEST_RESULT([config_zlib_deflate], [
-+ AC_MSG_RESULT([yes])
-+ ],[
-+ AC_MSG_RESULT([no])
-+ AC_MSG_ERROR([
-+ *** This kernel does not include the required zlib deflate support.
-+ *** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set.])
-+ ])
-+])
-diff --git a/config/kernel-create-nameidata.m4 b/config/kernel-create-nameidata.m4
-index d4c155c57..c43ca5b85 100644
---- a/config/kernel-create-nameidata.m4
-+++ b/config/kernel-create-nameidata.m4
-@@ -1,9 +1,8 @@
- dnl #
- dnl # 3.6 API change
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CREATE_NAMEIDATA], [
-- AC_MSG_CHECKING([whether iops->create() passes nameidata])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_NAMEIDATA], [
-+ ZFS_LINUX_TEST_SRC([create_nameidata], [
- #include <linux/fs.h>
- #include <linux/sched.h>
-
-@@ -19,11 +18,15 @@ AC_DEFUN([ZFS_AC_KERNEL_CREATE_NAMEIDATA], [
- iops __attribute__ ((unused)) = {
- .create = inode_create,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CREATE_NAMEIDATA], [
-+ AC_MSG_CHECKING([whether iops->create() passes nameidata])
-+ ZFS_LINUX_TEST_RESULT([create_nameidata], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_CREATE_NAMEIDATA, 1,
-- [iops->create() passes nameidata])
-+ [iops->create() passes nameidata])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-ctl-table-name.m4 b/config/kernel-ctl-table-name.m4
-index 3ce499968..16f2ad544 100644
---- a/config/kernel-ctl-table-name.m4
-+++ b/config/kernel-ctl-table-name.m4
-@@ -2,14 +2,18 @@ dnl #
- dnl # 2.6.33 API change,
- dnl # Removed .ctl_name from struct ctl_table.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CTL_NAME], [
-- AC_MSG_CHECKING([whether struct ctl_table has ctl_name])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CTL_NAME], [
-+ ZFS_LINUX_TEST_SRC([ctl_name], [
- #include <linux/sysctl.h>
- ],[
- struct ctl_table ctl __attribute__ ((unused));
- ctl.ctl_name = 0;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CTL_NAME], [
-+ AC_MSG_CHECKING([whether struct ctl_table has ctl_name])
-+ ZFS_LINUX_TEST_RESULT([ctl_name], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_CTL_NAME, 1, [struct ctl_table has ctl_name])
- ],[
-diff --git a/config/kernel-current-time.m4 b/config/kernel-current-time.m4
-index c7d5c9b52..3ceb5f63e 100644
---- a/config/kernel-current-time.m4
-+++ b/config/kernel-current-time.m4
-@@ -2,14 +2,19 @@ dnl #
- dnl # 4.9, current_time() added
- dnl # 4.18, return type changed from timespec to timespec64
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CURRENT_TIME],
-- [AC_MSG_CHECKING([whether current_time() exists])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_TIME], [
-+ ZFS_LINUX_TEST_SRC([current_time], [
- #include <linux/fs.h>
- ], [
- struct inode ip __attribute__ ((unused));
- ip.i_atime = current_time(&ip);
-- ], [current_time], [fs/inode.c], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CURRENT_TIME], [
-+ AC_MSG_CHECKING([whether current_time() exists])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([current_time],
-+ [current_time], [fs/inode.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_CURRENT_TIME, 1, [current_time() exists])
- ], [
-diff --git a/config/kernel-current_bio_tail.m4 b/config/kernel-current_bio_tail.m4
-index b72f21e8a..9dfc3e6e0 100644
---- a/config/kernel-current_bio_tail.m4
-+++ b/config/kernel-current_bio_tail.m4
-@@ -4,30 +4,36 @@ dnl # current->bio_tail and current->bio_list were struct bio pointers prior to
- dnl # Linux 2.6.34. They were refactored into a struct bio_list pointer called
- dnl # current->bio_list in Linux 2.6.34.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CURRENT_BIO_TAIL], [
-- AC_MSG_CHECKING([whether current->bio_tail exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_BIO_TAIL], [
-+ ZFS_LINUX_TEST_SRC([current_bio_tail], [
- #include <linux/sched.h>
-- ],[
-+ ], [
- current->bio_tail = (struct bio **) NULL;
-- ],[
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([current_bio_list], [
-+ #include <linux/sched.h>
-+ ], [
-+ current->bio_list = (struct bio_list *) NULL;
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CURRENT_BIO_TAIL], [
-+ AC_MSG_CHECKING([whether current->bio_tail exists])
-+ ZFS_LINUX_TEST_RESULT([current_bio_tail], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_CURRENT_BIO_TAIL, 1,
- [current->bio_tail exists])
- ],[
- AC_MSG_RESULT(no)
-+
- AC_MSG_CHECKING([whether current->bio_list exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/sched.h>
-- ],[
-- current->bio_list = (struct bio_list *) NULL;
-- ],[
-+ ZFS_LINUX_TEST_RESULT([current_bio_list], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_CURRENT_BIO_LIST, 1,
- [current->bio_list exists])
- ],[
-- AC_MSG_ERROR(no - Please file a bug report at
-- https://github.com/zfsonlinux/zfs/issues/new)
-+ ZFS_LINUX_TEST_ERROR([bio_list])
- ])
- ])
- ])
-diff --git a/config/kernel-d-make-root.m4 b/config/kernel-d-make-root.m4
-deleted file mode 100644
-index 9c2b73dcb..000000000
---- a/config/kernel-d-make-root.m4
-+++ /dev/null
-@@ -1,17 +0,0 @@
--dnl #
--dnl # 3.4.0 API change
--dnl # Added d_make_root() to replace previous d_alloc_root() function.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_D_MAKE_ROOT],
-- [AC_MSG_CHECKING([whether d_make_root() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-- #include <linux/dcache.h>
-- ], [
-- d_make_root(NULL);
-- ], [d_make_root], [fs/dcache.c], [
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_D_MAKE_ROOT, 1, [d_make_root() is available])
-- ], [
-- AC_MSG_RESULT(no)
-- ])
--])
-diff --git a/config/kernel-d-obtain-alias.m4 b/config/kernel-d-obtain-alias.m4
-deleted file mode 100644
-index 2b4b11ecc..000000000
---- a/config/kernel-d-obtain-alias.m4
-+++ /dev/null
-@@ -1,18 +0,0 @@
--dnl #
--dnl # 2.6.28 API change
--dnl # Added d_obtain_alias() helper function.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_D_OBTAIN_ALIAS],
-- [AC_MSG_CHECKING([whether d_obtain_alias() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-- #include <linux/dcache.h>
-- ], [
-- d_obtain_alias(NULL);
-- ], [d_obtain_alias], [fs/dcache.c], [
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_D_OBTAIN_ALIAS, 1,
-- [d_obtain_alias() is available])
-- ], [
-- AC_MSG_RESULT(no)
-- ])
--])
-diff --git a/config/kernel-d-prune-aliases.m4 b/config/kernel-d-prune-aliases.m4
-deleted file mode 100644
-index d9c521b1d..000000000
---- a/config/kernel-d-prune-aliases.m4
-+++ /dev/null
-@@ -1,19 +0,0 @@
--dnl #
--dnl # 2.6.12 API change
--dnl # d_prune_aliases() helper function available.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_D_PRUNE_ALIASES],
-- [AC_MSG_CHECKING([whether d_prune_aliases() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-- #include <linux/dcache.h>
-- ], [
-- struct inode *ip = NULL;
-- d_prune_aliases(ip);
-- ], [d_prune_aliases], [fs/dcache.c], [
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_D_PRUNE_ALIASES, 1,
-- [d_prune_aliases() is available])
-- ], [
-- AC_MSG_RESULT(no)
-- ])
--])
-diff --git a/config/kernel-declare-event-class.m4 b/config/kernel-declare-event-class.m4
-index 7867d7517..6c78ee858 100644
---- a/config/kernel-declare-event-class.m4
-+++ b/config/kernel-declare-event-class.m4
-@@ -2,13 +2,10 @@ dnl #
- dnl # Ensure the DECLARE_EVENT_CLASS macro is available to non-GPL modules.
- dnl #
- AC_DEFUN([ZFS_AC_KERNEL_DECLARE_EVENT_CLASS], [
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-I\$(src)"
--
- AC_MSG_CHECKING([whether DECLARE_EVENT_CLASS() is available])
- ZFS_LINUX_TRY_COMPILE_HEADER([
- #include <linux/module.h>
-- MODULE_LICENSE(ZFS_META_LICENSE);
-+ MODULE_LICENSE("$ZFS_META_LICENSE");
-
- #define CREATE_TRACE_POINTS
- #include "conftest.h"
-@@ -18,7 +15,7 @@ AC_DEFUN([ZFS_AC_KERNEL_DECLARE_EVENT_CLASS], [
- ],[
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_DECLARE_EVENT_CLASS, 1,
-- [DECLARE_EVENT_CLASS() is available])
-+ [DECLARE_EVENT_CLASS() is available])
- ],[
- AC_MSG_RESULT(no)
- ],[
-@@ -55,5 +52,4 @@ AC_DEFUN([ZFS_AC_KERNEL_DECLARE_EVENT_CLASS], [
- #define TRACE_INCLUDE_FILE conftest
- #include <trace/define_trace.h>
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-dentry-operations.m4 b/config/kernel-dentry-operations.m4
-index 61f5a27af..f943dad4c 100644
---- a/config/kernel-dentry-operations.m4
-+++ b/config/kernel-dentry-operations.m4
-@@ -1,9 +1,103 @@
-+dnl #
-+dnl # 3.4.0 API change
-+dnl # Added d_make_root() to replace previous d_alloc_root() function.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_D_MAKE_ROOT], [
-+ ZFS_LINUX_TEST_SRC([d_make_root], [
-+ #include <linux/dcache.h>
-+ ], [
-+ d_make_root(NULL);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_D_MAKE_ROOT], [
-+ AC_MSG_CHECKING([whether d_make_root() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([d_make_root],
-+ [d_make_root], [fs/dcache.c], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_D_MAKE_ROOT, 1, [d_make_root() is available])
-+ ], [
-+ AC_MSG_RESULT(no)
-+ ])
-+])
-+
-+dnl #
-+dnl # 2.6.28 API change
-+dnl # Added d_obtain_alias() helper function.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS], [
-+ ZFS_LINUX_TEST_SRC([d_obtain_alias], [
-+ #include <linux/dcache.h>
-+ ], [
-+ d_obtain_alias(NULL);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_D_OBTAIN_ALIAS], [
-+ AC_MSG_CHECKING([whether d_obtain_alias() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([d_obtain_alias],
-+ [d_obtain_alias], [fs/dcache.c], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_D_OBTAIN_ALIAS, 1,
-+ [d_obtain_alias() is available])
-+ ], [
-+ AC_MSG_RESULT(no)
-+ ])
-+])
-+
-+dnl #
-+dnl # 2.6.12 API change
-+dnl # d_prune_aliases() helper function available.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_D_PRUNE_ALIASES], [
-+ ZFS_LINUX_TEST_SRC([d_prune_aliases], [
-+ #include <linux/dcache.h>
-+ ], [
-+ struct inode *ip = NULL;
-+ d_prune_aliases(ip);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_D_PRUNE_ALIASES], [
-+ AC_MSG_CHECKING([whether d_prune_aliases() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([d_prune_aliases],
-+ [d_prune_aliases], [fs/dcache.c], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_D_PRUNE_ALIASES, 1,
-+ [d_prune_aliases() is available])
-+ ], [
-+ AC_MSG_RESULT(no)
-+ ])
-+])
-+
-+dnl #
-+dnl # 2.6.38 API change
-+dnl # Added d_set_d_op() helper function.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_D_SET_D_OP], [
-+ ZFS_LINUX_TEST_SRC([d_set_d_op], [
-+ #include <linux/dcache.h>
-+ ], [
-+ d_set_d_op(NULL, NULL);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP], [
-+ AC_MSG_CHECKING([whether d_set_d_op() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([d_set_d_op],
-+ [d_set_d_op], [fs/dcache.c], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_D_SET_D_OP, 1, [d_set_d_op() is available])
-+ ], [
-+ AC_MSG_RESULT(no)
-+ ])
-+])
-+
- dnl #
- dnl # 3.6 API change
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA], [
-- AC_MSG_CHECKING([whether dops->d_revalidate() takes struct nameidata])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_D_REVALIDATE_NAMEIDATA], [
-+ ZFS_LINUX_TEST_SRC([dentry_operations_revalidate], [
- #include <linux/dcache.h>
- #include <linux/sched.h>
-
-@@ -14,11 +108,15 @@ AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA], [
- dops __attribute__ ((unused)) = {
- .d_revalidate = revalidate,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA], [
-+ AC_MSG_CHECKING([whether dops->d_revalidate() takes struct nameidata])
-+ ZFS_LINUX_TEST_RESULT([dentry_operations_revalidate], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_D_REVALIDATE_NAMEIDATA, 1,
-- [dops->d_revalidate() operation takes nameidata])
-+ [dops->d_revalidate() operation takes nameidata])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -28,9 +126,8 @@ dnl #
- dnl # 2.6.30 API change
- dnl # The 'struct dentry_operations' was constified in the dentry structure.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS], [
-- AC_MSG_CHECKING([whether dentry uses const struct dentry_operations])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CONST_DENTRY_OPERATIONS], [
-+ ZFS_LINUX_TEST_SRC([dentry_operations_const], [
- #include <linux/dcache.h>
-
- const struct dentry_operations test_d_op = {
-@@ -38,32 +135,17 @@ AC_DEFUN([ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS], [
- };
- ],[
- struct dentry d __attribute__ ((unused));
--
- d.d_op = &test_d_op;
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_CONST_DENTRY_OPERATIONS, 1,
-- [dentry uses const struct dentry_operations])
-- ],[
-- AC_MSG_RESULT(no)
- ])
- ])
-
--dnl #
--dnl # 2.6.38 API change
--dnl # Added d_set_d_op() helper function.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP],
-- [AC_MSG_CHECKING([whether d_set_d_op() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-- #include <linux/dcache.h>
-- ], [
-- d_set_d_op(NULL, NULL);
-- ], [d_set_d_op], [fs/dcache.c], [
-+AC_DEFUN([ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS], [
-+ AC_MSG_CHECKING([whether dentry uses const struct dentry_operations])
-+ ZFS_LINUX_TEST_RESULT([dentry_operations_const], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_D_SET_D_OP, 1,
-- [d_set_d_op() is available])
-- ], [
-+ AC_DEFINE(HAVE_CONST_DENTRY_OPERATIONS, 1,
-+ [dentry uses const struct dentry_operations])
-+ ],[
- AC_MSG_RESULT(no)
- ])
- ])
-@@ -72,17 +154,41 @@ dnl #
- dnl # 2.6.38 API chage
- dnl # Added sb->s_d_op default dentry_operations member
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_S_D_OP],
-- [AC_MSG_CHECKING([whether super_block has s_d_op])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_S_D_OP], [
-+ ZFS_LINUX_TEST_SRC([super_block_s_d_op], [
- #include <linux/fs.h>
- ],[
- struct super_block sb __attribute__ ((unused));
- sb.s_d_op = NULL;
-- ], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_S_D_OP], [
-+ AC_MSG_CHECKING([whether super_block has s_d_op])
-+ ZFS_LINUX_TEST_RESULT([super_block_s_d_op], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_S_D_OP, 1, [struct super_block has s_d_op])
- ], [
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY], [
-+ ZFS_AC_KERNEL_SRC_D_MAKE_ROOT
-+ ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS
-+ ZFS_AC_KERNEL_SRC_D_PRUNE_ALIASES
-+ ZFS_AC_KERNEL_SRC_D_SET_D_OP
-+ ZFS_AC_KERNEL_SRC_D_REVALIDATE_NAMEIDATA
-+ ZFS_AC_KERNEL_SRC_CONST_DENTRY_OPERATIONS
-+ ZFS_AC_KERNEL_SRC_S_D_OP
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_DENTRY], [
-+ ZFS_AC_KERNEL_D_MAKE_ROOT
-+ ZFS_AC_KERNEL_D_OBTAIN_ALIAS
-+ ZFS_AC_KERNEL_D_PRUNE_ALIASES
-+ ZFS_AC_KERNEL_D_SET_D_OP
-+ ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA
-+ ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS
-+ ZFS_AC_KERNEL_S_D_OP
-+])
-diff --git a/config/kernel-dirty-inode.m4 b/config/kernel-dirty-inode.m4
-index ffd87bb14..dc7667fa4 100644
---- a/config/kernel-dirty-inode.m4
-+++ b/config/kernel-dirty-inode.m4
-@@ -4,9 +4,8 @@ dnl # The sops->dirty_inode() callbacks were updated to take a flags
- dnl # argument. This allows the greater control over whether the
- dnl # filesystem needs to push out a transaction or not.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS], [
-- AC_MSG_CHECKING([whether sops->dirty_inode() wants flags])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_DIRTY_INODE], [
-+ ZFS_LINUX_TEST_SRC([dirty_inode_with_flags], [
- #include <linux/fs.h>
-
- void dirty_inode(struct inode *a, int b) { return; }
-@@ -15,11 +14,15 @@ AC_DEFUN([ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS], [
- sops __attribute__ ((unused)) = {
- .dirty_inode = dirty_inode,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_DIRTY_INODE], [
-+ AC_MSG_CHECKING([whether sops->dirty_inode() wants flags])
-+ ZFS_LINUX_TEST_RESULT([dirty_inode_with_flags], [
- AC_MSG_RESULT([yes])
- AC_DEFINE(HAVE_DIRTY_INODE_WITH_FLAGS, 1,
-- [sops->dirty_inode() wants flags])
-+ [sops->dirty_inode() wants flags])
- ],[
- AC_MSG_RESULT([no])
- ])
-diff --git a/config/kernel-discard-granularity.m4 b/config/kernel-discard-granularity.m4
-index 2c677c909..c830d9aa9 100644
---- a/config/kernel-discard-granularity.m4
-+++ b/config/kernel-discard-granularity.m4
-@@ -2,18 +2,21 @@ dnl #
- dnl # 2.6.33 API change
- dnl # Discard granularity and alignment restrictions may now be set.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_DISCARD_GRANULARITY], [
-- AC_MSG_CHECKING([whether ql->discard_granularity is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_DISCARD_GRANULARITY], [
-+ ZFS_LINUX_TEST_SRC([discard_granularity], [
- #include <linux/blkdev.h>
- ],[
- struct queue_limits ql __attribute__ ((unused));
--
- ql.discard_granularity = 0;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_DISCARD_GRANULARITY], [
-+ AC_MSG_CHECKING([whether ql->discard_granularity is available])
-+ ZFS_LINUX_TEST_RESULT([discard_granularity], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_DISCARD_GRANULARITY, 1,
-- [ql->discard_granularity is available])
-+ [ql->discard_granularity is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-elevator-change.m4 b/config/kernel-elevator-change.m4
-index eba252579..3aa732040 100644
---- a/config/kernel-elevator-change.m4
-+++ b/config/kernel-elevator-change.m4
-@@ -2,24 +2,25 @@ dnl #
- dnl # 2.6.36 API, exported elevator_change() symbol
- dnl # 4.12 API, removed elevator_change() symbol
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_ELEVATOR_CHANGE], [
-- AC_MSG_CHECKING([whether elevator_change() is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_ELEVATOR_CHANGE], [
-+ ZFS_LINUX_TEST_SRC([elevator_change], [
- #include <linux/blkdev.h>
- #include <linux/elevator.h>
- ],[
-- int ret;
- struct request_queue *q = NULL;
- char *elevator = NULL;
-- ret = elevator_change(q, elevator);
-- ],[
-+ int error __attribute__ ((unused)) =
-+ elevator_change(q, elevator);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_ELEVATOR_CHANGE], [
-+ AC_MSG_CHECKING([whether elevator_change() is available])
-+ ZFS_LINUX_TEST_RESULT([elevator_change], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_ELEVATOR_CHANGE, 1,
-- [elevator_change() is available])
-+ [elevator_change() is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-encode-fh-inode.m4 b/config/kernel-encode-fh-inode.m4
-index 287f62a5e..9d4ba5f0f 100644
---- a/config/kernel-encode-fh-inode.m4
-+++ b/config/kernel-encode-fh-inode.m4
-@@ -4,20 +4,23 @@ dnl # torvalds/linux@b0b0382bb4904965a9e9fca77ad87514dfda0d1c changed the
- dnl # ->encode_fh() callback to pass the child inode and its parents inode
- dnl # rather than a dentry and a boolean saying whether we want the parent.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE], [
-- AC_MSG_CHECKING([whether eops->encode_fh() wants inode])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE], [
-+ ZFS_LINUX_TEST_SRC([export_operations_encode_fh], [
- #include <linux/exportfs.h>
- int encode_fh(struct inode *inode, __u32 *fh, int *max_len,
- struct inode *parent) { return 0; }
- static struct export_operations eops __attribute__ ((unused))={
- .encode_fh = encode_fh,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE], [
-+ AC_MSG_CHECKING([whether eops->encode_fh() wants inode])
-+ ZFS_LINUX_TEST_RESULT([export_operations_encode_fh], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_ENCODE_FH_WITH_INODE, 1,
-- [eops->encode_fh() wants child and parent inodes])
-+ [eops->encode_fh() wants child and parent inodes])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-evict-inode.m4 b/config/kernel-evict-inode.m4
-index 683cedb6d..cd91c6669 100644
---- a/config/kernel-evict-inode.m4
-+++ b/config/kernel-evict-inode.m4
-@@ -3,16 +3,19 @@ dnl # 2.6.36 API change
- dnl # The sops->delete_inode() and sops->clear_inode() callbacks have
- dnl # replaced by a single sops->evict_inode() callback.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_EVICT_INODE], [
-- AC_MSG_CHECKING([whether sops->evict_inode() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_EVICT_INODE], [
-+ ZFS_LINUX_TEST_SRC([evict_inode], [
- #include <linux/fs.h>
- void evict_inode (struct inode * t) { return; }
- static struct super_operations sops __attribute__ ((unused)) = {
- .evict_inode = evict_inode,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_EVICT_INODE], [
-+ AC_MSG_CHECKING([whether sops->evict_inode() exists])
-+ ZFS_LINUX_TEST_RESULT([evict_inode], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_EVICT_INODE, 1, [sops->evict_inode() exists])
- ],[
-diff --git a/config/kernel-fallocate-pax.m4 b/config/kernel-fallocate-pax.m4
-deleted file mode 100644
-index e8948be17..000000000
---- a/config/kernel-fallocate-pax.m4
-+++ /dev/null
-@@ -1,19 +0,0 @@
--dnl #
--dnl # PaX Linux 2.6.38 - 3.x API
--dnl #
--AC_DEFUN([ZFS_AC_PAX_KERNEL_FILE_FALLOCATE], [
-- AC_MSG_CHECKING([whether fops->fallocate() exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- ],[
-- long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
-- struct file_operations_no_const fops __attribute__ ((unused)) = {
-- .fallocate = fallocate,
-- };
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
-- ],[
-- AC_MSG_RESULT(no)
-- ])
--])
-diff --git a/config/kernel-fallocate.m4 b/config/kernel-fallocate.m4
-index 550906472..302957a6c 100644
---- a/config/kernel-fallocate.m4
-+++ b/config/kernel-fallocate.m4
-@@ -1,9 +1,11 @@
- dnl #
--dnl # Linux 2.6.38 - 3.x API
-+dnl # The fallocate callback was moved from the inode_operations
-+dnl # structure to the file_operations structure.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FILE_FALLOCATE], [
-- AC_MSG_CHECKING([whether fops->fallocate() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_FALLOCATE], [
-+
-+ dnl # Linux 2.6.38 - 3.x API
-+ ZFS_LINUX_TEST_SRC([file_fallocate], [
- #include <linux/fs.h>
-
- long test_fallocate(struct file *file, int mode,
-@@ -13,21 +15,10 @@ AC_DEFUN([ZFS_AC_KERNEL_FILE_FALLOCATE], [
- fops __attribute__ ((unused)) = {
- .fallocate = test_fallocate,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
-- ],[
-- AC_MSG_RESULT(no)
-- ])
--])
-+ ], [])
-
--dnl #
--dnl # Linux 2.6.x - 2.6.37 API
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_FALLOCATE], [
-- AC_MSG_CHECKING([whether iops->fallocate() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+ dnl # Linux 2.6.x - 2.6.37 API
-+ ZFS_LINUX_TEST_SRC([inode_fallocate], [
- #include <linux/fs.h>
-
- long test_fallocate(struct inode *inode, int mode,
-@@ -37,20 +28,23 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_FALLOCATE], [
- fops __attribute__ ((unused)) = {
- .fallocate = test_fallocate,
- };
-+ ], [])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_FALLOCATE], [
-+ AC_MSG_CHECKING([whether fops->fallocate() exists])
-+ ZFS_LINUX_TEST_RESULT([file_fallocate], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
- ],[
-- ],[
-+ AC_MSG_RESULT(no)
-+ ])
-+
-+ AC_MSG_CHECKING([whether iops->fallocate() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_fallocate], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_INODE_FALLOCATE, 1, [fops->fallocate() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
--
--dnl #
--dnl # The fallocate callback was moved from the inode_operations
--dnl # structure to the file_operations structure.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FALLOCATE], [
-- ZFS_AC_KERNEL_FILE_FALLOCATE
-- ZFS_AC_KERNEL_INODE_FALLOCATE
--])
-diff --git a/config/kernel-file-dentry.m4 b/config/kernel-file-dentry.m4
-index daf742ee1..9cb5869c3 100644
---- a/config/kernel-file-dentry.m4
-+++ b/config/kernel-file-dentry.m4
-@@ -4,14 +4,18 @@ dnl # struct access file->f_path.dentry was replaced by accessor function
- dnl # since fix torvalds/linux@4bacc9c9234c ("overlayfs: Make f_path always
- dnl # point to the overlay and f_inode to the underlay").
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FILE_DENTRY], [
-- AC_MSG_CHECKING([whether file_dentry() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_FILE_DENTRY], [
-+ ZFS_LINUX_TEST_SRC([file_dentry], [
- #include <linux/fs.h>
- ],[
- struct file *f = NULL;
- file_dentry(f);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_FILE_DENTRY], [
-+ AC_MSG_CHECKING([whether file_dentry() is available])
-+ ZFS_LINUX_TEST_RESULT([file_dentry], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_FILE_DENTRY, 1, [file_dentry() is available])
- ],[
-diff --git a/config/kernel-file-inode.m4 b/config/kernel-file-inode.m4
-index 300188fa3..00a362165 100644
---- a/config/kernel-file-inode.m4
-+++ b/config/kernel-file-inode.m4
-@@ -3,14 +3,18 @@ dnl # 3.19 API change
- dnl # struct access f->f_dentry->d_inode was replaced by accessor function
- dnl # file_inode(f)
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FILE_INODE], [
-- AC_MSG_CHECKING([whether file_inode() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_FILE_INODE], [
-+ ZFS_LINUX_TEST_SRC([file_inode], [
- #include <linux/fs.h>
- ],[
- struct file *f = NULL;
- file_inode(f);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_FILE_INODE], [
-+ AC_MSG_CHECKING([whether file_inode() is available])
-+ ZFS_LINUX_TEST_RESULT([file_inode], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_FILE_INODE, 1, [file_inode() is available])
- ],[
-diff --git a/config/kernel-fmode-t.m4 b/config/kernel-fmode-t.m4
-index 4a23c391d..bc0001b9e 100644
---- a/config/kernel-fmode-t.m4
-+++ b/config/kernel-fmode-t.m4
-@@ -2,16 +2,19 @@ dnl #
- dnl # 2.6.28 API change,
- dnl # check if fmode_t typedef is defined
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_TYPE_FMODE_T],
-- [AC_MSG_CHECKING([whether kernel defines fmode_t])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_FMODE_T], [
-+ ZFS_LINUX_TEST_SRC([type_fmode_t], [
- #include <linux/types.h>
- ],[
- fmode_t *ptr __attribute__ ((unused));
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_FMODE_T], [
-+ AC_MSG_CHECKING([whether kernel defines fmode_t])
-+ ZFS_LINUX_TEST_RESULT([type_fmode_t], [
- AC_MSG_RESULT([yes])
-- AC_DEFINE(HAVE_FMODE_T, 1,
-- [kernel defines fmode_t])
-+ AC_DEFINE(HAVE_FMODE_T, 1, [kernel defines fmode_t])
- ],[
- AC_MSG_RESULT([no])
- ])
-diff --git a/config/kernel-follow-down-one.m4 b/config/kernel-follow-down-one.m4
-index 63fa779d8..94e4aeb8d 100644
---- a/config/kernel-follow-down-one.m4
-+++ b/config/kernel-follow-down-one.m4
-@@ -3,14 +3,18 @@ dnl # 2.6.38 API change
- dnl # follow_down() renamed follow_down_one(). The original follow_down()
- dnl # symbol still exists but will traverse down all the layers.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_DOWN_ONE], [
-- AC_MSG_CHECKING([whether follow_down_one() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_FOLLOW_DOWN_ONE], [
-+ ZFS_LINUX_TEST_SRC([follow_down_one], [
- #include <linux/namei.h>
- ],[
- struct path *p = NULL;
- follow_down_one(p);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_DOWN_ONE], [
-+ AC_MSG_CHECKING([whether follow_down_one() is available])
-+ ZFS_LINUX_TEST_RESULT([follow_down_one], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_FOLLOW_DOWN_ONE, 1,
- [follow_down_one() is available])
-diff --git a/config/kernel-fpu.m4 b/config/kernel-fpu.m4
-index 0e622e859..a2c47d65a 100644
---- a/config/kernel-fpu.m4
-+++ b/config/kernel-fpu.m4
-@@ -18,8 +18,11 @@ dnl #
- dnl # Pre-4.2: Use kernel_fpu_{begin,end}()
- dnl # HAVE_KERNEL_FPU & KERNEL_EXPORTS_X86_FPU
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FPU], [
-- AC_MSG_CHECKING([which kernel_fpu header to use])
-+dnl # N.B. The header check is performed before all other checks since it
-+dnl # depends on HAVE_KERNEL_FPU_API_HEADER being set in confdefs.h.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_FPU_HEADER], [
-+ AC_MSG_CHECKING([whether fpu headers are available])
- ZFS_LINUX_TRY_COMPILE([
- #include <linux/module.h>
- #include <asm/fpu/api.h>
-@@ -31,66 +34,88 @@ AC_DEFUN([ZFS_AC_KERNEL_FPU], [
- ],[
- AC_MSG_RESULT(i387.h & xcr.h)
- ])
-+])
-
-- AC_MSG_CHECKING([which kernel_fpu function to use])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-- #include <linux/module.h>
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
-+ ZFS_LINUX_TEST_SRC([kernel_fpu], [
- #ifdef HAVE_KERNEL_FPU_API_HEADER
- #include <asm/fpu/api.h>
- #else
- #include <asm/i387.h>
- #include <asm/xcr.h>
- #endif
-- MODULE_LICENSE("$ZFS_META_LICENSE");
-- ],[
-+ ], [
- kernel_fpu_begin();
- kernel_fpu_end();
-- ], [kernel_fpu_begin], [arch/x86/kernel/fpu/core.c], [
-+ ], [], [$ZFS_META_LICENSE])
-+
-+ ZFS_LINUX_TEST_SRC([__kernel_fpu], [
-+ #ifdef HAVE_KERNEL_FPU_API_HEADER
-+ #include <asm/fpu/api.h>
-+ #else
-+ #include <asm/i387.h>
-+ #include <asm/xcr.h>
-+ #endif
-+ ], [
-+ __kernel_fpu_begin();
-+ __kernel_fpu_end();
-+ ], [], [$ZFS_META_LICENSE])
-+
-+ ZFS_LINUX_TEST_SRC([fpu_initialized], [
-+ #include <linux/module.h>
-+ #include <linux/sched.h>
-+ ],[
-+ struct fpu *fpu = ¤t->thread.fpu;
-+ if (fpu->initialized) { return (0); };
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([tif_need_fpu_load], [
-+ #include <linux/module.h>
-+ #include <asm/thread_info.h>
-+
-+ #if !defined(TIF_NEED_FPU_LOAD)
-+ #error "TIF_NEED_FPU_LOAD undefined"
-+ #endif
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_FPU], [
-+ dnl #
-+ dnl # Legacy kernel
-+ dnl #
-+ AC_MSG_CHECKING([whether kernel fpu is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([kernel_fpu_license],
-+ [kernel_fpu_begin], [arch/x86/kernel/fpu/core.c], [
- AC_MSG_RESULT(kernel_fpu_*)
- AC_DEFINE(HAVE_KERNEL_FPU, 1,
- [kernel has kernel_fpu_* functions])
- AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1,
- [kernel exports FPU functions])
- ],[
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-- #include <linux/module.h>
-- #ifdef HAVE_KERNEL_FPU_API_HEADER
-- #include <asm/fpu/api.h>
-- #else
-- #include <asm/i387.h>
-- #include <asm/xcr.h>
-- #endif
-- MODULE_LICENSE("$ZFS_META_LICENSE");
-- ],[
-- __kernel_fpu_begin();
-- __kernel_fpu_end();
-- ], [__kernel_fpu_begin], [arch/x86/kernel/fpu/core.c arch/x86/kernel/i387.c], [
-+ dnl #
-+ dnl # Linux 4.2 kernel
-+ dnl #
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([__kernel_fpu_license],
-+ [__kernel_fpu_begin],
-+ [arch/x86/kernel/fpu/core.c arch/x86/kernel/i387.c], [
- AC_MSG_RESULT(__kernel_fpu_*)
- AC_DEFINE(HAVE_UNDERSCORE_KERNEL_FPU, 1,
- [kernel has __kernel_fpu_* functions])
- AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1,
- [kernel exports FPU functions])
- ],[
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/module.h>
-- #include <linux/sched.h>
-- ],[
-- struct fpu *fpu = ¤t->thread.fpu;
-- if (fpu->initialized) { return (0); };
-- ],[
-+ dnl #
-+ dnl # Linux 5.0 kernel
-+ dnl #
-+ ZFS_LINUX_TEST_RESULT([fpu_initialized], [
- AC_MSG_RESULT(fpu.initialized)
- AC_DEFINE(HAVE_KERNEL_FPU_INITIALIZED, 1,
- [kernel fpu.initialized exists])
- ],[
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/module.h>
-- #include <asm/thread_info.h>
--
-- #if !defined(TIF_NEED_FPU_LOAD)
-- #error "TIF_NEED_FPU_LOAD undefined"
-- #endif
-- ],[
-- ],[
-+ dnl #
-+ dnl # Linux 5.2 kernel
-+ dnl #
-+ ZFS_LINUX_TEST_RESULT([tif_need_fpu_load], [
- AC_MSG_RESULT(TIF_NEED_FPU_LOAD)
- AC_DEFINE(
- HAVE_KERNEL_TIF_NEED_FPU_LOAD, 1,
-diff --git a/config/kernel-fst-mount.m4 b/config/kernel-fst-mount.m4
-index a8ac50bdd..cec1ed4d6 100644
---- a/config/kernel-fst-mount.m4
-+++ b/config/kernel-fst-mount.m4
-@@ -3,9 +3,8 @@ dnl # 2.6.38 API change
- dnl # The .get_sb callback has been replaced by a .mount callback
- dnl # in the file_system_type structure.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FST_MOUNT], [
-- AC_MSG_CHECKING([whether fst->mount() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_FST_MOUNT], [
-+ ZFS_LINUX_TEST_SRC([file_system_type_mount], [
- #include <linux/fs.h>
-
- static struct dentry *
-@@ -18,8 +17,12 @@ AC_DEFUN([ZFS_AC_KERNEL_FST_MOUNT], [
- static struct file_system_type fst __attribute__ ((unused)) = {
- .mount = mount,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_FST_MOUNT], [
-+ AC_MSG_CHECKING([whether fst->mount() exists])
-+ ZFS_LINUX_TEST_RESULT([file_system_type_mount], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_FST_MOUNT, 1, [fst->mount() exists])
- ],[
-diff --git a/config/kernel-fsync.m4 b/config/kernel-fsync.m4
-index e1f2d68b9..0494e31ad 100644
---- a/config/kernel-fsync.m4
-+++ b/config/kernel-fsync.m4
-@@ -1,8 +1,8 @@
- dnl #
--dnl # Linux 2.6.x - 2.6.34 API
-+dnl # Check file_operations->fsync interface.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITH_DENTRY], [
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_FSYNC], [
-+ ZFS_LINUX_TEST_SRC([fsync_with_dentry], [
- #include <linux/fs.h>
-
- int test_fsync(struct file *f, struct dentry *dentry, int x)
-@@ -12,20 +12,9 @@ AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITH_DENTRY], [
- fops __attribute__ ((unused)) = {
- .fsync = test_fsync,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT([dentry])
-- AC_DEFINE(HAVE_FSYNC_WITH_DENTRY, 1,
-- [fops->fsync() with dentry])
-- ],[
-- ])
--])
-+ ],[])
-
--dnl #
--dnl # Linux 2.6.35 - Linux 3.0 API
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITHOUT_DENTRY], [
-- ZFS_LINUX_TRY_COMPILE([
-+ ZFS_LINUX_TEST_SRC([fsync_without_dentry], [
- #include <linux/fs.h>
-
- int test_fsync(struct file *f, int x) { return 0; }
-@@ -34,20 +23,9 @@ AC_DEFUN([ZFS_AC_KERNEL_FSYNC_WITHOUT_DENTRY], [
- fops __attribute__ ((unused)) = {
- .fsync = test_fsync,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT([no dentry])
-- AC_DEFINE(HAVE_FSYNC_WITHOUT_DENTRY, 1,
-- [fops->fsync() without dentry])
-- ],[
-- ])
--])
-+ ],[])
-
--dnl #
--dnl # Linux 3.1 - 3.x API
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FSYNC_RANGE], [
-- ZFS_LINUX_TRY_COMPILE([
-+ ZFS_LINUX_TEST_SRC([fsync_range], [
- #include <linux/fs.h>
-
- int test_fsync(struct file *f, loff_t a, loff_t b, int c)
-@@ -57,18 +35,43 @@ AC_DEFUN([ZFS_AC_KERNEL_FSYNC_RANGE], [
- fops __attribute__ ((unused)) = {
- .fsync = test_fsync,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT([range])
-- AC_DEFINE(HAVE_FSYNC_RANGE, 1,
-- [fops->fsync() with range])
-- ],[
-- ])
-+ ],[])
- ])
-
- AC_DEFUN([ZFS_AC_KERNEL_FSYNC], [
-- AC_MSG_CHECKING([whether fops->fsync() wants])
-- ZFS_AC_KERNEL_FSYNC_WITH_DENTRY
-- ZFS_AC_KERNEL_FSYNC_WITHOUT_DENTRY
-- ZFS_AC_KERNEL_FSYNC_RANGE
-+ dnl #
-+ dnl # Linux 2.6.x - 2.6.34 API
-+ dnl #
-+ AC_MSG_CHECKING([whether fops->fsync() wants dentry])
-+ ZFS_LINUX_TEST_RESULT([fsync_with_dentry], [
-+ AC_MSG_RESULT([yes])
-+ AC_DEFINE(HAVE_FSYNC_WITH_DENTRY, 1,
-+ [fops->fsync() with dentry])
-+ ],[
-+ AC_MSG_RESULT([no])
-+
-+ dnl #
-+ dnl # Linux 2.6.35 - Linux 3.0 API
-+ dnl #
-+ AC_MSG_CHECKING([whether fops->fsync() wants no dentry])
-+ ZFS_LINUX_TEST_RESULT([fsync_without_dentry], [
-+ AC_MSG_RESULT([yes])
-+ AC_DEFINE(HAVE_FSYNC_WITHOUT_DENTRY, 1,
-+ [fops->fsync() without dentry])
-+ ],[
-+ AC_MSG_RESULT([no])
-+
-+ dnl #
-+ dnl # Linux 3.1 - 3.x API
-+ dnl #
-+ AC_MSG_CHECKING([whether fops->fsync() wants range])
-+ ZFS_LINUX_TEST_RESULT([fsync_range], [
-+ AC_MSG_RESULT([range])
-+ AC_DEFINE(HAVE_FSYNC_RANGE, 1,
-+ [fops->fsync() with range])
-+ ],[
-+ ZFS_LINUX_TEST_ERROR([fops->fsync])
-+ ])
-+ ])
-+ ])
- ])
-diff --git a/config/kernel-generic_io_acct.m4 b/config/kernel-generic_io_acct.m4
-index 0aa762162..423b3e5a3 100644
---- a/config/kernel-generic_io_acct.m4
-+++ b/config/kernel-generic_io_acct.m4
-@@ -1,12 +1,8 @@
- dnl #
--dnl # 3.19 API addition
-+dnl # Check for generic io accounting interface.
- dnl #
--dnl # torvalds/linux@394ffa503bc40e32d7f54a9b817264e81ce131b4 allows us to
--dnl # increment iostat counters without generic_make_request().
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT_3ARG], [
-- AC_MSG_CHECKING([whether 3 arg generic IO accounting symbols are available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
-+ ZFS_LINUX_TEST_SRC([generic_acct_3args], [
- #include <linux/bio.h>
-
- void (*generic_start_io_acct_f)(int, unsigned long,
-@@ -16,24 +12,9 @@ AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT_3ARG], [
- ], [
- generic_start_io_acct(0, 0, NULL);
- generic_end_io_acct(0, NULL, 0);
-- ], [generic_start_io_acct], [block/bio.c], [
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
-- [generic_start_io_acct()/generic_end_io_acct() available])
-- ], [
-- AC_MSG_RESULT(no)
- ])
--])
-
--dnl #
--dnl # Linux 4.14 API,
--dnl #
--dnl # generic_start_io_acct/generic_end_io_acct now require request_queue to be
--dnl # provided. No functional changes, but preparation for inflight accounting
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT_4ARG], [
-- AC_MSG_CHECKING([whether 4 arg generic IO accounting symbols are available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+ ZFS_LINUX_TEST_SRC([generic_acct_4args], [
- #include <linux/bio.h>
-
- void (*generic_start_io_acct_f)(struct request_queue *, int,
-@@ -43,11 +24,41 @@ AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT_4ARG], [
- ], [
- generic_start_io_acct(NULL, 0, 0, NULL);
- generic_end_io_acct(NULL, 0, NULL, 0);
-- ], [generic_start_io_acct], [block/bio.c], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
-+ dnl #
-+ dnl # 3.19 API addition
-+ dnl #
-+ dnl # torvalds/linux@394ffa50 allows us to increment iostat
-+ dnl # counters without generic_make_request().
-+ dnl #
-+ AC_MSG_CHECKING([whether generic IO accounting wants 3 args])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_3args],
-+ [generic_start_io_acct], [block/bio.c], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
-- [generic_start_io_acct()/generic_end_io_acct() 4 arg available])
-+ AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
-+ [generic_start_io_acct()/generic_end_io_acct() available])
- ], [
- AC_MSG_RESULT(no)
-+
-+ dnl #
-+ dnl # Linux 4.14 API,
-+ dnl #
-+ dnl # generic_start_io_acct/generic_end_io_acct now require
-+ dnl # request_queue to be provided. No functional changes,
-+ dnl # but preparation for inflight accounting.
-+ dnl #
-+ AC_MSG_CHECKING([whether generic IO accounting wants 4 args])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_4args],
-+ [generic_start_io_acct], [block/bio.c], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
-+ [generic_start_io_acct()/generic_end_io_acct() ]
-+ [4 arg available])
-+ ], [
-+ AC_MSG_RESULT(no)
-+ ])
- ])
- ])
-diff --git a/config/kernel-generic_readlink.m4 b/config/kernel-generic_readlink.m4
-index 914431de4..a7a33b408 100644
---- a/config/kernel-generic_readlink.m4
-+++ b/config/kernel-generic_readlink.m4
-@@ -4,18 +4,21 @@ dnl #
- dnl # NULL inode_operations.readlink implies generic_readlink(), which
- dnl # has been made static.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL], [
-- AC_MSG_CHECKING([whether generic_readlink is global])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_READLINK_GLOBAL], [
-+ ZFS_LINUX_TEST_SRC([generic_readlink_global], [
- #include <linux/fs.h>
- ],[
- int i __attribute__ ((unused));
--
- i = generic_readlink(NULL, NULL, 0);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL], [
-+ AC_MSG_CHECKING([whether generic_readlink is global])
-+ ZFS_LINUX_TEST_RESULT([generic_readlink_global], [
- AC_MSG_RESULT([yes])
- AC_DEFINE(HAVE_GENERIC_READLINK, 1,
-- [generic_readlink is global])
-+ [generic_readlink is global])
- ],[
- AC_MSG_RESULT([no])
- ])
-diff --git a/config/kernel-get-disk-and-module.m4 b/config/kernel-get-disk-and-module.m4
-index 2a51a5af7..51cf7743c 100644
---- a/config/kernel-get-disk-and-module.m4
-+++ b/config/kernel-get-disk-and-module.m4
-@@ -2,14 +2,19 @@ dnl #
- dnl # 4.16 API change
- dnl # Verify if get_disk_and_module() symbol is available.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_AND_MODULE],
-- [AC_MSG_CHECKING([whether get_disk_and_module() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_DISK_AND_MODULE], [
-+ ZFS_LINUX_TEST_SRC([get_disk_and_module], [
- #include <linux/genhd.h>
- ], [
- struct gendisk *disk = NULL;
- (void) get_disk_and_module(disk);
-- ], [get_disk_and_module], [block/genhd.c], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_AND_MODULE], [
-+ AC_MSG_CHECKING([whether get_disk_and_module() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([get_disk_and_module],
-+ [get_disk_and_module], [block/genhd.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_GET_DISK_AND_MODULE,
- 1, [get_disk_and_module() is available])
-diff --git a/config/kernel-get-disk-ro.m4 b/config/kernel-get-disk-ro.m4
-index 13ed81217..1e2abb475 100644
---- a/config/kernel-get-disk-ro.m4
-+++ b/config/kernel-get-disk-ro.m4
-@@ -1,21 +1,21 @@
- dnl #
- dnl # 2.6.x API change
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_RO], [
-- AC_MSG_CHECKING([whether get_disk_ro() is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_DISK_RO], [
-+ ZFS_LINUX_TEST_SRC([get_disk_ro], [
- #include <linux/blkdev.h>
- ],[
- struct gendisk *disk = NULL;
- (void) get_disk_ro(disk);
-- ],[
-+ ], [$NO_UNUSED_BUT_SET_VARIABLE])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_RO], [
-+ AC_MSG_CHECKING([whether get_disk_ro() is available])
-+ ZFS_LINUX_TEST_RESULT([get_disk_ro], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_GET_DISK_RO, 1,
-- [blk_disk_ro() is available])
-+ AC_DEFINE(HAVE_GET_DISK_RO, 1, [blk_disk_ro() is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-get-link.m4 b/config/kernel-get-link.m4
-index 3cda08c1b..e4f478e37 100644
---- a/config/kernel-get-link.m4
-+++ b/config/kernel-get-link.m4
-@@ -1,13 +1,29 @@
- dnl #
- dnl # Supported get_link() interfaces checked newest to oldest.
-+dnl # Note this interface used to be named follow_link.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_LINK], [
-- dnl #
-- dnl # 4.2 API change
-- dnl # - This kernel retired the nameidata structure.
-- dnl #
-- AC_MSG_CHECKING([whether iops->follow_link() passes cookie])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_get_link], [
-+ #include <linux/fs.h>
-+ const char *get_link(struct dentry *de, struct inode *ip,
-+ struct delayed_call *done) { return "symlink"; }
-+ static struct inode_operations
-+ iops __attribute__ ((unused)) = {
-+ .get_link = get_link,
-+ };
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([inode_operations_get_link_cookie], [
-+ #include <linux/fs.h>
-+ const char *get_link(struct dentry *de, struct
-+ inode *ip, void **cookie) { return "symlink"; }
-+ static struct inode_operations
-+ iops __attribute__ ((unused)) = {
-+ .get_link = get_link,
-+ };
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([inode_operations_follow_link], [
- #include <linux/fs.h>
- const char *follow_link(struct dentry *de,
- void **cookie) { return "symlink"; }
-@@ -15,35 +31,17 @@ AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_LINK], [
- iops __attribute__ ((unused)) = {
- .follow_link = follow_link,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_FOLLOW_LINK_COOKIE, 1,
-- [iops->follow_link() cookie])
-- ],[
-- dnl #
-- dnl # 2.6.32 API
-- dnl #
-- AC_MSG_RESULT(no)
-- AC_MSG_CHECKING(
-- [whether iops->follow_link() passes nameidata])
-- ZFS_LINUX_TRY_COMPILE([
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([inode_operations_follow_link_nameidata], [
- #include <linux/fs.h>
-- void *follow_link(struct dentry *de, struct
-- nameidata *nd) { return (void *)NULL; }
-- static struct inode_operations
-- iops __attribute__ ((unused)) = {
-- .follow_link = follow_link,
-- };
-- ],[
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_FOLLOW_LINK_NAMEIDATA, 1,
-- [iops->follow_link() nameidata])
-- ],[
-- AC_MSG_ERROR(no; please file a bug report)
-- ])
-- ])
-+ void *follow_link(struct dentry *de, struct
-+ nameidata *nd) { return (void *)NULL; }
-+ static struct inode_operations
-+ iops __attribute__ ((unused)) = {
-+ .follow_link = follow_link,
-+ };
-+ ],[])
- ])
-
- AC_DEFUN([ZFS_AC_KERNEL_GET_LINK], [
-@@ -53,20 +51,12 @@ AC_DEFUN([ZFS_AC_KERNEL_GET_LINK], [
- dnl # used it to retire the put_link() interface.
- dnl #
- AC_MSG_CHECKING([whether iops->get_link() passes delayed])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- const char *get_link(struct dentry *de, struct inode *ip,
-- struct delayed_call *done) { return "symlink"; }
-- static struct inode_operations
-- iops __attribute__ ((unused)) = {
-- .get_link = get_link,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT([inode_operations_get_link], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_GET_LINK_DELAYED, 1,
-- [iops->get_link() delayed])
-+ AC_DEFINE(HAVE_GET_LINK_DELAYED, 1, [iops->get_link() delayed])
- ],[
-+ AC_MSG_RESULT(no)
-+
- dnl #
- dnl # 4.5 API change
- dnl # The follow_link() interface has been replaced by
-@@ -74,27 +64,41 @@ AC_DEFUN([ZFS_AC_KERNEL_GET_LINK], [
- dnl # - An inode is passed as a separate argument
- dnl # - When called in RCU mode a NULL dentry is passed.
- dnl #
-- AC_MSG_RESULT(no)
- AC_MSG_CHECKING([whether iops->get_link() passes cookie])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- const char *get_link(struct dentry *de, struct
-- inode *ip, void **cookie) { return "symlink"; }
-- static struct inode_operations
-- iops __attribute__ ((unused)) = {
-- .get_link = get_link,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT([inode_operations_get_link_cookie], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_GET_LINK_COOKIE, 1,
- [iops->get_link() cookie])
- ],[
-+ AC_MSG_RESULT(no)
-+
- dnl #
-- dnl # Check for the follow_link APIs.
-+ dnl # 4.2 API change
-+ dnl # This kernel retired the nameidata structure.
- dnl #
-- AC_MSG_RESULT(no)
-- ZFS_AC_KERNEL_FOLLOW_LINK
-+ AC_MSG_CHECKING(
-+ [whether iops->follow_link() passes cookie])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_follow_link], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_FOLLOW_LINK_COOKIE, 1,
-+ [iops->follow_link() cookie])
-+ ],[
-+ AC_MSG_RESULT(no)
-+
-+ dnl #
-+ dnl # 2.6.32 API
-+ dnl #
-+ AC_MSG_CHECKING(
-+ [whether iops->follow_link() passes nameidata])
-+ ZFS_LINUX_TEST_RESULT(
-+ [inode_operations_follow_link_nameidata],[
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_FOLLOW_LINK_NAMEIDATA, 1,
-+ [iops->follow_link() nameidata])
-+ ],[
-+ ZFS_LINUX_TEST_ERROR([get_link])
-+ ])
-+ ])
- ])
- ])
- ])
-diff --git a/config/kernel-global_page_state.m4 b/config/kernel-global_page_state.m4
-index f4a40011f..a0cb9e2c8 100644
---- a/config/kernel-global_page_state.m4
-+++ b/config/kernel-global_page_state.m4
-@@ -4,16 +4,21 @@ dnl #
- dnl # 75ef71840539 mm, vmstat: add infrastructure for per-node vmstats
- dnl # 599d0c954f91 mm, vmscan: move LRU lists to node
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE], [
-- AC_MSG_CHECKING([whether global_node_page_state() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GLOBAL_NODE_PAGE_STATE], [
-+ ZFS_LINUX_TEST_SRC([global_node_page_state], [
- #include <linux/mm.h>
- #include <linux/vmstat.h>
- ],[
- (void) global_node_page_state(0);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE], [
-+ AC_MSG_CHECKING([whether global_node_page_state() exists])
-+ ZFS_LINUX_TEST_RESULT([global_node_page_state], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(ZFS_GLOBAL_NODE_PAGE_STATE, 1, [global_node_page_state() exists])
-+ AC_DEFINE(ZFS_GLOBAL_NODE_PAGE_STATE, 1,
-+ [global_node_page_state() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -24,16 +29,21 @@ dnl # 4.14 API change
- dnl #
- dnl # c41f012ade0b mm: rename global_page_state to global_zone_page_state
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE], [
-- AC_MSG_CHECKING([whether global_zone_page_state() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GLOBAL_ZONE_PAGE_STATE], [
-+ ZFS_LINUX_TEST_SRC([global_zone_page_state], [
- #include <linux/mm.h>
- #include <linux/vmstat.h>
- ],[
- (void) global_zone_page_state(0);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE], [
-+ AC_MSG_CHECKING([whether global_zone_page_state() exists])
-+ ZFS_LINUX_TEST_RESULT([global_zone_page_state], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(ZFS_GLOBAL_ZONE_PAGE_STATE, 1, [global_zone_page_state() exists])
-+ AC_DEFINE(ZFS_GLOBAL_ZONE_PAGE_STATE, 1,
-+ [global_zone_page_state() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -44,9 +54,11 @@ dnl # Create a define and autoconf variable for an enum member
- dnl #
- AC_DEFUN([ZFS_AC_KERNEL_ENUM_MEMBER], [
- AC_MSG_CHECKING([whether enum $2 contains $1])
-- AS_IF([AC_TRY_COMMAND("${srcdir}/scripts/enum-extract.pl" "$2" "$3" | egrep -qx $1)],[
-+ AS_IF([AC_TRY_COMMAND(
-+ "${srcdir}/scripts/enum-extract.pl" "$2" "$3" | egrep -qx $1)],[
- AC_MSG_RESULT([yes])
-- AC_DEFINE(m4_join([_], [ZFS_ENUM], m4_toupper($2), $1), 1, [enum $2 contains $1])
-+ AC_DEFINE(m4_join([_], [ZFS_ENUM], m4_toupper($2), $1), 1,
-+ [enum $2 contains $1])
- m4_join([_], [ZFS_ENUM], m4_toupper($2), $1)=1
- ],[
- AC_MSG_RESULT([no])
-@@ -59,8 +71,7 @@ dnl #
- AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR],[
- AC_MSG_RESULT(no)
- AC_MSG_RESULT([$1 in either node_stat_item or zone_stat_item: $2])
-- AC_MSG_RESULT([configure needs updating, see: config/kernel-global_page_state.m4])
-- AC_MSG_FAILURE([SHUT 'ER DOWN CLANCY, SHE'S PUMPIN' MUD!])
-+ ZFS_LINUX_TEST_ERROR([global page state])
- ])
-
- AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK], [
-@@ -75,10 +86,10 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK], [
- ])
-
- dnl #
--dnl # Ensure the config tests are finding one and only one of each enum of interest
-+dnl # Ensure the config tests are finding one and only one of each enum.
- dnl #
- AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY], [
-- AC_MSG_CHECKING([global_page_state enums are sane])
-+ AC_MSG_CHECKING([whether global_page_state enums are sane])
-
- ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_FILE_PAGES])
- ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_ANON])
-@@ -88,6 +99,11 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY], [
- AC_MSG_RESULT(yes)
- ])
-
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GLOBAL_PAGE_STATE], [
-+ ZFS_AC_KERNEL_SRC_GLOBAL_NODE_PAGE_STATE
-+ ZFS_AC_KERNEL_SRC_GLOBAL_ZONE_PAGE_STATE
-+])
-+
- dnl #
- dnl # enum members in which we're interested
- dnl #
-@@ -95,15 +111,23 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE], [
- ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE
- ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE
-
-- ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES], [node_stat_item], [$LINUX/include/linux/mmzone.h])
-- ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON], [node_stat_item], [$LINUX/include/linux/mmzone.h])
-- ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE], [node_stat_item], [$LINUX/include/linux/mmzone.h])
-- ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE], [node_stat_item], [$LINUX/include/linux/mmzone.h])
-+ ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES],
-+ [node_stat_item], [$LINUX/include/linux/mmzone.h])
-+ ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON],
-+ [node_stat_item], [$LINUX/include/linux/mmzone.h])
-+ ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],
-+ [node_stat_item], [$LINUX/include/linux/mmzone.h])
-+ ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],
-+ [node_stat_item], [$LINUX/include/linux/mmzone.h])
-
-- ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES], [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-- ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON], [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-- ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE], [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-- ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE], [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-+ ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES],
-+ [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-+ ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON],
-+ [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-+ ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],
-+ [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-+ ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],
-+ [zone_stat_item], [$LINUX/include/linux/mmzone.h])
-
- ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY
- ])
-diff --git a/config/kernel-group-info.m4 b/config/kernel-group-info.m4
-index 849a1e246..0fee1d36d 100644
---- a/config/kernel-group-info.m4
-+++ b/config/kernel-group-info.m4
-@@ -2,20 +2,21 @@ dnl #
- dnl # 4.9 API change
- dnl # group_info changed from 2d array via >blocks to 1d array via ->gid
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_GROUP_INFO_GID], [
-- AC_MSG_CHECKING([whether group_info->gid exists])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GROUP_INFO_GID], [
-+ ZFS_LINUX_TEST_SRC([group_info_gid], [
- #include <linux/cred.h>
- ],[
- struct group_info *gi = groups_alloc(1);
- gi->gid[0] = KGIDT_INIT(0);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_GROUP_INFO_GID], [
-+ AC_MSG_CHECKING([whether group_info->gid exists])
-+ ZFS_LINUX_TEST_RESULT([group_info_gid], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_GROUP_INFO_GID, 1, [group_info->gid exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-in-compat-syscall.m4 b/config/kernel-in-compat-syscall.m4
-index 9fca9da20..baaac8c4f 100644
---- a/config/kernel-in-compat-syscall.m4
-+++ b/config/kernel-in-compat-syscall.m4
-@@ -4,13 +4,17 @@ dnl # Added in_compat_syscall() which can be overridden on a per-
- dnl # architecture basis. Prior to this is_compat_task() was the
- dnl # provided interface.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_IN_COMPAT_SYSCALL], [
-- AC_MSG_CHECKING([whether in_compat_syscall() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL], [
-+ ZFS_LINUX_TEST_SRC([in_compat_syscall], [
- #include <linux/compat.h>
- ],[
- in_compat_syscall();
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_IN_COMPAT_SYSCALL], [
-+ AC_MSG_CHECKING([whether in_compat_syscall() is available])
-+ ZFS_LINUX_TEST_RESULT([in_compat_syscall], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_IN_COMPAT_SYSCALL, 1,
- [in_compat_syscall() is available])
-diff --git a/config/kernel-inode-getattr.m4 b/config/kernel-inode-getattr.m4
-index f10e0b251..48391d66f 100644
---- a/config/kernel-inode-getattr.m4
-+++ b/config/kernel-inode-getattr.m4
-@@ -2,9 +2,8 @@ dnl #
- dnl # Linux 4.11 API
- dnl # See torvalds/linux@a528d35
- dnl #
--AC_DEFUN([ZFS_AC_PATH_KERNEL_IOPS_GETATTR], [
-- AC_MSG_CHECKING([whether iops->getattr() takes a path])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
- #include <linux/fs.h>
-
- int test_getattr(
-@@ -16,24 +15,9 @@ AC_DEFUN([ZFS_AC_PATH_KERNEL_IOPS_GETATTR], [
- iops __attribute__ ((unused)) = {
- .getattr = test_getattr,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
-- [iops->getattr() takes a path])
-- ],[
-- AC_MSG_RESULT(no)
-- ])
--])
--
-+ ],[])
-
--
--dnl #
--dnl # Linux 3.9 - 4.10 API
--dnl #
--AC_DEFUN([ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR], [
-- AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
-- ZFS_LINUX_TRY_COMPILE([
-+ ZFS_LINUX_TEST_SRC([inode_operations_getattr_vfsmount], [
- #include <linux/fs.h>
-
- int test_getattr(
-@@ -45,23 +29,25 @@ AC_DEFUN([ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR], [
- iops __attribute__ ((unused)) = {
- .getattr = test_getattr,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
-+ AC_MSG_CHECKING([whether iops->getattr() takes a path])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
-- [iops->getattr() takes a vfsmount])
-+ AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
-+ [iops->getattr() takes a path])
- ],[
- AC_MSG_RESULT(no)
-- ])
--])
--
-
--dnl #
--dnl # The interface of the getattr callback from the inode_operations
--dnl # structure changed. Also, the interface of the simple_getattr()
--dnl # function provided by the kernel changed.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR], [
-- ZFS_AC_PATH_KERNEL_IOPS_GETATTR
-- ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR
-+ AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
-+ [iops->getattr() takes a vfsmount])
-+ ],[
-+ AC_MSG_RESULT(no)
-+ ])
-+ ])
- ])
-diff --git a/config/kernel-inode-lock.m4 b/config/kernel-inode-lock.m4
-index 8dee01422..5eb04af78 100644
---- a/config/kernel-inode-lock.m4
-+++ b/config/kernel-inode-lock.m4
-@@ -4,20 +4,21 @@ dnl # i_mutex is changed to i_rwsem. Instead of directly using
- dnl # i_mutex/i_rwsem, we should use inode_lock() and inode_lock_shared()
- dnl # We test inode_lock_shared because inode_lock is introduced earlier.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_LOCK], [
-- AC_MSG_CHECKING([whether inode_lock_shared() exists])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_LOCK], [
-+ ZFS_LINUX_TEST_SRC([inode_lock], [
- #include <linux/fs.h>
- ],[
- struct inode *inode = NULL;
- inode_lock_shared(inode);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_LOCK], [
-+ AC_MSG_CHECKING([whether inode_lock_shared() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_lock], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_INODE_LOCK_SHARED, 1, [yes])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-inode-set-flags.m4 b/config/kernel-inode-set-flags.m4
-index e0ad26796..133f666a9 100644
---- a/config/kernel-inode-set-flags.m4
-+++ b/config/kernel-inode-set-flags.m4
-@@ -2,14 +2,18 @@ dnl #
- dnl # 3.15 API change
- dnl # inode_set_flags introduced to set i_flags
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_FLAGS], [
-- AC_MSG_CHECKING([whether inode_set_flags() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SET_FLAGS], [
-+ ZFS_LINUX_TEST_SRC([inode_set_flags], [
- #include <linux/fs.h>
- ],[
- struct inode inode;
- inode_set_flags(&inode, S_IMMUTABLE, S_IMMUTABLE);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_FLAGS], [
-+ AC_MSG_CHECKING([whether inode_set_flags() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_set_flags], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_INODE_SET_FLAGS, 1, [inode_set_flags() exists])
- ],[
-diff --git a/config/kernel-inode-set-iversion.m4 b/config/kernel-inode-set-iversion.m4
-index 9a7d7890e..dd415de32 100644
---- a/config/kernel-inode-set-iversion.m4
-+++ b/config/kernel-inode-set-iversion.m4
-@@ -2,14 +2,18 @@ dnl #
- dnl # 4.16 API change
- dnl # inode_set_iversion introduced to set i_version
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_IVERSION], [
-- AC_MSG_CHECKING([whether inode_set_iversion() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SET_IVERSION], [
-+ ZFS_LINUX_TEST_SRC([inode_set_iversion], [
- #include <linux/iversion.h>
- ],[
- struct inode inode;
- inode_set_iversion(&inode, 1);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_IVERSION], [
-+ AC_MSG_CHECKING([whether inode_set_iversion() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_set_iversion], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_INODE_SET_IVERSION, 1,
- [inode_set_iversion() exists])
-diff --git a/config/kernel-inode-times.m4 b/config/kernel-inode-times.m4
-index f5818411a..57e7f31fd 100644
---- a/config/kernel-inode-times.m4
-+++ b/config/kernel-inode-times.m4
-@@ -2,11 +2,8 @@ dnl #
- dnl # 4.18 API change
- dnl # i_atime, i_mtime, and i_ctime changed from timespec to timespec64.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
-- AC_MSG_CHECKING([whether inode->i_*time's are timespec64])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [
-+ ZFS_LINUX_TEST_SRC([inode_times], [
- #include <linux/fs.h>
- ],[
- struct inode ip;
-@@ -14,12 +11,16 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
-
- memset(&ip, 0, sizeof(ip));
- ts = ip.i_mtime;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
-+ AC_MSG_CHECKING([whether inode->i_*time's are timespec64])
-+ ZFS_LINUX_TEST_RESULT([inode_times], [
- AC_MSG_RESULT(no)
- ],[
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_INODE_TIMESPEC64_TIMES, 1,
- [inode->i_*time's are timespec64])
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-insert-inode-locked.m4 b/config/kernel-insert-inode-locked.m4
-index da141d180..4990399c3 100644
---- a/config/kernel-insert-inode-locked.m4
-+++ b/config/kernel-insert-inode-locked.m4
-@@ -2,16 +2,21 @@ dnl #
- dnl # 2.6.28 API change
- dnl # Added insert_inode_locked() helper function.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INSERT_INODE_LOCKED],
-- [AC_MSG_CHECKING([whether insert_inode_locked() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED], [
-+ ZFS_LINUX_TEST_SRC([insert_inode_locked], [
- #include <linux/fs.h>
- ], [
- insert_inode_locked(NULL);
-- ], [insert_inode_locked], [fs/inode.c], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INSERT_INODE_LOCKED], [
-+ AC_MSG_CHECKING([whether insert_inode_locked() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([insert_inode_locked],
-+ [insert_inode_locked], [fs/inode.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_INSERT_INODE_LOCKED, 1,
-- [insert_inode_locked() is available])
-+ [insert_inode_locked() is available])
- ], [
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-invalidate-bdev-args.m4 b/config/kernel-invalidate-bdev-args.m4
-index 09c2ebf26..55a784dd9 100644
---- a/config/kernel-invalidate-bdev-args.m4
-+++ b/config/kernel-invalidate-bdev-args.m4
-@@ -2,17 +2,21 @@ dnl #
- dnl # 2.6.22 API change
- dnl # Unused destroy_dirty_buffers arg removed from prototype.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INVALIDATE_BDEV_ARGS], [
-- AC_MSG_CHECKING([whether invalidate_bdev() wants 1 arg])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INVALIDATE_BDEV], [
-+ ZFS_LINUX_TEST_SRC([invalidate_bdev], [
- #include <linux/buffer_head.h>
- ],[
- struct block_device *bdev = NULL;
- invalidate_bdev(bdev);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INVALIDATE_BDEV], [
-+ AC_MSG_CHECKING([whether invalidate_bdev() wants 1 arg])
-+ ZFS_LINUX_TEST_RESULT([invalidate_bdev], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_1ARG_INVALIDATE_BDEV, 1,
-- [invalidate_bdev() wants 1 arg])
-+ [invalidate_bdev() wants 1 arg])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-is_owner_or_cap.m4 b/config/kernel-is_owner_or_cap.m4
-index da07e58dd..ab8072409 100644
---- a/config/kernel-is_owner_or_cap.m4
-+++ b/config/kernel-is_owner_or_cap.m4
-@@ -4,33 +4,40 @@ dnl # The is_owner_or_cap() macro was renamed to inode_owner_or_capable(),
- dnl # This is used for permission checks in the xattr and file attribute call
- dnl # paths.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
-- AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [
-+ ZFS_LINUX_TEST_SRC([inode_owner_or_capable], [
- #include <linux/fs.h>
- ],[
- struct inode *ip = NULL;
- (void) inode_owner_or_capable(ip);
-+ ])
-+
-+
-+ ZFS_LINUX_TEST_SRC([is_owner_or_cap], [
-+ #include <linux/fs.h>
-+ #include <linux/sched.h>
- ],[
-+ struct inode *ip = NULL;
-+ (void) is_owner_or_cap(ip);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
-+ AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE, 1,
- [inode_owner_or_capable() exists])
- ],[
- AC_MSG_RESULT(no)
- AC_MSG_CHECKING([whether is_owner_or_cap() exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- #include <linux/sched.h>
-- ],[
-- struct inode *ip = NULL;
-- (void) is_owner_or_cap(ip);
-- ],[
-+
-+ ZFS_LINUX_TEST_RESULT([is_owner_or_cap], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_IS_OWNER_OR_CAP, 1,
- [is_owner_or_cap() exists])
- ],[
-- AC_MSG_ERROR(no - Please file a bug report at
-- https://github.com/zfsonlinux/zfs/issues/new)
-+ ZFS_LINUX_TEST_ERROR([capability])
- ])
- ])
- ])
-diff --git a/config/kernel-kmap-atomic-args.m4 b/config/kernel-kmap-atomic-args.m4
-index beb1692e7..d09e93d7f 100644
---- a/config/kernel-kmap-atomic-args.m4
-+++ b/config/kernel-kmap-atomic-args.m4
-@@ -3,17 +3,21 @@ dnl # 2.6.37 API change
- dnl # kmap_atomic changed from assigning hard-coded named slot to using
- dnl # push/pop based dynamical allocation.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS], [
-- AC_MSG_CHECKING([whether kmap_atomic wants 1 args])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_KMAP_ATOMIC_ARGS], [
-+ ZFS_LINUX_TEST_SRC([kmap_atomic], [
- #include <linux/pagemap.h>
- ],[
- struct page page;
- kmap_atomic(&page);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS], [
-+ AC_MSG_CHECKING([whether kmap_atomic wants 1 args])
-+ ZFS_LINUX_TEST_RESULT([kmap_atomic], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_1ARG_KMAP_ATOMIC, 1,
-- [kmap_atomic wants 1 args])
-+ [kmap_atomic wants 1 args])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-kmem-cache.m4 b/config/kernel-kmem-cache.m4
-index 21cc53d34..7576e6cfd 100644
---- a/config/kernel-kmem-cache.m4
-+++ b/config/kernel-kmem-cache.m4
-@@ -5,30 +5,36 @@ dnl # private allocation flags which are applied when allocating a new slab
- dnl # in kmem_getpages(). Unfortunately there is no public API for setting
- dnl # non-default flags.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_ALLOCFLAGS], [
-- AC_MSG_CHECKING([whether struct kmem_cache has allocflags])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_KMEM_CACHE_ALLOCFLAGS], [
-+ ZFS_LINUX_TEST_SRC([kmem_cache_allocflags], [
- #include <linux/slab.h>
- ],[
- struct kmem_cache cachep __attribute__ ((unused));
- cachep.allocflags = GFP_KERNEL;
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([kmem_cache_gfpflags], [
-+ #include <linux/slab.h>
- ],[
-+ struct kmem_cache cachep __attribute__ ((unused));
-+ cachep.gfpflags = GFP_KERNEL;
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_ALLOCFLAGS], [
-+ AC_MSG_CHECKING([whether struct kmem_cache has allocflags])
-+ ZFS_LINUX_TEST_RESULT([kmem_cache_allocflags], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_KMEM_CACHE_ALLOCFLAGS, 1,
-- [struct kmem_cache has allocflags])
-+ [struct kmem_cache has allocflags])
- ],[
- AC_MSG_RESULT(no)
-
- AC_MSG_CHECKING([whether struct kmem_cache has gfpflags])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/slab.h>
-- ],[
-- struct kmem_cache cachep __attribute__ ((unused));
-- cachep.gfpflags = GFP_KERNEL;
-- ],[
-+ ZFS_LINUX_TEST_RESULT([kmem_cache_gfpflags], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_KMEM_CACHE_GFPFLAGS, 1,
-- [struct kmem_cache has gfpflags])
-+ [struct kmem_cache has gfpflags])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -40,16 +46,10 @@ dnl # grsecurity API change,
- dnl # kmem_cache_create() with SLAB_USERCOPY flag replaced by
- dnl # kmem_cache_create_usercopy().
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY], [
-- AC_MSG_CHECKING([whether kmem_cache_create_usercopy() exists])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_KMEM_CACHE_CREATE_USERCOPY], [
-+ ZFS_LINUX_TEST_SRC([kmem_cache_create_usercopy], [
- #include <linux/slab.h>
-- static void ctor(void *foo)
-- {
-- // fake ctor
-- }
-+ static void ctor(void *foo) { /* fake ctor */ }
- ],[
- struct kmem_cache *skc_linux_cache;
- const char *name = "test";
-@@ -60,13 +60,27 @@ AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY], [
- size_t usersize = size - useroffset;
-
- skc_linux_cache = kmem_cache_create_usercopy(
-- name, size, align, flags, useroffset, usersize, ctor);
-- ],[
-+ name, size, align, flags, useroffset, usersize, ctor);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY], [
-+ AC_MSG_CHECKING([whether kmem_cache_create_usercopy() exists])
-+ ZFS_LINUX_TEST_RESULT([kmem_cache_create_usercopy], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_KMEM_CACHE_CREATE_USERCOPY, 1,
-- [kmem_cache_create_usercopy() exists])
-+ [kmem_cache_create_usercopy() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_KMEM_CACHE], [
-+ ZFS_AC_KERNEL_SRC_KMEM_CACHE_ALLOCFLAGS
-+ ZFS_AC_KERNEL_SRC_KMEM_CACHE_CREATE_USERCOPY
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE], [
-+ ZFS_AC_KERNEL_KMEM_CACHE_ALLOCFLAGS
-+ ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY
- ])
-diff --git a/config/kernel-kstrtoul.m4 b/config/kernel-kstrtoul.m4
-index 5530e0e2d..ef3c9843c 100644
---- a/config/kernel-kstrtoul.m4
-+++ b/config/kernel-kstrtoul.m4
-@@ -1,18 +1,20 @@
- dnl #
- dnl # 2.6.39 API change
- dnl #
--dnl # 33ee3b2e2eb9 kstrto*: converting strings to integers done (hopefully) right
--dnl #
- dnl # If kstrtoul() doesn't exist, fallback to use strict_strtoul() which has
- dnl # existed since 2.6.25.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_KSTRTOUL], [
-- AC_MSG_CHECKING([whether kstrtoul() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_KSTRTOUL], [
-+ ZFS_LINUX_TEST_SRC([kstrtoul], [
- #include <linux/kernel.h>
- ],[
- int ret __attribute__ ((unused)) = kstrtoul(NULL, 10, NULL);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_KSTRTOUL], [
-+ AC_MSG_CHECKING([whether kstrtoul() exists])
-+ ZFS_LINUX_TEST_RESULT([kstrtoul], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_KSTRTOUL, 1, [kstrtoul() exists])
- ],[
-diff --git a/config/kernel-ktime_get_coarse_real_ts64.m4 b/config/kernel-ktime_get_coarse_real_ts64.m4
-index d6be8c418..28492bf04 100644
---- a/config/kernel-ktime_get_coarse_real_ts64.m4
-+++ b/config/kernel-ktime_get_coarse_real_ts64.m4
-@@ -2,16 +2,21 @@ dnl #
- dnl # 4.18: ktime_get_coarse_real_ts64() added. Use it in place of
- dnl # current_kernel_time64().
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64],
-- [AC_MSG_CHECKING([whether ktime_get_coarse_real_ts64() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64], [
-+ ZFS_LINUX_TEST_SRC([ktime_get_coarse_real_ts64], [
- #include <linux/mm.h>
- ], [
- struct timespec64 ts;
- ktime_get_coarse_real_ts64(&ts);
-- ], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64], [
-+ AC_MSG_CHECKING([whether ktime_get_coarse_real_ts64() exists])
-+ ZFS_LINUX_TEST_RESULT([ktime_get_coarse_real_ts64], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_KTIME_GET_COARSE_REAL_TS64, 1, [ktime_get_coarse_real_ts64() exists])
-+ AC_DEFINE(HAVE_KTIME_GET_COARSE_REAL_TS64, 1,
-+ [ktime_get_coarse_real_ts64() exists])
- ], [
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-kuid-helpers.m4 b/config/kernel-kuid-helpers.m4
-index 60713b9d3..4bc4e039d 100644
---- a/config/kernel-kuid-helpers.m4
-+++ b/config/kernel-kuid-helpers.m4
-@@ -5,14 +5,18 @@ dnl # became necessary to go through one more level of indirection
- dnl # when dealing with uid/gid - namely the kuid type.
- dnl #
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_KUID_HELPERS], [
-- AC_MSG_CHECKING([whether i_(uid|gid)_(read|write) exist])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_KUID_HELPERS], [
-+ ZFS_LINUX_TEST_SRC([i_uid_read], [
- #include <linux/fs.h>
- ],[
- struct inode *ip = NULL;
- (void) i_uid_read(ip);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_KUID_HELPERS], [
-+ AC_MSG_CHECKING([whether i_(uid|gid)_(read|write) exist])
-+ ZFS_LINUX_TEST_RESULT([i_uid_read], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_KUID_HELPERS, 1,
- [i_(uid|gid)_(read|write) exist])
-diff --git a/config/kernel-kuidgid.m4 b/config/kernel-kuidgid.m4
-index 82685d263..15bf98154 100644
---- a/config/kernel-kuidgid.m4
-+++ b/config/kernel-kuidgid.m4
-@@ -3,20 +3,26 @@ dnl # User namespaces, use kuid_t in place of uid_t
- dnl # where available. Not strictly a user namespaces thing
- dnl # but it should prevent surprises
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_KUIDGID_T], [
-- AC_MSG_CHECKING([whether kuid_t/kgid_t is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_KUIDGID_T], [
-+ ZFS_LINUX_TEST_SRC([kuidgid_t_init], [
- #include <linux/uidgid.h>
- ], [
- kuid_t userid __attribute__ ((unused)) = KUIDT_INIT(0);
- kgid_t groupid __attribute__ ((unused)) = KGIDT_INIT(0);
-- ],[
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/uidgid.h>
-- ], [
-- kuid_t userid __attribute__ ((unused)) = 0;
-- kgid_t groupid __attribute__ ((unused)) = 0;
-- ],[
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([kuidgid_t], [
-+ #include <linux/uidgid.h>
-+ ], [
-+ kuid_t userid __attribute__ ((unused)) = 0;
-+ kgid_t groupid __attribute__ ((unused)) = 0;
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_KUIDGID_T], [
-+ AC_MSG_CHECKING([whether kuid_t/kgid_t is available])
-+ ZFS_LINUX_TEST_RESULT([kuidgid_t_init], [
-+ ZFS_LINUX_TEST_RESULT([kuidgid_t], [
- AC_MSG_RESULT(yes; optional)
- ],[
- AC_MSG_RESULT(yes; mandatory)
-diff --git a/config/kernel-lookup-bdev.m4 b/config/kernel-lookup-bdev.m4
-index abbf55d9b..72b4993e1 100644
---- a/config/kernel-lookup-bdev.m4
-+++ b/config/kernel-lookup-bdev.m4
-@@ -2,23 +2,33 @@ dnl #
- dnl # 2.6.27, lookup_bdev() was exported.
- dnl # 4.4.0-6.21 - x.y on Ubuntu, lookup_bdev() takes 2 arguments.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_BDEV],
-- [AC_MSG_CHECKING([whether lookup_bdev() wants 1 arg])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_LOOKUP_BDEV], [
-+ ZFS_LINUX_TEST_SRC([lookup_bdev_1arg], [
- #include <linux/fs.h>
- ], [
- lookup_bdev(NULL);
-- ], [lookup_bdev], [fs/block_dev.c], [
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([lookup_bdev_2args], [
-+ #include <linux/fs.h>
-+ ], [
-+ lookup_bdev(NULL, FMODE_READ);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_BDEV], [
-+ AC_MSG_CHECKING([whether lookup_bdev() wants 1 arg])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_1arg],
-+ [lookup_bdev], [fs/block_dev.c], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_1ARG_LOOKUP_BDEV, 1, [lookup_bdev() wants 1 arg])
-+ AC_DEFINE(HAVE_1ARG_LOOKUP_BDEV, 1,
-+ [lookup_bdev() wants 1 arg])
- ], [
- AC_MSG_RESULT(no)
-+
- AC_MSG_CHECKING([whether lookup_bdev() wants 2 args])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-- #include <linux/fs.h>
-- ], [
-- lookup_bdev(NULL, FMODE_READ);
-- ], [lookup_bdev], [fs/block_dev.c], [
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_2args],
-+ [lookup_bdev], [fs/block_dev.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_2ARGS_LOOKUP_BDEV, 1,
- [lookup_bdev() wants 2 args])
-@@ -26,4 +36,4 @@ AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_BDEV],
- AC_MSG_RESULT(no)
- ])
- ])
--])
-\ No newline at end of file
-+])
-diff --git a/config/kernel-lookup-nameidata.m4 b/config/kernel-lookup-nameidata.m4
-index 5453be5e8..865b8aff8 100644
---- a/config/kernel-lookup-nameidata.m4
-+++ b/config/kernel-lookup-nameidata.m4
-@@ -1,9 +1,8 @@
- dnl #
- dnl # 3.6 API change
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_NAMEIDATA], [
-- AC_MSG_CHECKING([whether iops->lookup() passes nameidata])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_LOOKUP_NAMEIDATA], [
-+ ZFS_LINUX_TEST_SRC([lookup_nameidata], [
- #include <linux/fs.h>
- #include <linux/sched.h>
-
-@@ -15,11 +14,15 @@ AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_NAMEIDATA], [
- __attribute__ ((unused)) = {
- .lookup = inode_lookup,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_NAMEIDATA], [
-+ AC_MSG_CHECKING([whether iops->lookup() passes nameidata])
-+ ZFS_LINUX_TEST_RESULT([lookup_nameidata], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_LOOKUP_NAMEIDATA, 1,
-- [iops->lookup() passes nameidata])
-+ [iops->lookup() passes nameidata])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-lseek-execute.m4 b/config/kernel-lseek-execute.m4
-index 8c4032b92..652f611f8 100644
---- a/config/kernel-lseek-execute.m4
-+++ b/config/kernel-lseek-execute.m4
-@@ -2,9 +2,8 @@ dnl #
- dnl # 3.11 API change
- dnl # lseek_execute helper exported
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_LSEEK_EXECUTE],
-- [AC_MSG_CHECKING([whether lseek_execute() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_LSEEK_EXECUTE], [
-+ ZFS_LINUX_TEST_SRC([lseek_execute], [
- #include <linux/fs.h>
- ], [
- struct file *fp __attribute__ ((unused)) = NULL;
-@@ -13,10 +12,15 @@ AC_DEFUN([ZFS_AC_KERNEL_LSEEK_EXECUTE],
- loff_t maxsize __attribute__ ((unused)) = 0;
-
- lseek_execute(fp, ip, offset, maxsize);
-- ], [lseek_exclusive], [fs/read_write.c], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_LSEEK_EXECUTE], [
-+ AC_MSG_CHECKING([whether lseek_execute() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([lseek_execute],
-+ [lseek_exclusive], [fs/read_write.c], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_LSEEK_EXECUTE, 1,
-- [lseek_execute() is available])
-+ AC_DEFINE(HAVE_LSEEK_EXECUTE, 1, [lseek_execute() is available])
- ], [
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-make-request-fn.m4 b/config/kernel-make-request-fn.m4
-new file mode 100644
-index 000000000..86339aa04
---- /dev/null
-+++ b/config/kernel-make-request-fn.m4
-@@ -0,0 +1,77 @@
-+dnl #
-+dnl # Check for make_request_fn interface.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
-+ ZFS_LINUX_TEST_SRC([make_request_fn_int], [
-+ #include <linux/blkdev.h>
-+ int make_request(struct request_queue *q,
-+ struct bio *bio) { return (0); }
-+ ],[
-+ blk_queue_make_request(NULL, &make_request);
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([make_request_fn_void], [
-+ #include <linux/blkdev.h>
-+ void make_request(struct request_queue *q,
-+ struct bio *bio) { return; }
-+ ],[
-+ blk_queue_make_request(NULL, &make_request);
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([make_request_fn_blk_qc_t], [
-+ #include <linux/blkdev.h>
-+ blk_qc_t make_request(struct request_queue *q,
-+ struct bio *bio) { return (BLK_QC_T_NONE); }
-+ ],[
-+ blk_queue_make_request(NULL, &make_request);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
-+ dnl #
-+ dnl # Legacy API
-+ dnl # make_request_fn returns int.
-+ dnl #
-+ AC_MSG_CHECKING([whether make_request_fn() returns int])
-+ ZFS_LINUX_TEST_RESULT([make_request_fn_int], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(MAKE_REQUEST_FN_RET, int,
-+ [make_request_fn() return type])
-+ AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_INT, 1,
-+ [Noting that make_request_fn() returns int])
-+ ],[
-+ AC_MSG_RESULT(no)
-+
-+ dnl #
-+ dnl # Linux 3.2 API Change
-+ dnl # make_request_fn returns void.
-+ dnl #
-+ AC_MSG_CHECKING([whether make_request_fn() returns void])
-+ ZFS_LINUX_TEST_RESULT([make_request_fn_void], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(MAKE_REQUEST_FN_RET, void,
-+ [make_request_fn() return type])
-+ AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_VOID, 1,
-+ [Noting that make_request_fn() returns void])
-+ ],[
-+ AC_MSG_RESULT(no)
-+
-+ dnl #
-+ dnl # Linux 4.4 API Change
-+ dnl # make_request_fn returns blk_qc_t.
-+ dnl #
-+ AC_MSG_CHECKING(
-+ [whether make_request_fn() returns blk_qc_t])
-+ ZFS_LINUX_TEST_RESULT([make_request_fn_blk_qc_t], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
-+ [make_request_fn() return type])
-+ AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
-+ [Noting that make_request_fn() ]
-+ [returns blk_qc_t])
-+ ],[
-+ ZFS_LINUX_TEST_ERROR([make_request_fn])
-+ ])
-+ ])
-+ ])
-+])
-diff --git a/config/kernel-misc-minor.m4 b/config/kernel-misc-minor.m4
-index a020d2ebc..20fe2cd2f 100644
---- a/config/kernel-misc-minor.m4
-+++ b/config/kernel-misc-minor.m4
-@@ -6,7 +6,7 @@ dnl # number. Start with a large known available unreserved minor and work
- dnl # our way down to lower value if a collision is detected.
- dnl #
- AC_DEFUN([ZFS_AC_KERNEL_MISC_MINOR], [
-- AC_MSG_CHECKING([for available /dev/zfs minor])
-+ AC_MSG_CHECKING([whether /dev/zfs minor is available])
-
- for i in $(seq 249 -1 200); do
- if ! grep -q "^#define\s\+.*_MINOR\s\+.*$i" \
-diff --git a/config/kernel-mk-request-fn.m4 b/config/kernel-mk-request-fn.m4
-deleted file mode 100644
-index 57eebe23d..000000000
---- a/config/kernel-mk-request-fn.m4
-+++ /dev/null
-@@ -1,65 +0,0 @@
--dnl #
--dnl # Linux 3.2 API Change
--dnl # make_request_fn returns void instead of int.
--dnl #
--dnl # Linux 4.4 API Change
--dnl # make_request_fn returns blk_qc_t.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
-- AC_MSG_CHECKING([whether make_request_fn() returns int])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/blkdev.h>
--
-- int make_request(struct request_queue *q, struct bio *bio)
-- {
-- return (0);
-- }
-- ],[
-- blk_queue_make_request(NULL, &make_request);
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(MAKE_REQUEST_FN_RET, int,
-- [make_request_fn() returns int])
-- AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_INT, 1,
-- [Noting that make_request_fn() returns int])
-- ],[
-- AC_MSG_RESULT(no)
-- AC_MSG_CHECKING([whether make_request_fn() returns void])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/blkdev.h>
--
-- void make_request(struct request_queue *q, struct bio *bio)
-- {
-- return;
-- }
-- ],[
-- blk_queue_make_request(NULL, &make_request);
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(MAKE_REQUEST_FN_RET, void,
-- [make_request_fn() returns void])
-- ],[
-- AC_MSG_RESULT(no)
-- AC_MSG_CHECKING([whether make_request_fn() returns blk_qc_t])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/blkdev.h>
--
-- blk_qc_t make_request(struct request_queue *q, struct bio *bio)
-- {
-- return (BLK_QC_T_NONE);
-- }
-- ],[
-- blk_queue_make_request(NULL, &make_request);
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
-- [make_request_fn() returns blk_qc_t])
-- AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
-- [Noting that make_request_fn() returns blk_qc_t])
-- ],[
-- AC_MSG_ERROR(no - Please file a bug report at
-- https://github.com/zfsonlinux/zfs/issues/new)
-- ])
-- ])
-- ])
--])
-diff --git a/config/kernel-mkdir-umode-t.m4 b/config/kernel-mkdir-umode-t.m4
-index ebc21be9e..4cbfc0c31 100644
---- a/config/kernel-mkdir-umode-t.m4
-+++ b/config/kernel-mkdir-umode-t.m4
-@@ -6,9 +6,8 @@ dnl # would also change all three prototypes. However, if it turns out that
- dnl # some distribution doesn't backport the whole thing this could be
- dnl # broken apart in to three separate checks.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
-- AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
- #include <linux/fs.h>
-
- int mkdir(struct inode *inode, struct dentry *dentry,
-@@ -18,8 +17,12 @@ AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
- iops __attribute__ ((unused)) = {
- .mkdir = mkdir,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
-+ AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
- [iops->create()/mkdir()/mknod() take umode_t])
-diff --git a/config/kernel-mod-param.m4 b/config/kernel-mod-param.m4
-index b72be684a..e00f19d61 100644
---- a/config/kernel-mod-param.m4
-+++ b/config/kernel-mod-param.m4
-@@ -2,9 +2,8 @@ dnl #
- dnl # Grsecurity kernel API change
- dnl # constified parameters of module_param_call() methods
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [
-- AC_MSG_CHECKING([whether module_param_call() is hardened])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST], [
-+ ZFS_LINUX_TEST_SRC([module_param_call], [
- #include <linux/module.h>
- #include <linux/moduleparam.h>
-
-@@ -19,8 +18,12 @@ AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [
- }
-
- module_param_call(p, param_set, param_get, NULL, 0644);
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [
-+ AC_MSG_CHECKING([whether module_param_call() is hardened])
-+ ZFS_LINUX_TEST_RESULT([module_param_call], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(MODULE_PARAM_CALL_CONST, 1,
- [hardened module_param_call])
-diff --git a/config/kernel-objtool.m4 b/config/kernel-objtool.m4
-index 467329b25..bf60e7869 100644
---- a/config/kernel-objtool.m4
-+++ b/config/kernel-objtool.m4
-@@ -1,41 +1,44 @@
- dnl #
--dnl # 4.6 API for compile-time stack validation
-+dnl # Check for objtool support.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_OBJTOOL], [
-- AC_MSG_CHECKING([for compile-time stack validation (objtool)])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_OBJTOOL], [
-+
-+ dnl # 4.6 API for compile-time stack validation
-+ ZFS_LINUX_TEST_SRC([objtool], [
- #undef __ASSEMBLY__
- #include <asm/frame.h>
- ],[
- #if !defined(FRAME_BEGIN)
- CTASSERT(1);
- #endif
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_KERNEL_OBJTOOL, 1,
-- [kernel does stack verification])
--
-- ZFS_AC_KERNEL_STACK_FRAME_NON_STANDARD
-- ],[
-- AC_MSG_RESULT(no)
- ])
--])
-
--dnl #
--dnl # 4.6 API added STACK_FRAME_NON_STANDARD macro
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_STACK_FRAME_NON_STANDARD], [
-- AC_MSG_CHECKING([whether STACK_FRAME_NON_STANDARD is defined])
-- ZFS_LINUX_TRY_COMPILE([
-+ dnl # 4.6 API added STACK_FRAME_NON_STANDARD macro
-+ ZFS_LINUX_TEST_SRC([stack_frame_non_standard], [
- #include <linux/frame.h>
- ],[
- #if !defined(STACK_FRAME_NON_STANDARD)
- CTASSERT(1);
- #endif
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_OBJTOOL], [
-+ AC_MSG_CHECKING(
-+ [whether compile-time stack validation (objtool) is available])
-+ ZFS_LINUX_TEST_RESULT([objtool], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_STACK_FRAME_NON_STANDARD, 1,
-- [STACK_FRAME_NON_STANDARD is defined])
-+ AC_DEFINE(HAVE_KERNEL_OBJTOOL, 1,
-+ [kernel does stack verification])
-+
-+ AC_MSG_CHECKING([whether STACK_FRAME_NON_STANDARD is defined])
-+ ZFS_LINUX_TEST_RESULT([stack_frame_non_standard], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_STACK_FRAME_NON_STANDARD, 1,
-+ [STACK_FRAME_NON_STANDARD is defined])
-+ ],[
-+ AC_MSG_RESULT(no)
-+ ])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-open-bdev-exclusive.m4 b/config/kernel-open-bdev-exclusive.m4
-index 0661315a6..2e46b8876 100644
---- a/config/kernel-open-bdev-exclusive.m4
-+++ b/config/kernel-open-bdev-exclusive.m4
-@@ -2,16 +2,21 @@ dnl #
- dnl # 2.6.28 API change
- dnl # open/close_bdev_excl() renamed to open/close_bdev_exclusive()
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_OPEN_BDEV_EXCLUSIVE],
-- [AC_MSG_CHECKING([whether open_bdev_exclusive() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_OPEN_EXCLUSIVE], [
-+ ZFS_LINUX_TEST_SRC([open_bdev_exclusive], [
- #include <linux/fs.h>
- ], [
- open_bdev_exclusive(NULL, 0, NULL);
-- ], [open_bdev_exclusive], [fs/block_dev.c], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_BDEV_OPEN_EXCLUSIVE], [
-+ AC_MSG_CHECKING([whether open_bdev_exclusive() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([open_bdev_exclusive],
-+ [open_bdev_exclusive], [fs/block_dev.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_OPEN_BDEV_EXCLUSIVE, 1,
-- [open_bdev_exclusive() is available])
-+ [open_bdev_exclusive() is available])
- ], [
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-pde-data.m4 b/config/kernel-pde-data.m4
-index 8aa4c2204..928c5ef0d 100644
---- a/config/kernel-pde-data.m4
-+++ b/config/kernel-pde-data.m4
-@@ -2,15 +2,19 @@ dnl #
- dnl # 3.10 API change,
- dnl # PDE is replaced by PDE_DATA
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_PDE_DATA], [
-- AC_MSG_CHECKING([whether PDE_DATA() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_PDE_DATA], [
-+ ZFS_LINUX_TEST_SRC([pde_data], [
- #include <linux/proc_fs.h>
- ], [
- PDE_DATA(NULL);
-- ], [PDE_DATA], [], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_PDE_DATA], [
-+ AC_MSG_CHECKING([whether PDE_DATA() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([pde_data], [PDE_DATA], [], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_PDE_DATA, 1, [yes])
-+ AC_DEFINE(HAVE_PDE_DATA, 1, [PDE_DATA is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-put-link.m4 b/config/kernel-put-link.m4
-index a0bb36ef2..f03df9e99 100644
---- a/config/kernel-put-link.m4
-+++ b/config/kernel-put-link.m4
-@@ -1,17 +1,35 @@
- dnl #
- dnl # Supported symlink APIs
- dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_PUT_LINK], [
-+ ZFS_LINUX_TEST_SRC([put_link_cookie], [
-+ #include <linux/fs.h>
-+ void put_link(struct inode *ip, void *cookie)
-+ { return; }
-+ static struct inode_operations
-+ iops __attribute__ ((unused)) = {
-+ .put_link = put_link,
-+ };
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([put_link_nameidata], [
-+ #include <linux/fs.h>
-+ void put_link(struct dentry *de, struct
-+ nameidata *nd, void *ptr) { return; }
-+ static struct inode_operations
-+ iops __attribute__ ((unused)) = {
-+ .put_link = put_link,
-+ };
-+ ],[])
-+])
-+
- AC_DEFUN([ZFS_AC_KERNEL_PUT_LINK], [
- dnl #
- dnl # 4.5 API change
- dnl # get_link() uses delayed done, there is no put_link() interface.
-+ dnl # This check intially uses the inode_operations_get_link result
- dnl #
-- ZFS_LINUX_TRY_COMPILE([
-- #if !defined(HAVE_GET_LINK_DELAYED)
-- #error "Expecting get_link() delayed done"
-- #endif
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT([inode_operations_get_link], [
- AC_DEFINE(HAVE_PUT_LINK_DELAYED, 1, [iops->put_link() delayed])
- ],[
- dnl #
-@@ -19,41 +37,24 @@ AC_DEFUN([ZFS_AC_KERNEL_PUT_LINK], [
- dnl # This kernel retired the nameidata structure.
- dnl #
- AC_MSG_CHECKING([whether iops->put_link() passes cookie])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- void put_link(struct inode *ip, void *cookie)
-- { return; }
-- static struct inode_operations
-- iops __attribute__ ((unused)) = {
-- .put_link = put_link,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT([put_link_cookie], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_PUT_LINK_COOKIE, 1,
- [iops->put_link() cookie])
- ],[
-+ AC_MSG_RESULT(no)
-+
- dnl #
- dnl # 2.6.32 API
- dnl #
-- AC_MSG_RESULT(no)
- AC_MSG_CHECKING(
- [whether iops->put_link() passes nameidata])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- void put_link(struct dentry *de, struct
-- nameidata *nd, void *ptr) { return; }
-- static struct inode_operations
-- iops __attribute__ ((unused)) = {
-- .put_link = put_link,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT([put_link_nameidata], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_PUT_LINK_NAMEIDATA, 1,
- [iops->put_link() nameidata])
- ],[
-- AC_MSG_ERROR(no; please file a bug report)
-+ ZFS_LINUX_TEST_ERROR([put_link])
- ])
- ])
- ])
-diff --git a/config/kernel-rename.m4 b/config/kernel-rename.m4
-index 9f894fb4d..f70739153 100644
---- a/config/kernel-rename.m4
-+++ b/config/kernel-rename.m4
-@@ -3,9 +3,8 @@ dnl # 4.9 API change,
- dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
- dnl # flags.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
-- AC_MSG_CHECKING([whether iops->rename() wants flags])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_rename], [
- #include <linux/fs.h>
- int rename_fn(struct inode *sip, struct dentry *sdp,
- struct inode *tip, struct dentry *tdp,
-@@ -15,10 +14,15 @@ AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
- iops __attribute__ ((unused)) = {
- .rename = rename_fn,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
-+ AC_MSG_CHECKING([whether iops->rename() wants flags])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_rename], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1, [iops->rename() wants flags])
-+ AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
-+ [iops->rename() wants flags])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-rw.m4 b/config/kernel-rw.m4
-index 1c8a265e0..85b47d5c6 100644
---- a/config/kernel-rw.m4
-+++ b/config/kernel-rw.m4
-@@ -3,11 +3,8 @@ 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([ZFS_AC_KERNEL_WRITE], [
-- AC_MSG_CHECKING([whether kernel_write() takes loff_t pointer])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_WRITE], [
-+ ZFS_LINUX_TEST_SRC([kernel_write], [
- #include <linux/fs.h>
- ],[
- struct file *file = NULL;
-@@ -17,14 +14,18 @@ AC_DEFUN([ZFS_AC_KERNEL_WRITE], [
- ssize_t ret;
-
- ret = kernel_write(file, buf, count, pos);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_WRITE], [
-+ AC_MSG_CHECKING([whether kernel_write() takes loff_t pointer])
-+ ZFS_LINUX_TEST_RESULT([kernel_write], [
- 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 #
-@@ -32,11 +33,8 @@ 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([ZFS_AC_KERNEL_READ], [
-- AC_MSG_CHECKING([whether kernel_read() takes loff_t pointer])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_READ], [
-+ ZFS_LINUX_TEST_SRC([kernel_read], [
- #include <linux/fs.h>
- ],[
- struct file *file = NULL;
-@@ -46,12 +44,26 @@ AC_DEFUN([ZFS_AC_KERNEL_READ], [
- ssize_t ret;
-
- ret = kernel_read(file, buf, count, pos);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_READ], [
-+ AC_MSG_CHECKING([whether kernel_read() takes loff_t pointer])
-+ ZFS_LINUX_TEST_RESULT([kernel_read], [
- 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"
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_RW], [
-+ ZFS_AC_KERNEL_SRC_WRITE
-+ ZFS_AC_KERNEL_SRC_READ
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_RW], [
-+ ZFS_AC_KERNEL_WRITE
-+ ZFS_AC_KERNEL_READ
- ])
-diff --git a/config/kernel-rwsem.m4 b/config/kernel-rwsem.m4
-index 532c22718..67c5cf908 100644
---- a/config/kernel-rwsem.m4
-+++ b/config/kernel-rwsem.m4
-@@ -4,25 +4,26 @@ dnl #
- dnl # The rw_semaphore.wait_lock member was changed from spinlock_t to
- dnl # raw_spinlock_t at commit ddb6c9b58a19edcfac93ac670b066c836ff729f1.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW], [
-- AC_MSG_CHECKING([whether struct rw_semaphore member wait_lock is raw])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM_SPINLOCK_IS_RAW], [
-+ ZFS_LINUX_TEST_SRC([rwsem_spinlock_is_raw], [
- #include <linux/rwsem.h>
- ],[
- struct rw_semaphore dummy_semaphore __attribute__ ((unused));
- raw_spinlock_t dummy_lock __attribute__ ((unused)) =
- __RAW_SPIN_LOCK_INITIALIZER(dummy_lock);
- dummy_semaphore.wait_lock = dummy_lock;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW], [
-+ AC_MSG_CHECKING([whether struct rw_semaphore member wait_lock is raw])
-+ ZFS_LINUX_TEST_RESULT([rwsem_spinlock_is_raw], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(RWSEM_SPINLOCK_IS_RAW, 1,
-- [struct rw_semaphore member wait_lock is raw_spinlock_t])
-+ [struct rw_semaphore member wait_lock is raw_spinlock_t])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-
- dnl #
-@@ -30,23 +31,24 @@ dnl # 3.16 API Change
- dnl #
- dnl # rwsem-spinlock "->activity" changed to "->count"
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ACTIVITY], [
-- AC_MSG_CHECKING([whether struct rw_semaphore has member activity])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM_ACTIVITY], [
-+ ZFS_LINUX_TEST_SRC([rwsem_activity], [
- #include <linux/rwsem.h>
- ],[
- struct rw_semaphore dummy_semaphore __attribute__ ((unused));
- dummy_semaphore.activity = 0;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ACTIVITY], [
-+ AC_MSG_CHECKING([whether struct rw_semaphore has member activity])
-+ ZFS_LINUX_TEST_RESULT([rwsem_activity], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_RWSEM_ACTIVITY, 1,
-- [struct rw_semaphore has member activity])
-+ [struct rw_semaphore has member activity])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-
- dnl #
-@@ -54,22 +56,35 @@ dnl # 4.8 API Change
- dnl #
- dnl # rwsem "->count" changed to atomic_long_t type
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT], [
-- AC_MSG_CHECKING(
-- [whether struct rw_semaphore has atomic_long_t member count])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM_ATOMIC_LONG_COUNT], [
-+ ZFS_LINUX_TEST_SRC([rwsem_atomic_long_count], [
- #include <linux/rwsem.h>
- ],[
- DECLARE_RWSEM(dummy_semaphore);
- (void) atomic_long_read(&dummy_semaphore.count);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT], [
-+ AC_MSG_CHECKING(
-+ [whether struct rw_semaphore has atomic_long_t member count])
-+ ZFS_LINUX_TEST_RESULT([rwsem_atomic_long_count], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_RWSEM_ATOMIC_LONG_COUNT, 1,
-- [struct rw_semaphore has atomic_long_t member count])
-+ [struct rw_semaphore has atomic_long_t member count])
- ],[
- AC_MSG_RESULT(no)
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM], [
-+ ZFS_AC_KERNEL_SRC_RWSEM_SPINLOCK_IS_RAW
-+ ZFS_AC_KERNEL_SRC_RWSEM_ACTIVITY
-+ ZFS_AC_KERNEL_SRC_RWSEM_ATOMIC_LONG_COUNT
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_RWSEM], [
-+ ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW
-+ ZFS_AC_KERNEL_RWSEM_ACTIVITY
-+ ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT
- ])
-diff --git a/config/kernel-sched.m4 b/config/kernel-sched.m4
-index 640b008aa..4a7db970a 100644
---- a/config/kernel-sched.m4
-+++ b/config/kernel-sched.m4
-@@ -2,14 +2,18 @@ dnl #
- dnl # 3.9 API change,
- dnl # Moved things from linux/sched.h to linux/sched/rt.h
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SCHED_RT_HEADER],
-- [AC_MSG_CHECKING([whether header linux/sched/rt.h exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SCHED_RT_HEADER], [
-+ ZFS_LINUX_TEST_SRC([sched_rt_header], [
- #include <linux/sched.h>
- #include <linux/sched/rt.h>
- ],[
- return 0;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SCHED_RT_HEADER], [
-+ AC_MSG_CHECKING([whether header linux/sched/rt.h exists])
-+ ZFS_LINUX_TEST_RESULT([sched_rt_header], [
- AC_DEFINE(HAVE_SCHED_RT_HEADER, 1, [linux/sched/rt.h exists])
- AC_MSG_RESULT(yes)
- ],[
-@@ -21,36 +25,59 @@ dnl #
- dnl # 4.11 API change,
- dnl # Moved things from linux/sched.h to linux/sched/signal.h
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER],
-- [AC_MSG_CHECKING([whether header linux/sched/signal.h exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SCHED_SIGNAL_HEADER], [
-+ ZFS_LINUX_TEST_SRC([sched_signal_header], [
- #include <linux/sched.h>
- #include <linux/sched/signal.h>
- ],[
- return 0;
-- ],[
-- AC_DEFINE(HAVE_SCHED_SIGNAL_HEADER, 1, [linux/sched/signal.h exists])
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER], [
-+ AC_MSG_CHECKING([whether header linux/sched/signal.h exists])
-+ ZFS_LINUX_TEST_RESULT([sched_signal_header], [
-+ AC_DEFINE(HAVE_SCHED_SIGNAL_HEADER, 1,
-+ [linux/sched/signal.h exists])
- AC_MSG_RESULT(yes)
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-+
- dnl #
- dnl # 3.19 API change
- dnl # The io_schedule_timeout() function is present in all 2.6.32 kernels
- dnl # but it was not exported until Linux 3.19. The RHEL 7.x kernels which
- dnl # are based on a 3.10 kernel do export this symbol.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT], [
-- AC_MSG_CHECKING([whether io_schedule_timeout() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_IO_SCHEDULE_TIMEOUT], [
-+ ZFS_LINUX_TEST_SRC([io_schedule_timeout], [
- #include <linux/sched.h>
- ], [
- (void) io_schedule_timeout(1);
-- ], [io_schedule_timeout], [], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT], [
-+ AC_MSG_CHECKING([whether io_schedule_timeout() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([io_schedule_timeout],
-+ [io_schedule_timeout], [], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_IO_SCHEDULE_TIMEOUT, 1, [yes])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SCHED], [
-+ ZFS_AC_KERNEL_SRC_SCHED_RT_HEADER
-+ ZFS_AC_KERNEL_SRC_SCHED_SIGNAL_HEADER
-+ ZFS_AC_KERNEL_SRC_IO_SCHEDULE_TIMEOUT
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SCHED], [
-+ ZFS_AC_KERNEL_SCHED_RT_HEADER
-+ ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER
-+ ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT
-+])
-diff --git a/config/kernel-security-inode-init.m4 b/config/kernel-security-inode-init.m4
-index a62176d42..0dea7e392 100644
---- a/config/kernel-security-inode-init.m4
-+++ b/config/kernel-security-inode-init.m4
-@@ -5,9 +5,8 @@ dnl # qstr argument which must be passed in from the dentry if available.
- dnl # Passing a NULL is safe when no qstr is available the relevant
- dnl # security checks will just be skipped.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY], [
-- AC_MSG_CHECKING([whether security_inode_init_security wants 6 args])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_6ARGS], [
-+ ZFS_LINUX_TEST_SRC([security_inode_init_security_6args], [
- #include <linux/security.h>
- ],[
- struct inode *ip __attribute__ ((unused)) = NULL;
-@@ -18,10 +17,15 @@ AC_DEFUN([ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY], [
- size_t len __attribute__ ((unused)) = 0;
-
- security_inode_init_security(ip, dip, str, &name, &value, &len);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_6ARGS], [
-+ AC_MSG_CHECKING([whether security_inode_init_security wants 6 args])
-+ ZFS_LINUX_TEST_RESULT([security_inode_init_security_6args], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY, 1,
-- [security_inode_init_security wants 6 args])
-+ [security_inode_init_security wants 6 args])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -34,9 +38,8 @@ dnl # a filesystem specific callback to write security extended attributes.
- dnl # This was done to support the initialization of multiple LSM xattrs
- dnl # and the EVM xattr.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY], [
-- AC_MSG_CHECKING([whether security_inode_init_security wants callback])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_CALLBACK], [
-+ ZFS_LINUX_TEST_SRC([security_inode_init_security], [
- #include <linux/security.h>
- ],[
- struct inode *ip __attribute__ ((unused)) = NULL;
-@@ -45,11 +48,26 @@ AC_DEFUN([ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY], [
- initxattrs func __attribute__ ((unused)) = NULL;
-
- security_inode_init_security(ip, dip, str, func, NULL);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_CALLBACK], [
-+ AC_MSG_CHECKING([whether security_inode_init_security wants callback])
-+ ZFS_LINUX_TEST_RESULT([security_inode_init_security], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY, 1,
-- [security_inode_init_security wants callback])
-+ [security_inode_init_security wants callback])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SECURITY_INODE], [
-+ ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_6ARGS
-+ ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_CALLBACK
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SECURITY_INODE], [
-+ ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_6ARGS
-+ ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_CALLBACK
-+])
-diff --git a/config/kernel-set-nlink.m4 b/config/kernel-set-nlink.m4
-index f7ffc0d3a..63a5a8c0d 100644
---- a/config/kernel-set-nlink.m4
-+++ b/config/kernel-set-nlink.m4
-@@ -2,18 +2,21 @@ dnl #
- dnl # Linux v3.2-rc1 API change
- dnl # SHA: bfe8684869601dacfcb2cd69ef8cfd9045f62170
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SET_NLINK], [
-- AC_MSG_CHECKING([whether set_nlink() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_NLINK], [
-+ ZFS_LINUX_TEST_SRC([set_nlink], [
- #include <linux/fs.h>
- ],[
- struct inode node;
- unsigned int link = 0;
- (void) set_nlink(&node, link);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SET_NLINK], [
-+ AC_MSG_CHECKING([whether set_nlink() is available])
-+ ZFS_LINUX_TEST_RESULT([set_nlink], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_SET_NLINK, 1,
-- [set_nlink() is available])
-+ AC_DEFINE(HAVE_SET_NLINK, 1, [set_nlink() is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-setattr-prepare.m4 b/config/kernel-setattr-prepare.m4
-index 32f7deb77..45408c45c 100644
---- a/config/kernel-setattr-prepare.m4
-+++ b/config/kernel-setattr-prepare.m4
-@@ -3,17 +3,21 @@ dnl # 4.9 API change
- dnl # The inode_change_ok() function has been renamed setattr_prepare()
- dnl # and updated to take a dentry rather than an inode.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE],
-- [AC_MSG_CHECKING([whether setattr_prepare() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
-+ ZFS_LINUX_TEST_SRC([setattr_prepare], [
- #include <linux/fs.h>
- ], [
- struct dentry *dentry = NULL;
- struct iattr *attr = NULL;
-- int error;
-+ int error __attribute__ ((unused)) =
-+ setattr_prepare(dentry, attr);
-+ ])
-+])
-
-- error = setattr_prepare(dentry, attr);
-- ], [setattr_prepare], [fs/attr.c], [
-+AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
-+ AC_MSG_CHECKING([whether setattr_prepare() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare],
-+ [setattr_prepare], [fs/attr.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SETATTR_PREPARE, 1,
- [setattr_prepare() is available])
-diff --git a/config/kernel-sget-args.m4 b/config/kernel-sget-args.m4
-index 9d1745925..13581399e 100644
---- a/config/kernel-sget-args.m4
-+++ b/config/kernel-sget-args.m4
-@@ -2,9 +2,8 @@ dnl #
- dnl # 3.6 API change,
- dnl # 'sget' now takes the mount flags as an argument.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_5ARG_SGET],
-- [AC_MSG_CHECKING([whether sget() wants 5 args])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SGET], [
-+ ZFS_LINUX_TEST_SRC([sget_5args], [
- #include <linux/fs.h>
- ],[
- struct file_system_type *type = NULL;
-@@ -13,11 +12,15 @@ AC_DEFUN([ZFS_AC_KERNEL_5ARG_SGET],
- int flags = 0;
- void *data = NULL;
- (void) sget(type, test, set, flags, data);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SGET], [
-+ AC_MSG_CHECKING([whether sget() wants 5 args])
-+ ZFS_LINUX_TEST_RESULT([sget_5args], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_5ARG_SGET, 1, [sget() wants 5 args])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
--
-diff --git a/config/kernel-show-options.m4 b/config/kernel-show-options.m4
-index 67d683c55..9e426bc39 100644
---- a/config/kernel-show-options.m4
-+++ b/config/kernel-show-options.m4
-@@ -1,21 +1,26 @@
- dnl #
- dnl # Linux 3.3 API
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SHOW_OPTIONS], [
-- AC_MSG_CHECKING([whether sops->show_options() wants dentry])
--
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SHOW_OPTIONS], [
-+ ZFS_LINUX_TEST_SRC([super_operations_show_options], [
- #include <linux/fs.h>
-
-- int show_options (struct seq_file * x, struct dentry * y) { return 0; };
-+ int show_options(struct seq_file * x, struct dentry * y) {
-+ return 0;
-+ };
-+
- static struct super_operations sops __attribute__ ((unused)) = {
- .show_options = show_options,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SHOW_OPTIONS], [
-+ AC_MSG_CHECKING([whether sops->show_options() wants dentry])
-+ ZFS_LINUX_TEST_RESULT([super_operations_show_options], [
- AC_MSG_RESULT([yes])
- AC_DEFINE(HAVE_SHOW_OPTIONS_WITH_DENTRY, 1,
-- [sops->show_options() with dentry])
-+ [sops->show_options() with dentry])
- ],[
- AC_MSG_RESULT([no])
- ])
-diff --git a/config/kernel-shrink.m4 b/config/kernel-shrink.m4
-index 405cbf42c..45b4b5d4b 100644
---- a/config/kernel-shrink.m4
-+++ b/config/kernel-shrink.m4
-@@ -4,9 +4,8 @@ dnl # The super_block structure now stores a per-filesystem shrinker.
- dnl # This interface is preferable because it can be used to specifically
- dnl # target only the zfs filesystem for pruning.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SHRINK], [
-- AC_MSG_CHECKING([whether super_block has s_shrink])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK], [
-+ ZFS_LINUX_TEST_SRC([super_block_s_shrink], [
- #include <linux/fs.h>
-
- int shrink(struct shrinker *s, struct shrink_control *sc)
-@@ -18,8 +17,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINK], [
- .s_shrink.seeks = DEFAULT_SEEKS,
- .s_shrink.batch = 0,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK], [
-+ AC_MSG_CHECKING([whether super_block has s_shrink])
-+ ZFS_LINUX_TEST_RESULT([super_block_s_shrink], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SHRINK, 1, [struct super_block has s_shrink])
-
-@@ -50,15 +53,18 @@ dnl # a list_head is used. Then to prevent the spinning from occurring
- dnl # the .next pointer is set to the fs_supers list_head which ensures
- dnl # the iterate_supers_type() function will always terminate.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD], [
-- AC_MSG_CHECKING([whether super_block has s_instances list_head])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_INSTANCES_LIST_HEAD], [
-+ ZFS_LINUX_TEST_SRC([super_block_s_instances_list_head], [
- #include <linux/fs.h>
- ],[
- struct super_block sb __attribute__ ((unused));
--
- INIT_LIST_HEAD(&sb.s_instances);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_INSTANCES_LIST_HEAD], [
-+ AC_MSG_CHECKING([whether super_block has s_instances list_head])
-+ ZFS_LINUX_TEST_RESULT([super_block_s_instances_list_head], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_S_INSTANCES_LIST_HEAD, 1,
- [struct super_block has s_instances list_head])
-@@ -67,9 +73,8 @@ AC_DEFUN([ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD], [
- ])
- ])
-
--AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [
-- AC_MSG_CHECKING([whether sops->nr_cached_objects() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_NR_CACHED_OBJECTS], [
-+ ZFS_LINUX_TEST_SRC([nr_cached_objects], [
- #include <linux/fs.h>
-
- int nr_cached_objects(struct super_block *sb) { return 0; }
-@@ -78,19 +83,22 @@ AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [
- sops __attribute__ ((unused)) = {
- .nr_cached_objects = nr_cached_objects,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [
-+ AC_MSG_CHECKING([whether sops->nr_cached_objects() exists])
-+ ZFS_LINUX_TEST_RESULT([nr_cached_objects], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_NR_CACHED_OBJECTS, 1,
-- [sops->nr_cached_objects() exists])
-+ [sops->nr_cached_objects() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-
--AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [
-- AC_MSG_CHECKING([whether sops->free_cached_objects() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_FREE_CACHED_OBJECTS], [
-+ ZFS_LINUX_TEST_SRC([free_cached_objects], [
- #include <linux/fs.h>
-
- void free_cached_objects(struct super_block *sb, int x)
-@@ -100,11 +108,15 @@ AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [
- sops __attribute__ ((unused)) = {
- .free_cached_objects = free_cached_objects,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [
-+ AC_MSG_CHECKING([whether sops->free_cached_objects() exists])
-+ ZFS_LINUX_TEST_RESULT([free_cached_objects], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_FREE_CACHED_OBJECTS, 1,
-- [sops->free_cached_objects() exists])
-+ [sops->free_cached_objects() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -115,15 +127,19 @@ dnl # 3.12 API change
- dnl # The nid member was added to struct shrink_control to support
- dnl # NUMA-aware shrinkers.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
-- AC_MSG_CHECKING([whether shrink_control has nid])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID], [
-+ ZFS_LINUX_TEST_SRC([shrink_control_nid], [
- #include <linux/fs.h>
- ],[
- struct shrink_control sc __attribute__ ((unused));
- unsigned long scnidsize __attribute__ ((unused)) =
- sizeof(sc.nid);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
-+ AC_MSG_CHECKING([whether shrink_control has nid])
-+ ZFS_LINUX_TEST_RESULT([shrink_control_nid], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(SHRINK_CONTROL_HAS_NID, 1,
- [struct shrink_control has nid])
-@@ -132,84 +148,96 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
- ])
- ])
-
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [
-+ ZFS_LINUX_TEST_SRC([shrinker_cb_2arg], [
-+ #include <linux/mm.h>
-+ int shrinker_cb(int nr_to_scan, gfp_t gfp_mask) { return 0; }
-+ ],[
-+ struct shrinker cache_shrinker = {
-+ .shrink = shrinker_cb,
-+ .seeks = DEFAULT_SEEKS,
-+ };
-+ register_shrinker(&cache_shrinker);
-+ ])
-
--AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
-- dnl #
-- dnl # 2.6.23 to 2.6.34 API change
-- dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask)
-- dnl #
-- AC_MSG_CHECKING([whether old 2-argument shrinker exists])
-- ZFS_LINUX_TRY_COMPILE([
-+ ZFS_LINUX_TEST_SRC([shrinker_cb_3arg], [
- #include <linux/mm.h>
-+ int shrinker_cb(struct shrinker *shrink, int nr_to_scan,
-+ gfp_t gfp_mask) { return 0; }
-+ ],[
-+ struct shrinker cache_shrinker = {
-+ .shrink = shrinker_cb,
-+ .seeks = DEFAULT_SEEKS,
-+ };
-+ register_shrinker(&cache_shrinker);
-+ ])
-
-- int shrinker_cb(int nr_to_scan, gfp_t gfp_mask) {
-- return 0;
-- }
-+ ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control], [
-+ #include <linux/mm.h>
-+ int shrinker_cb(struct shrinker *shrink,
-+ struct shrink_control *sc) { return 0; }
- ],[
- struct shrinker cache_shrinker = {
- .shrink = shrinker_cb,
- .seeks = DEFAULT_SEEKS,
- };
- register_shrinker(&cache_shrinker);
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control_split], [
-+ #include <linux/mm.h>
-+ unsigned long shrinker_cb(struct shrinker *shrink,
-+ struct shrink_control *sc) { return 0; }
- ],[
-+ struct shrinker cache_shrinker = {
-+ .count_objects = shrinker_cb,
-+ .scan_objects = shrinker_cb,
-+ .seeks = DEFAULT_SEEKS,
-+ };
-+ register_shrinker(&cache_shrinker);
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
-+ dnl #
-+ dnl # 2.6.23 to 2.6.34 API change
-+ dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask)
-+ dnl #
-+ AC_MSG_CHECKING([whether old 2-argument shrinker exists])
-+ ZFS_LINUX_TEST_RESULT([shrinker_cb_2arg], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_2ARGS_OLD_SHRINKER_CALLBACK, 1,
-- [old shrinker callback wants 2 args])
-+ [old shrinker callback wants 2 args])
- ],[
- AC_MSG_RESULT(no)
-+
- dnl #
- dnl # 2.6.35 - 2.6.39 API change
- dnl # ->shrink(struct shrinker *,
- dnl # int nr_to_scan, gfp_t gfp_mask)
- dnl #
- AC_MSG_CHECKING([whether old 3-argument shrinker exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/mm.h>
--
-- int shrinker_cb(struct shrinker *shrink, int nr_to_scan,
-- gfp_t gfp_mask) {
-- return 0;
-- }
-- ],[
-- struct shrinker cache_shrinker = {
-- .shrink = shrinker_cb,
-- .seeks = DEFAULT_SEEKS,
-- };
-- register_shrinker(&cache_shrinker);
-- ],[
-+ ZFS_LINUX_TEST_RESULT([shrinker_cb_3arg], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1,
- [old shrinker callback wants 3 args])
- ],[
- AC_MSG_RESULT(no)
-+
- dnl #
- dnl # 3.0 - 3.11 API change
- dnl # ->shrink(struct shrinker *,
- dnl # struct shrink_control *sc)
- dnl #
- AC_MSG_CHECKING(
-- [whether new 2-argument shrinker exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/mm.h>
--
-- int shrinker_cb(struct shrinker *shrink,
-- struct shrink_control *sc) {
-- return 0;
-- }
-- ],[
-- struct shrinker cache_shrinker = {
-- .shrink = shrinker_cb,
-- .seeks = DEFAULT_SEEKS,
-- };
-- register_shrinker(&cache_shrinker);
-- ],[
-+ [whether new 2-argument shrinker exists])
-+ ZFS_LINUX_TEST_RESULT([shrinker_cb_shrink_control], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_2ARGS_NEW_SHRINKER_CALLBACK, 1,
- [new shrinker callback wants 2 args])
- ],[
- AC_MSG_RESULT(no)
-+
- dnl #
- dnl # 3.12 API change,
- dnl # ->shrink() is logically split in to
-@@ -217,52 +245,61 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
- dnl #
- AC_MSG_CHECKING(
- [whether ->count_objects callback exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/mm.h>
--
-- unsigned long shrinker_cb(
-- struct shrinker *shrink,
-- struct shrink_control *sc) {
-- return 0;
-- }
-- ],[
-- struct shrinker cache_shrinker = {
-- .count_objects = shrinker_cb,
-- .scan_objects = shrinker_cb,
-- .seeks = DEFAULT_SEEKS,
-- };
-- register_shrinker(&cache_shrinker);
-- ],[
-+ ZFS_LINUX_TEST_RESULT(
-+ [shrinker_cb_shrink_control_split], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK,
- 1, [->count_objects exists])
- ],[
-- AC_MSG_ERROR(error)
-+ ZFS_LINUX_TEST_ERROR([shrinker])
- ])
- ])
- ])
- ])
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-
- dnl #
- dnl # 2.6.39 API change,
- dnl # Shrinker adjust to use common shrink_control structure.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT], [
-- AC_MSG_CHECKING([whether struct shrink_control exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT], [
-+ ZFS_LINUX_TEST_SRC([shrink_control_struct], [
- #include <linux/mm.h>
- ],[
- struct shrink_control sc __attribute__ ((unused));
-
- sc.nr_to_scan = 0;
- sc.gfp_mask = GFP_KERNEL;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT], [
-+ AC_MSG_CHECKING([whether struct shrink_control exists])
-+ ZFS_LINUX_TEST_RESULT([shrink_control_struct], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SHRINK_CONTROL_STRUCT, 1,
-- [struct shrink_control exists])
-+ [struct shrink_control exists])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER], [
-+ ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK
-+ ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_INSTANCES_LIST_HEAD
-+ ZFS_AC_KERNEL_SRC_NR_CACHED_OBJECTS
-+ ZFS_AC_KERNEL_SRC_FREE_CACHED_OBJECTS
-+ ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID
-+ ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK
-+ ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SHRINKER], [
-+ ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK
-+ ZFS_AC_KERNEL_SUPER_BLOCK_S_INSTANCES_LIST_HEAD
-+ ZFS_AC_KERNEL_NR_CACHED_OBJECTS
-+ ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
-+ ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID
-+ ZFS_AC_KERNEL_SHRINKER_CALLBACK
-+ ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT
-+])
-diff --git a/config/kernel-submit_bio.m4 b/config/kernel-submit_bio.m4
-index da5f85ca7..cf80e9b83 100644
---- a/config/kernel-submit_bio.m4
-+++ b/config/kernel-submit_bio.m4
-@@ -3,15 +3,19 @@ dnl # 4.8 API change
- dnl # The rw argument has been removed from submit_bio/submit_bio_wait.
- dnl # Callers are now expected to set bio->bi_rw instead of passing it in.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SUBMIT_BIO], [
-- AC_MSG_CHECKING([whether submit_bio() wants 1 arg])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SUBMIT_BIO], [
-+ ZFS_LINUX_TEST_SRC([submit_bio], [
- #include <linux/bio.h>
- ],[
- blk_qc_t blk_qc;
- struct bio *bio = NULL;
- blk_qc = submit_bio(bio);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SUBMIT_BIO], [
-+ AC_MSG_CHECKING([whether submit_bio() wants 1 arg])
-+ ZFS_LINUX_TEST_RESULT([submit_bio], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_1ARG_SUBMIT_BIO, 1, [submit_bio() wants 1 arg])
- ],[
-diff --git a/config/kernel-super-userns.m4 b/config/kernel-super-userns.m4
-index de94ad967..1ad35f2d1 100644
---- a/config/kernel-super-userns.m4
-+++ b/config/kernel-super-userns.m4
-@@ -3,15 +3,19 @@ dnl # 4.8 API change
- dnl # struct user_namespace was added to struct super_block as
- dnl # super->s_user_ns member
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_SUPER_USER_NS], [
-- AC_MSG_CHECKING([whether super_block->s_user_ns exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_USER_NS], [
-+ ZFS_LINUX_TEST_SRC([super_user_ns], [
- #include <linux/fs.h>
- #include <linux/user_namespace.h>
-- ],[
-+ ], [
- struct super_block super;
- super.s_user_ns = (struct user_namespace *)NULL;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SUPER_USER_NS], [
-+ AC_MSG_CHECKING([whether super_block->s_user_ns exists])
-+ ZFS_LINUX_TEST_RESULT([super_user_ns], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SUPER_USER_NS, 1,
- [super_block->s_user_ns exists])
-diff --git a/config/kernel-timer.m4 b/config/kernel-timer.m4
-index b0e1afa15..5e8fc0d3a 100644
---- a/config/kernel-timer.m4
-+++ b/config/kernel-timer.m4
-@@ -8,13 +8,9 @@ dnl # kernels that support the new timer_list.func signature.
- dnl #
- dnl # Also check for the existance of flags in struct timer_list, they were
- dnl # added in 4.1-rc8 via 0eeda71bc30d.
--
--AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
-- AC_MSG_CHECKING([whether timer_setup() is available])
-- tmp_flags="$EXTRA_KCFLAGS"
-- EXTRA_KCFLAGS="-Werror"
--
-- ZFS_LINUX_TRY_COMPILE([
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_TIMER_SETUP], [
-+ ZFS_LINUX_TEST_SRC([timer_setup], [
- #include <linux/timer.h>
-
- struct my_task_timer {
-@@ -24,13 +20,34 @@ AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
-
- void task_expire(struct timer_list *tl)
- {
-- struct my_task_timer *task_timer = from_timer(task_timer, tl, timer);
-+ struct my_task_timer *task_timer =
-+ from_timer(task_timer, tl, timer);
- task_timer->data = 42;
- }
- ],[
- struct my_task_timer task_timer;
- timer_setup(&task_timer.timer, task_expire, 0);
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([timer_list_function], [
-+ #include <linux/timer.h>
-+ void task_expire(struct timer_list *tl) {}
- ],[
-+ struct timer_list tl;
-+ tl.function = task_expire;
-+ ])
-+
-+ ZFS_LINUX_TEST_SRC([timer_list_flags], [
-+ #include <linux/timer.h>
-+ ],[
-+ struct timer_list tl;
-+ tl.flags = 2;
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
-+ AC_MSG_CHECKING([whether timer_setup() is available])
-+ ZFS_LINUX_TEST_RESULT([timer_setup], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_KERNEL_TIMER_SETUP, 1,
- [timer_setup() is available])
-@@ -39,14 +56,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
- ])
-
- AC_MSG_CHECKING([whether timer function expects timer_list])
--
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/timer.h>
-- void task_expire(struct timer_list *tl) {}
-- ],[
-- struct timer_list tl;
-- tl.function = task_expire;
-- ],[
-+ ZFS_LINUX_TEST_RESULT([timer_list_function], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST, 1,
- [timer_list.function gets a timer_list])
-@@ -55,19 +65,11 @@ AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [
- ])
-
- AC_MSG_CHECKING([whether struct timer_list has flags])
--
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/timer.h>
-- ],[
-- struct timer_list tl;
-- tl.flags = 2;
-- ],[
-+ ZFS_LINUX_TEST_RESULT([timer_list_flags], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_KERNEL_TIMER_LIST_FLAGS, 1,
- [struct timer_list has a flags member])
- ],[
- AC_MSG_RESULT(no)
- ])
--
-- EXTRA_KCFLAGS="$tmp_flags"
- ])
-diff --git a/config/kernel-tmpfile.m4 b/config/kernel-tmpfile.m4
-index 5aad90450..f510bfe6b 100644
---- a/config/kernel-tmpfile.m4
-+++ b/config/kernel-tmpfile.m4
-@@ -2,9 +2,8 @@ dnl #
- dnl # 3.11 API change
- dnl # Add support for i_op->tmpfile
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
-- AC_MSG_CHECKING([whether i_op->tmpfile() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
- #include <linux/fs.h>
- int tmpfile(struct inode *inode, struct dentry *dentry,
- umode_t mode) { return 0; }
-@@ -12,11 +11,14 @@ AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
- iops __attribute__ ((unused)) = {
- .tmpfile = tmpfile,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
-+ AC_MSG_CHECKING([whether i_op->tmpfile() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_TMPFILE, 1,
-- [i_op->tmpfile() exists])
-+ AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-totalhigh_pages.m4 b/config/kernel-totalhigh_pages.m4
-index b22e86d4d..4ecb03a50 100644
---- a/config/kernel-totalhigh_pages.m4
-+++ b/config/kernel-totalhigh_pages.m4
-@@ -1,16 +1,18 @@
- dnl #
- dnl # 5.0 API change
- dnl #
--dnl # ca79b0c211af mm: convert totalram_pages and totalhigh_pages variables to atomic
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_TOTALHIGH_PAGES], [
-- AC_MSG_CHECKING([whether totalhigh_pages() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES], [
-+ ZFS_LINUX_TEST_SRC([totalhigh_pages], [
- #include <linux/highmem.h>
- ],[
- unsigned long pages __attribute__ ((unused));
- pages = totalhigh_pages();
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_TOTALHIGH_PAGES], [
-+ AC_MSG_CHECKING([whether totalhigh_pages() exists])
-+ ZFS_LINUX_TEST_RESULT([totalhigh_pages], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_TOTALHIGH_PAGES, 1, [totalhigh_pages() exists])
- ],[
-diff --git a/config/kernel-totalram-pages-func.m4 b/config/kernel-totalram-pages-func.m4
-index a6eac6454..d0e812a8d 100644
---- a/config/kernel-totalram-pages-func.m4
-+++ b/config/kernel-totalram-pages-func.m4
-@@ -2,16 +2,21 @@ dnl #
- dnl # Linux 5.0: totalram_pages is no longer a global variable, and must be
- dnl # read via the totalram_pages() helper function.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC], [
-- AC_MSG_CHECKING([whether totalram_pages() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_TOTALRAM_PAGES_FUNC], [
-+ ZFS_LINUX_TEST_SRC([totalram_pages], [
- #include <linux/mm.h>
- ],[
- unsigned long pages __attribute__ ((unused));
- pages = totalram_pages();
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC], [
-+ AC_MSG_CHECKING([whether totalram_pages() exists])
-+ ZFS_LINUX_TEST_RESULT([totalram_pages], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_TOTALRAM_PAGES_FUNC, 1, [kernel has totalram_pages()])
-+ AC_DEFINE(HAVE_TOTALRAM_PAGES_FUNC, 1,
-+ [kernel has totalram_pages()])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-truncate-range.m4 b/config/kernel-truncate-range.m4
-index da2cb50fc..8fdbb1086 100644
---- a/config/kernel-truncate-range.m4
-+++ b/config/kernel-truncate-range.m4
-@@ -4,17 +4,20 @@ dnl # torvalds/linux@17cf28afea2a1112f240a3a2da8af883be024811 removed
- dnl # truncate_range(). The file hole punching functionality is now
- dnl # provided by fallocate()
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_RANGE], [
-- AC_MSG_CHECKING([whether iops->truncate_range() exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_TRUNCATE_RANGE], [
-+ ZFS_LINUX_TEST_SRC([inode_operations_truncate_range], [
- #include <linux/fs.h>
- void truncate_range(struct inode *inode, loff_t start,
- loff_t end) { return; }
- static struct inode_operations iops __attribute__ ((unused)) = {
- .truncate_range = truncate_range,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_RANGE], [
-+ AC_MSG_CHECKING([whether iops->truncate_range() exists])
-+ ZFS_LINUX_TEST_RESULT([inode_operations_truncate_range], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_INODE_TRUNCATE_RANGE, 1,
- [iops->truncate_range() exists])
-diff --git a/config/kernel-truncate-setsize.m4 b/config/kernel-truncate-setsize.m4
-index 7e4aff479..e719c1444 100644
---- a/config/kernel-truncate-setsize.m4
-+++ b/config/kernel-truncate-setsize.m4
-@@ -2,16 +2,21 @@ dnl #
- dnl # 2.6.35 API change
- dnl # Added truncate_setsize() helper function.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_SETSIZE],
-- [AC_MSG_CHECKING([whether truncate_setsize() is available])
-- ZFS_LINUX_TRY_COMPILE_SYMBOL([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE], [
-+ ZFS_LINUX_TEST_SRC([truncate_setsize], [
- #include <linux/mm.h>
- ], [
- truncate_setsize(NULL, 0);
-- ], [truncate_setsize], [mm/truncate.c], [
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_SETSIZE], [
-+ AC_MSG_CHECKING([whether truncate_setsize() is available])
-+ ZFS_LINUX_TEST_RESULT_SYMBOL([truncate_setsize],
-+ [truncate_setsize], [mm/truncate.c], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_TRUNCATE_SETSIZE, 1,
-- [truncate_setsize() is available])
-+ [truncate_setsize() is available])
- ], [
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-userns-capabilities.m4 b/config/kernel-userns-capabilities.m4
-index fa3381978..5dcbc03d3 100644
---- a/config/kernel-userns-capabilities.m4
-+++ b/config/kernel-userns-capabilities.m4
-@@ -2,16 +2,19 @@ dnl #
- dnl # 2.6.38 API change
- dnl # ns_capable() was introduced
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_NS_CAPABLE], [
-- AC_MSG_CHECKING([whether ns_capable exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_NS_CAPABLE], [
-+ ZFS_LINUX_TEST_SRC([ns_capable], [
- #include <linux/capability.h>
- ],[
- ns_capable((struct user_namespace *)NULL, CAP_SYS_ADMIN);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_NS_CAPABLE], [
-+ AC_MSG_CHECKING([whether ns_capable exists])
-+ ZFS_LINUX_TEST_RESULT([ns_capable], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_NS_CAPABLE, 1,
-- [ns_capable exists])
-+ AC_DEFINE(HAVE_NS_CAPABLE, 1, [ns_capable exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -23,17 +26,20 @@ dnl # struct user_namespace was added to struct cred_t as
- dnl # cred->user_ns member
- dnl # Note that current_user_ns() was added in 2.6.28.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CRED_USER_NS], [
-- AC_MSG_CHECKING([whether cred_t->user_ns exists])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CRED_USER_NS], [
-+ ZFS_LINUX_TEST_SRC([cred_user_ns], [
- #include <linux/cred.h>
- ],[
- struct cred cr;
- cr.user_ns = (struct user_namespace *)NULL;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CRED_USER_NS], [
-+ AC_MSG_CHECKING([whether cred_t->user_ns exists])
-+ ZFS_LINUX_TEST_RESULT([cred_user_ns], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_CRED_USER_NS, 1,
-- [cred_t->user_ns exists])
-+ AC_DEFINE(HAVE_CRED_USER_NS, 1, [cred_t->user_ns exists])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -44,14 +50,18 @@ dnl # 3.4 API change
- dnl # kuid_has_mapping() and kgid_has_mapping() were added to distinguish
- dnl # between internal kernel uids/gids and user namespace uids/gids.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_KUID_HAS_MAPPING], [
-- AC_MSG_CHECKING([whether kuid_has_mapping/kgid_has_mapping exist])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_KUID_HAS_MAPPING], [
-+ ZFS_LINUX_TEST_SRC([kuid_has_mapping], [
- #include <linux/uidgid.h>
- ],[
- kuid_has_mapping((struct user_namespace *)NULL, KUIDT_INIT(0));
- kgid_has_mapping((struct user_namespace *)NULL, KGIDT_INIT(0));
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_KUID_HAS_MAPPING], [
-+ AC_MSG_CHECKING([whether kuid_has_mapping/kgid_has_mapping exist])
-+ ZFS_LINUX_TEST_RESULT([kuid_has_mapping], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_KUID_HAS_MAPPING, 1,
- [kuid_has_mapping/kgid_has_mapping exist])
-@@ -60,6 +70,12 @@ AC_DEFUN([ZFS_AC_KERNEL_KUID_HAS_MAPPING], [
- ])
- ])
-
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES], [
-+ ZFS_AC_KERNEL_SRC_NS_CAPABLE
-+ ZFS_AC_KERNEL_SRC_CRED_USER_NS
-+ ZFS_AC_KERNEL_SRC_KUID_HAS_MAPPING
-+])
-+
- AC_DEFUN([ZFS_AC_KERNEL_USERNS_CAPABILITIES], [
- ZFS_AC_KERNEL_NS_CAPABLE
- ZFS_AC_KERNEL_CRED_USER_NS
-diff --git a/config/kernel-urange-sleep.m4 b/config/kernel-usleep_range.m4
-similarity index 60%
-rename from config/kernel-urange-sleep.m4
-rename to config/kernel-usleep_range.m4
-index b5764de3e..5bf051ab4 100644
---- a/config/kernel-urange-sleep.m4
-+++ b/config/kernel-usleep_range.m4
-@@ -1,20 +1,23 @@
- dnl #
--dnl # 2.6.36 API compatibility.
--dnl # Added usleep_range timer.
-+dnl # 2.6.36 API compatibility- Added usleep_range timer.
-+dnl #
- dnl # usleep_range is a finer precision implementation of msleep
- dnl # designed to be a drop-in replacement for udelay where a precise
- dnl # sleep / busy-wait is unnecessary.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_USLEEP_RANGE], [
-- AC_MSG_CHECKING([whether usleep_range() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_USLEEP_RANGE], [
-+ ZFS_LINUX_TEST_SRC([usleep_range], [
- #include <linux/delay.h>
- ],[
- usleep_range(0, 0);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_USLEEP_RANGE], [
-+ AC_MSG_CHECKING([whether usleep_range() is available])
-+ ZFS_LINUX_TEST_RESULT([usleep_range], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_USLEEP_RANGE, 1,
-- [usleep_range is available])
-+ AC_DEFINE(HAVE_USLEEP_RANGE, 1, [usleep_range is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-vfs-direct_IO.m4 b/config/kernel-vfs-direct_IO.m4
-index cc50bfbe4..82583d52f 100644
---- a/config/kernel-vfs-direct_IO.m4
-+++ b/config/kernel-vfs-direct_IO.m4
-@@ -1,9 +1,8 @@
- dnl #
--dnl # Linux 4.6.x API change
-+dnl # Check for direct IO interfaces.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER], [
-- AC_MSG_CHECKING([whether aops->direct_IO() uses iov_iter])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO], [
-+ ZFS_LINUX_TEST_SRC([direct_io_iter], [
- #include <linux/fs.h>
-
- ssize_t test_direct_IO(struct kiocb *kiocb,
-@@ -13,24 +12,9 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER], [
- aops __attribute__ ((unused)) = {
- .direct_IO = test_direct_IO,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT([yes])
-- AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER, 1,
-- [aops->direct_IO() uses iov_iter without rw])
-- zfs_ac_direct_io="yes"
-- ],[
-- AC_MSG_RESULT([no])
-- ])
--])
-+ ],[])
-
--dnl #
--dnl # Linux 4.1.x API change
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_OFFSET], [
-- AC_MSG_CHECKING(
-- [whether aops->direct_IO() uses iov_iter with offset])
-- ZFS_LINUX_TRY_COMPILE([
-+ ZFS_LINUX_TEST_SRC([direct_io_iter_offset], [
- #include <linux/fs.h>
-
- ssize_t test_direct_IO(struct kiocb *kiocb,
-@@ -40,24 +24,9 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_OFFSET], [
- aops __attribute__ ((unused)) = {
- .direct_IO = test_direct_IO,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT([yes])
-- AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_OFFSET, 1,
-- [aops->direct_IO() uses iov_iter with offset])
-- zfs_ac_direct_io="yes"
-- ],[
-- AC_MSG_RESULT([no])
-- ])
--])
-+ ],[])
-
--dnl #
--dnl # Linux 3.16.x API change
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_RW_OFFSET], [
-- AC_MSG_CHECKING(
-- [whether aops->direct_IO() uses iov_iter with rw and offset])
-- ZFS_LINUX_TRY_COMPILE([
-+ ZFS_LINUX_TEST_SRC([direct_io_iter_rw_offset], [
- #include <linux/fs.h>
-
- ssize_t test_direct_IO(int rw, struct kiocb *kiocb,
-@@ -67,23 +36,9 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_RW_OFFSET], [
- aops __attribute__ ((unused)) = {
- .direct_IO = test_direct_IO,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT([yes])
-- AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_RW_OFFSET, 1,
-- [aops->direct_IO() uses iov_iter with rw and offset])
-- zfs_ac_direct_io="yes"
-- ],[
-- AC_MSG_RESULT([no])
-- ])
--])
-+ ],[])
-
--dnl #
--dnl # Ancient Linux API (predates git)
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_IOVEC], [
-- AC_MSG_CHECKING([whether aops->direct_IO() uses iovec])
-- ZFS_LINUX_TRY_COMPILE([
-+ ZFS_LINUX_TEST_SRC([direct_io_iovec], [
- #include <linux/fs.h>
-
- ssize_t test_direct_IO(int rw, struct kiocb *kiocb,
-@@ -94,37 +49,61 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO_IOVEC], [
- aops __attribute__ ((unused)) = {
- .direct_IO = test_direct_IO,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT([yes])
-- AC_DEFINE(HAVE_VFS_DIRECT_IO_IOVEC, 1,
-- [aops->direct_IO() uses iovec])
-- zfs_ac_direct_io="yes"
-- ],[
-- AC_MSG_RESULT([no])
-- ])
-+ ],[])
- ])
-
- AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO], [
-- zfs_ac_direct_io="no"
--
-- if test "$zfs_ac_direct_io" = "no"; then
-- ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER
-- fi
--
-- if test "$zfs_ac_direct_io" = "no"; then
-- ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_OFFSET
-- fi
--
-- if test "$zfs_ac_direct_io" = "no"; then
-- ZFS_AC_KERNEL_VFS_DIRECT_IO_ITER_RW_OFFSET
-- fi
--
-- if test "$zfs_ac_direct_io" = "no"; then
-- ZFS_AC_KERNEL_VFS_DIRECT_IO_IOVEC
-- fi
-+ dnl #
-+ dnl # Linux 4.6.x API change
-+ dnl #
-+ AC_MSG_CHECKING([whether aops->direct_IO() uses iov_iter])
-+ ZFS_LINUX_TEST_RESULT([direct_io_iter], [
-+ AC_MSG_RESULT([yes])
-+ AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER, 1,
-+ [aops->direct_IO() uses iov_iter without rw])
-+ ],[
-+ AC_MSG_RESULT([no])
-
-- if test "$zfs_ac_direct_io" = "no"; then
-- AC_MSG_ERROR([no; unknown direct IO interface])
-- fi
-+ dnl #
-+ dnl # Linux 4.1.x API change
-+ dnl #
-+ AC_MSG_CHECKING(
-+ [whether aops->direct_IO() uses offset])
-+ ZFS_LINUX_TEST_RESULT([direct_io_iter_offset], [
-+ AC_MSG_RESULT([yes])
-+ AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_OFFSET, 1,
-+ [aops->direct_IO() uses iov_iter with offset])
-+
-+ ],[
-+ AC_MSG_RESULT([no])
-+
-+ dnl #
-+ dnl # Linux 3.16.x API change
-+ dnl #
-+ AC_MSG_CHECKING(
-+ [whether aops->direct_IO() uses rw and offset])
-+ ZFS_LINUX_TEST_RESULT([direct_io_iter_rw_offset], [
-+ AC_MSG_RESULT([yes])
-+ AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_RW_OFFSET, 1,
-+ [aops->direct_IO() uses iov_iter with ]
-+ [rw and offset])
-+ ],[
-+ AC_MSG_RESULT([no])
-+
-+ dnl #
-+ dnl # Ancient Linux API (predates git)
-+ dnl #
-+ AC_MSG_CHECKING(
-+ [whether aops->direct_IO() uses iovec])
-+ ZFS_LINUX_TEST_RESULT([direct_io_iovec], [
-+ AC_MSG_RESULT([yes])
-+ AC_DEFINE(HAVE_VFS_DIRECT_IO_IOVEC, 1,
-+ [aops->direct_IO() uses iovec])
-+ ],[
-+ ZFS_LINUX_TEST_ERROR([direct IO])
-+ AC_MSG_RESULT([no])
-+ ])
-+ ])
-+ ])
-+ ])
- ])
-diff --git a/config/kernel-vfs-fsync.m4 b/config/kernel-vfs-fsync.m4
-index a474f9f17..18a60d29a 100644
---- a/config/kernel-vfs-fsync.m4
-+++ b/config/kernel-vfs-fsync.m4
-@@ -2,13 +2,17 @@ dnl #
- dnl # 2.6.35 API change,
- dnl # Unused 'struct dentry *' removed from vfs_fsync() prototype.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_2ARGS_VFS_FSYNC], [
-- AC_MSG_CHECKING([whether vfs_fsync() wants 2 args])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS], [
-+ ZFS_LINUX_TEST_SRC([vfs_fsync_2args], [
- #include <linux/fs.h>
- ],[
- vfs_fsync(NULL, 0);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_VFS_FSYNC_2ARGS], [
-+ AC_MSG_CHECKING([whether vfs_fsync() wants 2 args])
-+ ZFS_LINUX_TEST_RESULT([vfs_fsync_2args], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_2ARGS_VFS_FSYNC, 1, [vfs_fsync() wants 2 args])
- ],[
-diff --git a/config/kernel-vfs-getattr.m4 b/config/kernel-vfs-getattr.m4
-index b13723538..eb07853cc 100644
---- a/config/kernel-vfs-getattr.m4
-+++ b/config/kernel-vfs-getattr.m4
-@@ -2,19 +2,23 @@ dnl #
- dnl # 4.11 API, a528d35e@torvalds/linux
- dnl # vfs_getattr(const struct path *p, struct kstat *s, u32 m, unsigned int f)
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_4ARGS_VFS_GETATTR], [
-- AC_MSG_CHECKING([whether vfs_getattr() wants 4 args])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR_4ARGS], [
-+ ZFS_LINUX_TEST_SRC([vfs_getattr_4args], [
- #include <linux/fs.h>
- ],[
- vfs_getattr((const struct path *)NULL,
- (struct kstat *)NULL,
- (u32)0,
- (unsigned int)0);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR_4ARGS], [
-+ AC_MSG_CHECKING([whether vfs_getattr() wants 4 args])
-+ ZFS_LINUX_TEST_RESULT([vfs_getattr_4args], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_4ARGS_VFS_GETATTR, 1,
-- [vfs_getattr wants 4 args])
-+ [vfs_getattr wants 4 args])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -24,17 +28,21 @@ dnl #
- dnl # 3.9 API
- dnl # vfs_getattr(struct path *p, struct kstat *s)
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_2ARGS_VFS_GETATTR], [
-- AC_MSG_CHECKING([whether vfs_getattr() wants 2 args])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR_2ARGS], [
-+ ZFS_LINUX_TEST_SRC([vfs_getattr_2args], [
- #include <linux/fs.h>
- ],[
- vfs_getattr((struct path *) NULL,
- (struct kstat *)NULL);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR_2ARGS], [
-+ AC_MSG_CHECKING([whether vfs_getattr() wants 2 args])
-+ ZFS_LINUX_TEST_RESULT([vfs_getattr_2args], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_2ARGS_VFS_GETATTR, 1,
-- [vfs_getattr wants 2 args])
-+ [vfs_getattr wants 2 args])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -44,19 +52,35 @@ dnl #
- dnl # <3.9 API
- dnl # vfs_getattr(struct vfsmount *v, struct dentry *d, struct kstat *k)
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_3ARGS_VFS_GETATTR], [
-- AC_MSG_CHECKING([whether vfs_getattr() wants 3 args])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR_3ARGS], [
-+ ZFS_LINUX_TEST_SRC([vfs_getattr_3args], [
- #include <linux/fs.h>
- ],[
- vfs_getattr((struct vfsmount *)NULL,
- (struct dentry *)NULL,
- (struct kstat *)NULL);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR_3ARGS], [
-+ AC_MSG_CHECKING([whether vfs_getattr() wants 3 args])
-+ ZFS_LINUX_TEST_RESULT([vfs_getattr_3args], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_3ARGS_VFS_GETATTR, 1,
-- [vfs_getattr wants 3 args])
-+ [vfs_getattr wants 3 args])
- ],[
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR], [
-+ ZFS_AC_KERNEL_SRC_VFS_GETATTR_4ARGS
-+ ZFS_AC_KERNEL_SRC_VFS_GETATTR_2ARGS
-+ ZFS_AC_KERNEL_SRC_VFS_GETATTR_3ARGS
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR], [
-+ ZFS_AC_KERNEL_VFS_GETATTR_4ARGS
-+ ZFS_AC_KERNEL_VFS_GETATTR_2ARGS
-+ ZFS_AC_KERNEL_VFS_GETATTR_3ARGS
-+])
-diff --git a/config/kernel-vfs-iterate.m4 b/config/kernel-vfs-iterate.m4
-index 5de901d44..172118eac 100644
---- a/config/kernel-vfs-iterate.m4
-+++ b/config/kernel-vfs-iterate.m4
-@@ -1,9 +1,5 @@
--AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
-- dnl #
-- dnl # 4.7 API change
-- dnl #
-- AC_MSG_CHECKING([whether fops->iterate_shared() is available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_ITERATE], [
-+ ZFS_LINUX_TEST_SRC([file_operations_iterate_shared], [
- #include <linux/fs.h>
- int iterate(struct file *filp, struct dir_context * context)
- { return 0; }
-@@ -12,11 +8,44 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
- __attribute__ ((unused)) = {
- .iterate_shared = iterate,
- };
-- ],[
-- ],[
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([file_operations_iterate], [
-+ #include <linux/fs.h>
-+ int iterate(struct file *filp,
-+ struct dir_context *context) { return 0; }
-+
-+ static const struct file_operations fops
-+ __attribute__ ((unused)) = {
-+ .iterate = iterate,
-+ };
-+
-+ #if defined(FMODE_KABI_ITERATE)
-+ #error "RHEL 7.5, FMODE_KABI_ITERATE interface"
-+ #endif
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([file_operations_readdir], [
-+ #include <linux/fs.h>
-+ int readdir(struct file *filp, void *entry,
-+ filldir_t func) { return 0; }
-+
-+ static const struct file_operations fops
-+ __attribute__ ((unused)) = {
-+ .readdir = readdir,
-+ };
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
-+ dnl #
-+ dnl # 4.7 API change
-+ dnl #
-+ AC_MSG_CHECKING([whether fops->iterate_shared() is available])
-+ ZFS_LINUX_TEST_RESULT([file_operations_iterate_shared], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_VFS_ITERATE_SHARED, 1,
-- [fops->iterate_shared() is available])
-+ [fops->iterate_shared() is available])
- ],[
- AC_MSG_RESULT(no)
-
-@@ -31,44 +60,23 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
- dnl # to using fops.readdir() to retain KABI compatibility.
- dnl #
- AC_MSG_CHECKING([whether fops->iterate() is available])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- int iterate(struct file *filp,
-- struct dir_context *context) { return 0; }
--
-- static const struct file_operations fops
-- __attribute__ ((unused)) = {
-- .iterate = iterate,
-- };
--
-- #if defined(FMODE_KABI_ITERATE)
-- #error "RHEL 7.5, FMODE_KABI_ITERATE interface"
-- #endif
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT([file_operations_iterate], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_VFS_ITERATE, 1,
-- [fops->iterate() is available])
-+ [fops->iterate() is available])
- ],[
- AC_MSG_RESULT(no)
-
-+ dnl #
-+ dnl # readdir interface introduced
-+ dnl #
- AC_MSG_CHECKING([whether fops->readdir() is available])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- int readdir(struct file *filp, void *entry,
-- filldir_t func) { return 0; }
--
-- static const struct file_operations fops
-- __attribute__ ((unused)) = {
-- .readdir = readdir,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT([file_operations_readdir], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_VFS_READDIR, 1,
-- [fops->readdir() is available])
-+ [fops->readdir() is available])
- ],[
-- AC_MSG_ERROR(no; file a bug report with ZoL)
-+ ZFS_LINUX_TEST_ERROR([vfs_iterate])
- ])
- ])
- ])
-diff --git a/config/kernel-vfs-rw-iterate.m4 b/config/kernel-vfs-rw-iterate.m4
-index ace54f707..000353ec1 100644
---- a/config/kernel-vfs-rw-iterate.m4
-+++ b/config/kernel-vfs-rw-iterate.m4
-@@ -1,9 +1,8 @@
- dnl #
- dnl # Linux 3.16 API
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
-- [AC_MSG_CHECKING([whether fops->read/write_iter() are available])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_RW_ITERATE], [
-+ ZFS_LINUX_TEST_SRC([file_operations_rw], [
- #include <linux/fs.h>
-
- ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to)
-@@ -16,39 +15,41 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
- .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])
-+ ],[])
-
-- ZFS_AC_KERNEL_NEW_SYNC_READ
-+ ZFS_LINUX_TEST_SRC([new_sync_rw], [
-+ #include <linux/fs.h>
- ],[
-- AC_MSG_RESULT(no)
-+ ssize_t ret __attribute__ ((unused));
-+ struct file *filp = NULL;
-+ char __user *rbuf = NULL;
-+ const char __user *wbuf = NULL;
-+ size_t len = 0;
-+ loff_t ppos;
-+
-+ ret = new_sync_read(filp, rbuf, len, &ppos);
-+ ret = new_sync_write(filp, wbuf, len, &ppos);
- ])
- ])
-
--dnl #
--dnl # Linux 4.1 API
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_NEW_SYNC_READ],
-- [AC_MSG_CHECKING([whether new_sync_read/write() are available])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-- ],[
-- ssize_t ret __attribute__ ((unused));
-- struct file *filp = NULL;
-- char __user *rbuf = NULL;
-- const char __user *wbuf = NULL;
-- size_t len = 0;
-- loff_t ppos;
--
-- ret = new_sync_read(filp, rbuf, len, &ppos);
-- ret = new_sync_write(filp, wbuf, len, &ppos);
-- ],[
-+AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE], [
-+ AC_MSG_CHECKING([whether fops->read/write_iter() are available])
-+ ZFS_LINUX_TEST_RESULT([file_operations_rw], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_NEW_SYNC_READ, 1,
-- [new_sync_read()/new_sync_write() are available])
-+ AC_DEFINE(HAVE_VFS_RW_ITERATE, 1,
-+ [fops->read/write_iter() are available])
-+
-+ dnl #
-+ dnl # Linux 4.1 API
-+ dnl #
-+ AC_MSG_CHECKING([whether new_sync_read/write() are available])
-+ ZFS_LINUX_TEST_RESULT([new_sync_rw], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_NEW_SYNC_READ, 1,
-+ [new_sync_read()/new_sync_write() are available])
-+ ],[
-+ AC_MSG_RESULT(no)
-+ ])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -57,19 +58,22 @@ AC_DEFUN([ZFS_AC_KERNEL_NEW_SYNC_READ],
- dnl #
- dnl # Linux 4.1.x API
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_GENERIC_WRITE_CHECKS],
-- [AC_MSG_CHECKING([whether generic_write_checks() takes kiocb])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GENERIC_WRITE_CHECKS], [
-+ ZFS_LINUX_TEST_SRC([generic_write_checks], [
- #include <linux/fs.h>
--
- ],[
- struct kiocb *iocb = NULL;
- struct iov_iter *iov = NULL;
- generic_write_checks(iocb, iov);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_VFS_GENERIC_WRITE_CHECKS], [
-+ AC_MSG_CHECKING([whether generic_write_checks() takes kiocb])
-+ ZFS_LINUX_TEST_RESULT([generic_write_checks], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_GENERIC_WRITE_CHECKS_KIOCB, 1,
-- [generic_write_checks() takes kiocb])
-+ [generic_write_checks() takes kiocb])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel-wait.m4 b/config/kernel-wait.m4
-index d6442c1df..0414242bf 100644
---- a/config/kernel-wait.m4
-+++ b/config/kernel-wait.m4
-@@ -1,3 +1,26 @@
-+dnl #
-+dnl # 4.13 API change
-+dnl # Renamed struct wait_queue -> struct wait_queue_entry.
-+dnl #
-+dnl # N.B. The type check is performed before all other checks
-+dnl # since ZFS_AC_KERNEL_SRC_WAIT_QUEUE_HEAD_ENTRY depends on
-+dnl # HAVE_WAIT_QUEUE_ENTRY_T being set in confdefs.h.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T], [
-+ AC_MSG_CHECKING([whether wait_queue_entry_t exists])
-+ ZFS_LINUX_TRY_COMPILE([
-+ #include <linux/wait.h>
-+ ],[
-+ wait_queue_entry_t *entry __attribute__ ((unused));
-+ ],[
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_WAIT_QUEUE_ENTRY_T, 1,
-+ [wait_queue_entry_t exists])
-+ ],[
-+ AC_MSG_RESULT(no)
-+ ])
-+])
-+
- dnl #
- dnl # 3.17 API change,
- dnl # wait_on_bit() no longer requires an action argument. The former
-@@ -8,34 +31,20 @@ dnl # of just two functions: one which uses io_schedule() and one which just
- dnl # uses schedule(). This API change was made to consolidate all of those
- dnl # redundant wait functions.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_WAIT_ON_BIT], [
-- AC_MSG_CHECKING([whether wait_on_bit() takes an action])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_WAIT_ON_BIT], [
-+ ZFS_LINUX_TEST_SRC([wait_on_bit], [
- #include <linux/wait.h>
- ],[
- int (*action)(void *) = NULL;
- wait_on_bit(NULL, 0, action, 0);
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_WAIT_ON_BIT_ACTION, 1, [yes])
-- ],[
-- AC_MSG_RESULT(no)
- ])
- ])
--dnl #
--dnl # 4.13 API change
--dnl # Renamed struct wait_queue -> struct wait_queue_entry.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T], [
-- AC_MSG_CHECKING([whether wait_queue_entry_t exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/wait.h>
-- ],[
-- wait_queue_entry_t *entry __attribute__ ((unused));
-- ],[
-+
-+AC_DEFUN([ZFS_AC_KERNEL_WAIT_ON_BIT], [
-+ AC_MSG_CHECKING([whether wait_on_bit() takes an action])
-+ ZFS_LINUX_TEST_RESULT([wait_on_bit], [
- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_WAIT_QUEUE_ENTRY_T, 1,
-- [wait_queue_entry_t exists])
-+ AC_DEFINE(HAVE_WAIT_ON_BIT_ACTION, 1, [yes])
- ],[
- AC_MSG_RESULT(no)
- ])
-@@ -46,9 +55,8 @@ dnl # 4.13 API change
- dnl # Renamed wait_queue_head::task_list -> wait_queue_head::head
- dnl # Renamed wait_queue_entry::task_list -> wait_queue_entry::entry
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY], [
-- AC_MSG_CHECKING([whether wq_head->head and wq_entry->entry exist])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_WAIT_QUEUE_HEAD_ENTRY], [
-+ ZFS_LINUX_TEST_SRC([wait_queue_head_entry], [
- #include <linux/wait.h>
-
- #ifdef HAVE_WAIT_QUEUE_ENTRY_T
-@@ -66,7 +74,12 @@ AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY], [
-
- head = &wq_head.head;
- entry = &wq_entry.entry;
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY], [
-+ AC_MSG_CHECKING([whether wq_head->head and wq_entry->entry exist])
-+ ZFS_LINUX_TEST_RESULT([wait_queue_head_entry], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_WAIT_QUEUE_HEAD_ENTRY, 1,
- [wq_head->head and wq_entry->entry exist])
-@@ -74,3 +87,13 @@ AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY], [
- AC_MSG_RESULT(no)
- ])
- ])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_WAIT], [
-+ ZFS_AC_KERNEL_SRC_WAIT_ON_BIT
-+ ZFS_AC_KERNEL_SRC_WAIT_QUEUE_HEAD_ENTRY
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_WAIT], [
-+ ZFS_AC_KERNEL_WAIT_ON_BIT
-+ ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY
-+])
-diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
-index 0b61b85b1..ed84c6390 100644
---- a/config/kernel-xattr-handler.m4
-+++ b/config/kernel-xattr-handler.m4
-@@ -3,9 +3,8 @@ dnl # 2.6.35 API change,
- dnl # The 'struct xattr_handler' was constified in the generic
- dnl # super_block structure.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [
-- AC_MSG_CHECKING([whether super_block uses const struct xattr_handler])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_CONST_XATTR_HANDLER], [
-+ ZFS_LINUX_TEST_SRC([const_xattr_handler], [
- #include <linux/fs.h>
- #include <linux/xattr.h>
-
-@@ -22,11 +21,15 @@ AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [
- const struct super_block sb __attribute__ ((unused)) = {
- .s_xattr = xattr_handlers,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [
-+ AC_MSG_CHECKING([whether super_block uses const struct xattr_handler])
-+ ZFS_LINUX_TEST_RESULT([const_xattr_handler], [
- AC_MSG_RESULT([yes])
- AC_DEFINE(HAVE_CONST_XATTR_HANDLER, 1,
-- [super_block uses const struct xattr_handler])
-+ [super_block uses const struct xattr_handler])
- ],[
- AC_MSG_RESULT([no])
- ])
-@@ -38,17 +41,20 @@ dnl # struct xattr_handler added new member "name".
- dnl # xattr_handler which matches to whole name rather than prefix should use
- dnl # "name" instead of "prefix", e.g. "system.posix_acl_access"
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [
-- AC_MSG_CHECKING([whether xattr_handler has name])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_NAME], [
-+ ZFS_LINUX_TEST_SRC([xattr_handler_name], [
- #include <linux/xattr.h>
-
- static const struct xattr_handler
- xops __attribute__ ((unused)) = {
- .name = XATTR_NAME_POSIX_ACL_ACCESS,
- };
-- ],[
-- ],[
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [
-+ AC_MSG_CHECKING([whether xattr_handler has name])
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_name], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_HANDLER_NAME, 1,
- [xattr_handler has name])
-@@ -58,52 +64,65 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [
- ])
-
- dnl #
--dnl # 4.9 API change,
--dnl # iops->{set,get,remove}xattr and generic_{set,get,remove}xattr are
--dnl # removed. xattr operations will directly go through sb->s_xattr.
-+dnl # Supported xattr handler get() interfaces checked newest to oldest.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR], [
-- AC_MSG_CHECKING([whether generic_setxattr() exists])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/fs.h>
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_GET], [
-+ ZFS_LINUX_TEST_SRC([xattr_handler_get_dentry_inode], [
- #include <linux/xattr.h>
-
-- static const struct inode_operations
-- iops __attribute__ ((unused)) = {
-- .setxattr = generic_setxattr
-+ int get(const struct xattr_handler *handler,
-+ struct dentry *dentry, struct inode *inode,
-+ const char *name, void *buffer, size_t size) { return 0; }
-+ static const struct xattr_handler
-+ xops __attribute__ ((unused)) = {
-+ .get = get,
- };
-- ],[
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(HAVE_GENERIC_SETXATTR, 1,
-- [generic_setxattr() exists])
-- ],[
-- AC_MSG_RESULT(no)
-- ])
--])
-+ ],[])
-
--dnl #
--dnl # Supported xattr handler get() interfaces checked newest to oldest.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
-- dnl #
-- dnl # 4.7 API change,
-- dnl # The xattr_handler->get() callback was changed to take both
-- dnl # dentry and inode.
-- dnl #
-- AC_MSG_CHECKING([whether xattr_handler->get() wants both dentry and inode])
-- ZFS_LINUX_TRY_COMPILE([
-+ ZFS_LINUX_TEST_SRC([xattr_handler_get_xattr_handler], [
- #include <linux/xattr.h>
-
- int get(const struct xattr_handler *handler,
-- struct dentry *dentry, struct inode *inode,
-- const char *name, void *buffer, size_t size) { return 0; }
-+ struct dentry *dentry, const char *name,
-+ void *buffer, size_t size) { return 0; }
- static const struct xattr_handler
- xops __attribute__ ((unused)) = {
- .get = get,
- };
-- ],[
-- ],[
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([xattr_handler_get_dentry], [
-+ #include <linux/xattr.h>
-+
-+ int get(struct dentry *dentry, const char *name,
-+ void *buffer, size_t size, int handler_flags)
-+ { return 0; }
-+ static const struct xattr_handler
-+ xops __attribute__ ((unused)) = {
-+ .get = get,
-+ };
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([xattr_handler_get_inode], [
-+ #include <linux/xattr.h>
-+
-+ int get(struct inode *ip, const char *name,
-+ void *buffer, size_t size) { return 0; }
-+ static const struct xattr_handler
-+ xops __attribute__ ((unused)) = {
-+ .get = get,
-+ };
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
-+ dnl #
-+ dnl # 4.7 API change,
-+ dnl # The xattr_handler->get() callback was changed to take both
-+ dnl # dentry and inode.
-+ dnl #
-+ AC_MSG_CHECKING([whether xattr_handler->get() wants dentry and inode])
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_get_dentry_inode], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1,
- [xattr_handler->get() wants both dentry and inode])
-@@ -115,69 +134,40 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
- dnl # should be accessed by handler->flags.
- dnl #
- AC_MSG_RESULT(no)
-- AC_MSG_CHECKING([whether xattr_handler->get() wants xattr_handler])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/xattr.h>
--
-- int get(const struct xattr_handler *handler,
-- struct dentry *dentry, const char *name,
-- void *buffer, size_t size) { return 0; }
-- static const struct xattr_handler
-- xops __attribute__ ((unused)) = {
-- .get = get,
-- };
-- ],[
-- ],[
-+ AC_MSG_CHECKING(
-+ [whether xattr_handler->get() wants xattr_handler])
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_get_xattr_handler], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1,
- [xattr_handler->get() wants xattr_handler])
- ],[
- dnl #
- dnl # 2.6.33 API change,
-- dnl # The xattr_handler->get() callback was changed to take
-- dnl # a dentry instead of an inode, and a handler_flags
-- dnl # argument was added.
-+ dnl # The xattr_handler->get() callback was changed
-+ dnl # to take a dentry instead of an inode, and a
-+ dnl # handler_flags argument was added.
- dnl #
- AC_MSG_RESULT(no)
-- AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/xattr.h>
--
-- int get(struct dentry *dentry, const char *name,
-- void *buffer, size_t size, int handler_flags)
-- { return 0; }
-- static const struct xattr_handler
-- xops __attribute__ ((unused)) = {
-- .get = get,
-- };
-- ],[
-- ],[
-+ AC_MSG_CHECKING(
-+ [whether xattr_handler->get() wants dentry])
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_get_dentry], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1,
- [xattr_handler->get() wants dentry])
- ],[
- dnl #
-- dnl # 2.6.32 API
-+ dnl # Legacy 2.6.32 API
- dnl #
- AC_MSG_RESULT(no)
- AC_MSG_CHECKING(
- [whether xattr_handler->get() wants inode])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/xattr.h>
--
-- int get(struct inode *ip, const char *name,
-- void *buffer, size_t size) { return 0; }
-- static const struct xattr_handler
-- xops __attribute__ ((unused)) = {
-- .get = get,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT(
-+ [xattr_handler_get_inode], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_GET_INODE, 1,
- [xattr_handler->get() wants inode])
- ],[
-- AC_MSG_ERROR([no; please file a bug report])
-+ ZFS_LINUX_TEST_ERROR([xattr get()])
- ])
- ])
- ])
-@@ -187,14 +177,8 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
- dnl #
- dnl # Supported xattr handler set() interfaces checked newest to oldest.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
-- dnl #
-- dnl # 4.7 API change,
-- dnl # The xattr_handler->set() callback was changed to take both
-- dnl # dentry and inode.
-- dnl #
-- AC_MSG_CHECKING([whether xattr_handler->set() wants both dentry and inode])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
-+ ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [
- #include <linux/xattr.h>
-
- int set(const struct xattr_handler *handler,
-@@ -206,8 +190,54 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
- xops __attribute__ ((unused)) = {
- .set = set,
- };
-- ],[
-- ],[
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([xattr_handler_set_xattr_handler], [
-+ #include <linux/xattr.h>
-+
-+ int set(const struct xattr_handler *handler,
-+ struct dentry *dentry, const char *name,
-+ const void *buffer, size_t size, int flags)
-+ { return 0; }
-+ static const struct xattr_handler
-+ xops __attribute__ ((unused)) = {
-+ .set = set,
-+ };
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry], [
-+ #include <linux/xattr.h>
-+
-+ int set(struct dentry *dentry, const char *name,
-+ const void *buffer, size_t size, int flags,
-+ int handler_flags) { return 0; }
-+ static const struct xattr_handler
-+ xops __attribute__ ((unused)) = {
-+ .set = set,
-+ };
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([xattr_handler_set_inode], [
-+ #include <linux/xattr.h>
-+
-+ int set(struct inode *ip, const char *name,
-+ const void *buffer, size_t size, int flags)
-+ { return 0; }
-+ static const struct xattr_handler
-+ xops __attribute__ ((unused)) = {
-+ .set = set,
-+ };
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
-+ dnl #
-+ dnl # 4.7 API change,
-+ dnl # The xattr_handler->set() callback was changed to take both
-+ dnl # dentry and inode.
-+ dnl #
-+ AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
- [xattr_handler->set() wants both dentry and inode])
-@@ -219,71 +249,40 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
- dnl # should be accessed by handler->flags.
- dnl #
- AC_MSG_RESULT(no)
-- AC_MSG_CHECKING([whether xattr_handler->set() wants xattr_handler])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/xattr.h>
--
-- int set(const struct xattr_handler *handler,
-- struct dentry *dentry, const char *name,
-- const void *buffer, size_t size, int flags)
-- { return 0; }
-- static const struct xattr_handler
-- xops __attribute__ ((unused)) = {
-- .set = set,
-- };
-- ],[
-- ],[
-+ AC_MSG_CHECKING(
-+ [whether xattr_handler->set() wants xattr_handler])
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_set_xattr_handler], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
- [xattr_handler->set() wants xattr_handler])
- ],[
- dnl #
- dnl # 2.6.33 API change,
-- dnl # The xattr_handler->set() callback was changed to take a
-- dnl # dentry instead of an inode, and a handler_flags
-- dnl # argument was added.
-+ dnl # The xattr_handler->set() callback was changed
-+ dnl # to take a dentry instead of an inode, and a
-+ dnl # handler_flags argument was added.
- dnl #
- AC_MSG_RESULT(no)
-- AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/xattr.h>
--
-- int set(struct dentry *dentry, const char *name,
-- const void *buffer, size_t size, int flags,
-- int handler_flags) { return 0; }
-- static const struct xattr_handler
-- xops __attribute__ ((unused)) = {
-- .set = set,
-- };
-- ],[
-- ],[
-+ AC_MSG_CHECKING(
-+ [whether xattr_handler->set() wants dentry])
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
- [xattr_handler->set() wants dentry])
- ],[
- dnl #
-- dnl # 2.6.32 API
-+ dnl # Legacy 2.6.32 API
- dnl #
- AC_MSG_RESULT(no)
- AC_MSG_CHECKING(
- [whether xattr_handler->set() wants inode])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/xattr.h>
--
-- int set(struct inode *ip, const char *name,
-- const void *buffer, size_t size, int flags)
-- { return 0; }
-- static const struct xattr_handler
-- xops __attribute__ ((unused)) = {
-- .set = set,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT(
-+ [xattr_handler_set_inode], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_SET_INODE, 1,
- [xattr_handler->set() wants inode])
- ],[
-- AC_MSG_ERROR([no; please file a bug report])
-+ ZFS_LINUX_TEST_ERROR([xattr set()])
- ])
- ])
- ])
-@@ -293,12 +292,8 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
- dnl #
- dnl # Supported xattr handler list() interfaces checked newest to oldest.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
-- dnl # 4.5 API change,
-- dnl # The xattr_handler->list() callback was changed to take only a
-- dnl # dentry and it only needs to return if it's accessible.
-- AC_MSG_CHECKING([whether xattr_handler->list() wants simple])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_LIST], [
-+ ZFS_LINUX_TEST_SRC([xattr_handler_list_simple], [
- #include <linux/xattr.h>
-
- bool list(struct dentry *dentry) { return 0; }
-@@ -306,8 +301,52 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
- xops __attribute__ ((unused)) = {
- .list = list,
- };
-- ],[
-- ],[
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([xattr_handler_list_xattr_handler], [
-+ #include <linux/xattr.h>
-+
-+ size_t list(const struct xattr_handler *handler,
-+ struct dentry *dentry, char *list, size_t list_size,
-+ const char *name, size_t name_len) { return 0; }
-+ static const struct xattr_handler
-+ xops __attribute__ ((unused)) = {
-+ .list = list,
-+ };
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([xattr_handler_list_dentry], [
-+ #include <linux/xattr.h>
-+
-+ size_t list(struct dentry *dentry,
-+ char *list, size_t list_size,
-+ const char *name, size_t name_len,
-+ int handler_flags) { return 0; }
-+ static const struct xattr_handler
-+ xops __attribute__ ((unused)) = {
-+ .list = list,
-+ };
-+ ],[])
-+
-+ ZFS_LINUX_TEST_SRC([xattr_handler_list_inode], [
-+ #include <linux/xattr.h>
-+
-+ size_t list(struct inode *ip, char *lst,
-+ size_t list_size, const char *name,
-+ size_t name_len) { return 0; }
-+ static const struct xattr_handler
-+ xops __attribute__ ((unused)) = {
-+ .list = list,
-+ };
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
-+ dnl # 4.5 API change,
-+ dnl # The xattr_handler->list() callback was changed to take only a
-+ dnl # dentry and it only needs to return if it's accessible.
-+ AC_MSG_CHECKING([whether xattr_handler->list() wants simple])
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_list_simple], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_LIST_SIMPLE, 1,
- [xattr_handler->list() wants simple])
-@@ -321,18 +360,7 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
- AC_MSG_RESULT(no)
- AC_MSG_CHECKING(
- [whether xattr_handler->list() wants xattr_handler])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/xattr.h>
--
-- size_t list(const struct xattr_handler *handler,
-- struct dentry *dentry, char *list, size_t list_size,
-- const char *name, size_t name_len) { return 0; }
-- static const struct xattr_handler
-- xops __attribute__ ((unused)) = {
-- .list = list,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_list_xattr_handler], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_LIST_HANDLER, 1,
- [xattr_handler->list() wants xattr_handler])
-@@ -346,47 +374,24 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
- AC_MSG_RESULT(no)
- AC_MSG_CHECKING(
- [whether xattr_handler->list() wants dentry])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/xattr.h>
--
-- size_t list(struct dentry *dentry,
-- char *list, size_t list_size,
-- const char *name, size_t name_len,
-- int handler_flags) { return 0; }
-- static const struct xattr_handler
-- xops __attribute__ ((unused)) = {
-- .list = list,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT([xattr_handler_list_dentry], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_LIST_DENTRY, 1,
- [xattr_handler->list() wants dentry])
- ],[
- dnl #
-- dnl # 2.6.32 API
-+ dnl # Legacy 2.6.32 API
- dnl #
- AC_MSG_RESULT(no)
- AC_MSG_CHECKING(
- [whether xattr_handler->list() wants inode])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/xattr.h>
--
-- size_t list(struct inode *ip, char *lst,
-- size_t list_size, const char *name,
-- size_t name_len) { return 0; }
-- static const struct xattr_handler
-- xops __attribute__ ((unused)) = {
-- .list = list,
-- };
-- ],[
-- ],[
-+ ZFS_LINUX_TEST_RESULT(
-+ [xattr_handler_list_inode], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_XATTR_LIST_INODE, 1,
- [xattr_handler->list() wants inode])
- ],[
-- AC_MSG_ERROR(
-- [no; please file a bug report])
-+ ZFS_LINUX_TEST_ERROR([xattr list()])
- ])
- ])
- ])
-@@ -398,15 +403,19 @@ dnl # 3.7 API change,
- dnl # The posix_acl_{from,to}_xattr functions gained a new
- dnl # parameter: user_ns
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS], [
-- AC_MSG_CHECKING([whether posix_acl_from_xattr() needs user_ns])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_FROM_XATTR_USERNS], [
-+ ZFS_LINUX_TEST_SRC([posix_acl_from_xattr_userns], [
- #include <linux/cred.h>
- #include <linux/fs.h>
- #include <linux/posix_acl_xattr.h>
- ],[
- posix_acl_from_xattr(&init_user_ns, NULL, 0);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS], [
-+ AC_MSG_CHECKING([whether posix_acl_from_xattr() needs user_ns])
-+ ZFS_LINUX_TEST_RESULT([posix_acl_from_xattr_userns], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_POSIX_ACL_FROM_XATTR_USERNS, 1,
- [posix_acl_from_xattr() needs user_ns])
-@@ -415,3 +424,50 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS], [
- ])
- ])
-
-+dnl #
-+dnl # 4.9 API change,
-+dnl # iops->{set,get,remove}xattr and generic_{set,get,remove}xattr are
-+dnl # removed. xattr operations will directly go through sb->s_xattr.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_SETXATTR], [
-+ ZFS_LINUX_TEST_SRC([have_generic_setxattr], [
-+ #include <linux/fs.h>
-+ #include <linux/xattr.h>
-+
-+ static const struct inode_operations
-+ iops __attribute__ ((unused)) = {
-+ .setxattr = generic_setxattr
-+ };
-+ ],[])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_GENERIC_SETXATTR], [
-+ AC_MSG_CHECKING([whether generic_setxattr() exists])
-+ ZFS_LINUX_TEST_RESULT([have_generic_setxattr], [
-+ AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_GENERIC_SETXATTR, 1,
-+ [generic_setxattr() exists])
-+ ],[
-+ AC_MSG_RESULT(no)
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR], [
-+ ZFS_AC_KERNEL_SRC_CONST_XATTR_HANDLER
-+ ZFS_AC_KERNEL_SRC_XATTR_HANDLER_NAME
-+ ZFS_AC_KERNEL_SRC_XATTR_HANDLER_GET
-+ ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET
-+ ZFS_AC_KERNEL_SRC_XATTR_HANDLER_LIST
-+ ZFS_AC_KERNEL_SRC_POSIX_ACL_FROM_XATTR_USERNS
-+ ZFS_AC_KERNEL_SRC_GENERIC_SETXATTR
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_XATTR], [
-+ ZFS_AC_KERNEL_CONST_XATTR_HANDLER
-+ ZFS_AC_KERNEL_XATTR_HANDLER_NAME
-+ ZFS_AC_KERNEL_XATTR_HANDLER_GET
-+ ZFS_AC_KERNEL_XATTR_HANDLER_SET
-+ ZFS_AC_KERNEL_XATTR_HANDLER_LIST
-+ ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS
-+ ZFS_AC_KERNEL_GENERIC_SETXATTR
-+])
-diff --git a/config/kernel-zlib.m4 b/config/kernel-zlib.m4
-index 3ca7cf682..d554d1168 100644
---- a/config/kernel-zlib.m4
-+++ b/config/kernel-zlib.m4
-@@ -1,62 +1,25 @@
--dnl #
--dnl # zlib inflate compat,
--dnl # Verify the kernel has CONFIG_ZLIB_INFLATE support enabled.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE], [
-- AC_MSG_CHECKING([whether CONFIG_ZLIB_INFLATE is defined])
-- ZFS_LINUX_TRY_COMPILE([
-- #if !defined(CONFIG_ZLIB_INFLATE) && \
-- !defined(CONFIG_ZLIB_INFLATE_MODULE)
-- #error CONFIG_ZLIB_INFLATE not defined
-- #endif
-- ],[ ],[
-- AC_MSG_RESULT([yes])
-- ],[
-- AC_MSG_RESULT([no])
-- AC_MSG_ERROR([
-- *** This kernel does not include the required zlib inflate support.
-- *** Rebuild the kernel with CONFIG_ZLIB_INFLATE=y|m set.])
-- ])
--])
--
--dnl #
--dnl # zlib deflate compat,
--dnl # Verify the kernel has CONFIG_ZLIB_DEFLATE support enabled.
--dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE], [
-- AC_MSG_CHECKING([whether CONFIG_ZLIB_DEFLATE is defined])
-- ZFS_LINUX_TRY_COMPILE([
-- #if !defined(CONFIG_ZLIB_DEFLATE) && \
-- !defined(CONFIG_ZLIB_DEFLATE_MODULE)
-- #error CONFIG_ZLIB_DEFLATE not defined
-- #endif
-- ],[ ],[
-- AC_MSG_RESULT([yes])
-- ],[
-- AC_MSG_RESULT([no])
-- AC_MSG_ERROR([
-- *** This kernel does not include the required zlib deflate support.
-- *** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set.])
-- ])
--])
--
- dnl #
- dnl # 2.6.39 API compat,
-+dnl
- dnl # The function zlib_deflate_workspacesize() now take 2 arguments.
- dnl # This was done to avoid always having to allocate the maximum size
- dnl # workspace (268K). The caller can now specific the windowBits and
- dnl # memLevel compression parameters to get a smaller workspace.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE],
-- [AC_MSG_CHECKING([whether zlib_deflate_workspacesize() wants 2 args])
-- ZFS_LINUX_TRY_COMPILE([
-+AC_DEFUN([ZFS_AC_KERNEL_SRC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE], [
-+ ZFS_LINUX_TEST_SRC([2args_zlib_deflate_workspacesize], [
- #include <linux/zlib.h>
- ],[
- return zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL);
-- ],[
-+ ])
-+])
-+
-+AC_DEFUN([ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE], [
-+ AC_MSG_CHECKING([whether zlib_deflate_workspacesize() wants 2 args])
-+ ZFS_LINUX_TEST_RESULT([2args_zlib_deflate_workspacesize], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE, 1,
-- [zlib_deflate_workspacesize() wants 2 args])
-+ [zlib_deflate_workspacesize() wants 2 args])
- ],[
- AC_MSG_RESULT(no)
- ])
-diff --git a/config/kernel.m4 b/config/kernel.m4
-index 8e89c8014..b22a00cdd 100644
---- a/config/kernel.m4
-+++ b/config/kernel.m4
-@@ -2,111 +2,217 @@ dnl #
- dnl # Default ZFS kernel configuration
- dnl #
- AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
-+ dnl # Setup the kernel build environment.
- ZFS_AC_KERNEL
- ZFS_AC_QAT
-- ZFS_AC_KERNEL_ACCESS_OK_TYPE
-- ZFS_AC_TEST_MODULE
-+
-+ dnl # Sanity checks for module building and CONFIG_* defines
-+ ZFS_AC_KERNEL_TEST_MODULE
-+ ZFS_AC_KERNEL_CONFIG_DEFINED
-+
-+ dnl # Sequential ZFS_LINUX_TRY_COMPILE tests
-+ ZFS_AC_KERNEL_FPU_HEADER
-+ ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T
- ZFS_AC_KERNEL_MISC_MINOR
-+ ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
-+
-+ dnl # Parallel ZFS_LINUX_TEST_SRC / ZFS_LINUX_TEST_RESULT tests
-+ ZFS_AC_KERNEL_TEST_SRC
-+ ZFS_AC_KERNEL_TEST_RESULT
-+
-+ AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
-+ KERNEL_MAKE="$KERNEL_MAKE O=$LINUX_OBJ"
-+ ])
-+
-+ AC_SUBST(KERNEL_MAKE)
-+])
-+
-+dnl #
-+dnl # Generate and compile all of the kernel API test cases to determine
-+dnl # which interfaces are available. By invoking the kernel build system
-+dnl # only once the compilation can be done in parallel significantly
-+dnl # speeding up the process.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
-+ ZFS_AC_KERNEL_SRC_OBJTOOL
-+ ZFS_AC_KERNEL_SRC_GLOBAL_PAGE_STATE
-+ ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE
-+ ZFS_AC_KERNEL_SRC_CTL_NAME
-+ ZFS_AC_KERNEL_SRC_PDE_DATA
-+ ZFS_AC_KERNEL_SRC_FALLOCATE
-+ ZFS_AC_KERNEL_SRC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
-+ ZFS_AC_KERNEL_SRC_RWSEM
-+ ZFS_AC_KERNEL_SRC_SCHED
-+ ZFS_AC_KERNEL_SRC_USLEEP_RANGE
-+ ZFS_AC_KERNEL_SRC_KMEM_CACHE
-+ ZFS_AC_KERNEL_SRC_WAIT
-+ ZFS_AC_KERNEL_SRC_INODE_TIMES
-+ ZFS_AC_KERNEL_SRC_INODE_LOCK
-+ ZFS_AC_KERNEL_SRC_GROUP_INFO_GID
-+ ZFS_AC_KERNEL_SRC_RW
-+ ZFS_AC_KERNEL_SRC_TIMER_SETUP
-+ ZFS_AC_KERNEL_SRC_CURRENT_BIO_TAIL
-+ ZFS_AC_KERNEL_SRC_SUPER_USER_NS
-+ ZFS_AC_KERNEL_SRC_SUBMIT_BIO
-+ ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS
-+ ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
-+ ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART
-+ ZFS_AC_KERNEL_SRC_INVALIDATE_BDEV
-+ ZFS_AC_KERNEL_SRC_LOOKUP_BDEV
-+ ZFS_AC_KERNEL_SRC_BDEV_OPEN_EXCLUSIVE
-+ ZFS_AC_KERNEL_SRC_BDEV_LOGICAL_BLOCK_SIZE
-+ ZFS_AC_KERNEL_SRC_BDEV_PHYSICAL_BLOCK_SIZE
-+ ZFS_AC_KERNEL_SRC_BIO_BVEC_ITER
-+ ZFS_AC_KERNEL_SRC_BIO_FAILFAST
-+ ZFS_AC_KERNEL_SRC_BIO_SET_DEV
-+ ZFS_AC_KERNEL_SRC_BIO_OPS
-+ ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS
-+ ZFS_AC_KERNEL_SRC_BIO_BI_STATUS
-+ ZFS_AC_KERNEL_SRC_BIO_RW_BARRIER
-+ ZFS_AC_KERNEL_SRC_BIO_RW_DISCARD
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAGS
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLUSH
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_HW_SECTORS
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_SEGMENTS
-+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG
-+ ZFS_AC_KERNEL_SRC_GET_DISK_AND_MODULE
-+ ZFS_AC_KERNEL_SRC_GET_DISK_RO
-+ ZFS_AC_KERNEL_SRC_GENERIC_READLINK_GLOBAL
-+ ZFS_AC_KERNEL_SRC_DISCARD_GRANULARITY
-+ ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE
-+ ZFS_AC_KERNEL_SRC_XATTR
-+ ZFS_AC_KERNEL_SRC_ACL
-+ ZFS_AC_KERNEL_SRC_INODE_GETATTR
-+ ZFS_AC_KERNEL_SRC_INODE_SET_FLAGS
-+ ZFS_AC_KERNEL_SRC_INODE_SET_IVERSION
-+ ZFS_AC_KERNEL_SRC_SHOW_OPTIONS
-+ ZFS_AC_KERNEL_SRC_FILE_INODE
-+ ZFS_AC_KERNEL_SRC_FILE_DENTRY
-+ ZFS_AC_KERNEL_SRC_FSYNC
-+ ZFS_AC_KERNEL_SRC_AIO_FSYNC
-+ ZFS_AC_KERNEL_SRC_EVICT_INODE
-+ ZFS_AC_KERNEL_SRC_DIRTY_INODE
-+ ZFS_AC_KERNEL_SRC_SHRINKER
-+ ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T
-+ ZFS_AC_KERNEL_SRC_LOOKUP_NAMEIDATA
-+ ZFS_AC_KERNEL_SRC_CREATE_NAMEIDATA
-+ ZFS_AC_KERNEL_SRC_GET_LINK
-+ ZFS_AC_KERNEL_SRC_PUT_LINK
-+ ZFS_AC_KERNEL_SRC_TMPFILE
-+ ZFS_AC_KERNEL_SRC_TRUNCATE_RANGE
-+ ZFS_AC_KERNEL_SRC_AUTOMOUNT
-+ ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE
-+ ZFS_AC_KERNEL_SRC_COMMIT_METADATA
-+ ZFS_AC_KERNEL_SRC_CLEAR_INODE
-+ ZFS_AC_KERNEL_SRC_SETATTR_PREPARE
-+ ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED
-+ ZFS_AC_KERNEL_SRC_DENTRY
-+ ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE
-+ ZFS_AC_KERNEL_SRC_SECURITY_INODE
-+ ZFS_AC_KERNEL_SRC_FST_MOUNT
-+ ZFS_AC_KERNEL_SRC_BDI
-+ ZFS_AC_KERNEL_SRC_SET_NLINK
-+ ZFS_AC_KERNEL_SRC_ELEVATOR_CHANGE
-+ ZFS_AC_KERNEL_SRC_SGET
-+ ZFS_AC_KERNEL_SRC_LSEEK_EXECUTE
-+ ZFS_AC_KERNEL_SRC_VFS_GETATTR
-+ ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS
-+ ZFS_AC_KERNEL_SRC_VFS_ITERATE
-+ ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO
-+ ZFS_AC_KERNEL_SRC_VFS_RW_ITERATE
-+ ZFS_AC_KERNEL_SRC_VFS_GENERIC_WRITE_CHECKS
-+ ZFS_AC_KERNEL_SRC_KMAP_ATOMIC_ARGS
-+ ZFS_AC_KERNEL_SRC_FOLLOW_DOWN_ONE
-+ ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN
-+ ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT
-+ ZFS_AC_KERNEL_SRC_FPU
-+ ZFS_AC_KERNEL_SRC_FMODE_T
-+ ZFS_AC_KERNEL_SRC_KUIDGID_T
-+ ZFS_AC_KERNEL_SRC_KUID_HELPERS
-+ ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST
-+ ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS
-+ ZFS_AC_KERNEL_SRC_CURRENT_TIME
-+ ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
-+ ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL
-+ ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64
-+ ZFS_AC_KERNEL_SRC_TOTALRAM_PAGES_FUNC
-+ ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES
-+ ZFS_AC_KERNEL_SRC_KSTRTOUL
-+
-+ AC_MSG_CHECKING([for available kernel interfaces])
-+ ZFS_LINUX_TEST_COMPILE_ALL([kabi])
-+ AC_MSG_RESULT([done])
-+])
-+
-+dnl #
-+dnl # Check results of kernel interface tests.
-+dnl #
-+AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
-+ ZFS_AC_KERNEL_ACCESS_OK_TYPE
-+ ZFS_AC_KERNEL_GLOBAL_PAGE_STATE
- ZFS_AC_KERNEL_OBJTOOL
-- ZFS_AC_KERNEL_CONFIG
- ZFS_AC_KERNEL_CTL_NAME
- ZFS_AC_KERNEL_PDE_DATA
-- ZFS_AC_KERNEL_2ARGS_VFS_FSYNC
-- ZFS_AC_KERNEL_KUIDGID_T
- ZFS_AC_KERNEL_FALLOCATE
- ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
-- ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW
-- ZFS_AC_KERNEL_RWSEM_ACTIVITY
-- ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT
-- ZFS_AC_KERNEL_SCHED_RT_HEADER
-- ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER
-- ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT
-- ZFS_AC_KERNEL_4ARGS_VFS_GETATTR
-- ZFS_AC_KERNEL_3ARGS_VFS_GETATTR
-- ZFS_AC_KERNEL_2ARGS_VFS_GETATTR
-+ ZFS_AC_KERNEL_RWSEM
-+ ZFS_AC_KERNEL_SCHED
- ZFS_AC_KERNEL_USLEEP_RANGE
-- ZFS_AC_KERNEL_KMEM_CACHE_ALLOCFLAGS
-- ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY
-- ZFS_AC_KERNEL_WAIT_ON_BIT
-- ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T
-- ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY
-+ ZFS_AC_KERNEL_KMEM_CACHE
-+ ZFS_AC_KERNEL_WAIT
- ZFS_AC_KERNEL_INODE_TIMES
- ZFS_AC_KERNEL_INODE_LOCK
- ZFS_AC_KERNEL_GROUP_INFO_GID
-- ZFS_AC_KERNEL_WRITE
-- ZFS_AC_KERNEL_READ
-+ ZFS_AC_KERNEL_RW
- ZFS_AC_KERNEL_TIMER_SETUP
-- ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
- ZFS_AC_KERNEL_CURRENT_BIO_TAIL
- ZFS_AC_KERNEL_SUPER_USER_NS
- ZFS_AC_KERNEL_SUBMIT_BIO
-- ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
-- ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
-- ZFS_AC_KERNEL_TYPE_FMODE_T
-+ ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS
- ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH
- ZFS_AC_KERNEL_BLKDEV_REREAD_PART
-- ZFS_AC_KERNEL_OPEN_BDEV_EXCLUSIVE
-+ ZFS_AC_KERNEL_INVALIDATE_BDEV
- ZFS_AC_KERNEL_LOOKUP_BDEV
-- ZFS_AC_KERNEL_INVALIDATE_BDEV_ARGS
-+ ZFS_AC_KERNEL_BDEV_OPEN_EXCLUSIVE
- ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE
- ZFS_AC_KERNEL_BDEV_PHYSICAL_BLOCK_SIZE
- ZFS_AC_KERNEL_BIO_BVEC_ITER
-- ZFS_AC_KERNEL_BIO_FAILFAST_DTD
-+ ZFS_AC_KERNEL_BIO_FAILFAST
- ZFS_AC_KERNEL_BIO_SET_DEV
-- ZFS_AC_KERNEL_REQ_FAILFAST_MASK
-- ZFS_AC_KERNEL_REQ_OP_DISCARD
-- ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE
-- ZFS_AC_KERNEL_REQ_OP_FLUSH
-- ZFS_AC_KERNEL_BIO_BI_OPF
-+ ZFS_AC_KERNEL_BIO_OPS
- ZFS_AC_KERNEL_BIO_END_IO_T_ARGS
- ZFS_AC_KERNEL_BIO_BI_STATUS
- ZFS_AC_KERNEL_BIO_RW_BARRIER
- ZFS_AC_KERNEL_BIO_RW_DISCARD
- ZFS_AC_KERNEL_BLK_QUEUE_BDI
-- ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR
-- ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET
-+ ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
-+ ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
-+ ZFS_AC_KERNEL_BLK_QUEUE_FLAGS
- ZFS_AC_KERNEL_BLK_QUEUE_FLUSH
- ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS
- ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS
-- ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG
-- ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BLK_PLUG
-+ ZFS_AC_KERNEL_BLK_QUEUE_PLUG
- ZFS_AC_KERNEL_GET_DISK_AND_MODULE
- ZFS_AC_KERNEL_GET_DISK_RO
-- ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS
- ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL
- ZFS_AC_KERNEL_DISCARD_GRANULARITY
-- ZFS_AC_KERNEL_CONST_XATTR_HANDLER
-- ZFS_AC_KERNEL_XATTR_HANDLER_NAME
-- ZFS_AC_KERNEL_XATTR_HANDLER_GET
-- ZFS_AC_KERNEL_XATTR_HANDLER_SET
-- ZFS_AC_KERNEL_XATTR_HANDLER_LIST
- ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE
-- ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS
-- ZFS_AC_KERNEL_POSIX_ACL_RELEASE
-- ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE
-- ZFS_AC_KERNEL_POSIX_ACL_CHMOD
-- ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
-- ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS
-- ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION
-- ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
-- ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
-- ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
-- ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
-- ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
-- ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR
-+ ZFS_AC_KERNEL_XATTR
-+ ZFS_AC_KERNEL_ACL
-+ ZFS_AC_KERNEL_INODE_GETATTR
- ZFS_AC_KERNEL_INODE_SET_FLAGS
- ZFS_AC_KERNEL_INODE_SET_IVERSION
-- ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE
- ZFS_AC_KERNEL_SHOW_OPTIONS
- ZFS_AC_KERNEL_FILE_INODE
- ZFS_AC_KERNEL_FILE_DENTRY
- ZFS_AC_KERNEL_FSYNC
-- ZFS_AC_KERNEL_EVICT_INODE
-- ZFS_AC_KERNEL_DIRTY_INODE_WITH_FLAGS
-- ZFS_AC_KERNEL_NR_CACHED_OBJECTS
-- ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
-- ZFS_AC_KERNEL_FALLOCATE
- ZFS_AC_KERNEL_AIO_FSYNC
-+ ZFS_AC_KERNEL_EVICT_INODE
-+ ZFS_AC_KERNEL_DIRTY_INODE
-+ ZFS_AC_KERNEL_SHRINKER
- ZFS_AC_KERNEL_MKDIR_UMODE_T
- ZFS_AC_KERNEL_LOOKUP_NAMEIDATA
- ZFS_AC_KERNEL_CREATE_NAMEIDATA
-@@ -120,58 +226,38 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
- ZFS_AC_KERNEL_CLEAR_INODE
- ZFS_AC_KERNEL_SETATTR_PREPARE
- ZFS_AC_KERNEL_INSERT_INODE_LOCKED
-- ZFS_AC_KERNEL_D_MAKE_ROOT
-- ZFS_AC_KERNEL_D_OBTAIN_ALIAS
-- ZFS_AC_KERNEL_D_PRUNE_ALIASES
-- ZFS_AC_KERNEL_D_SET_D_OP
-- ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA
-- ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS
-+ ZFS_AC_KERNEL_DENTRY
- ZFS_AC_KERNEL_TRUNCATE_SETSIZE
-- ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY
-- ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY
-+ ZFS_AC_KERNEL_SECURITY_INODE
- ZFS_AC_KERNEL_FST_MOUNT
-- ZFS_AC_KERNEL_SHRINK
-- ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID
-- ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT
-- ZFS_AC_KERNEL_SHRINKER_CALLBACK
-- ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD
-- ZFS_AC_KERNEL_S_D_OP
- ZFS_AC_KERNEL_BDI
- ZFS_AC_KERNEL_SET_NLINK
- ZFS_AC_KERNEL_ELEVATOR_CHANGE
-- ZFS_AC_KERNEL_5ARG_SGET
-+ ZFS_AC_KERNEL_SGET
- ZFS_AC_KERNEL_LSEEK_EXECUTE
-+ ZFS_AC_KERNEL_VFS_GETATTR
-+ ZFS_AC_KERNEL_VFS_FSYNC_2ARGS
- ZFS_AC_KERNEL_VFS_ITERATE
-- ZFS_AC_KERNEL_VFS_RW_ITERATE
- ZFS_AC_KERNEL_VFS_DIRECT_IO
-- ZFS_AC_KERNEL_GENERIC_WRITE_CHECKS
-+ ZFS_AC_KERNEL_VFS_RW_ITERATE
-+ ZFS_AC_KERNEL_VFS_GENERIC_WRITE_CHECKS
- ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS
- ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
- ZFS_AC_KERNEL_MAKE_REQUEST_FN
-- ZFS_AC_KERNEL_GENERIC_IO_ACCT_3ARG
-- ZFS_AC_KERNEL_GENERIC_IO_ACCT_4ARG
-+ ZFS_AC_KERNEL_GENERIC_IO_ACCT
- ZFS_AC_KERNEL_FPU
-+ ZFS_AC_KERNEL_FMODE_T
-+ ZFS_AC_KERNEL_KUIDGID_T
- ZFS_AC_KERNEL_KUID_HELPERS
- ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST
- ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
-- ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR
- ZFS_AC_KERNEL_CURRENT_TIME
-- ZFS_AC_KERNEL_GLOBAL_PAGE_STATE
-- ZFS_AC_KERNEL_ACL_HAS_REFCOUNT
- ZFS_AC_KERNEL_USERNS_CAPABILITIES
- ZFS_AC_KERNEL_IN_COMPAT_SYSCALL
- ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64
- ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC
- ZFS_AC_KERNEL_TOTALHIGH_PAGES
-- ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
-- ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
- ZFS_AC_KERNEL_KSTRTOUL
--
-- AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
-- KERNEL_MAKE="$KERNEL_MAKE O=$LINUX_OBJ"
-- ])
--
-- AC_SUBST(KERNEL_MAKE)
- ])
-
- dnl #
-@@ -190,9 +276,10 @@ AC_DEFUN([ZFS_AC_MODULE_SYMVERS], [
- AS_IF([test ! -f "$LINUX_OBJ/$LINUX_SYMBOLS"], [
- AC_MSG_ERROR([
- *** Please make sure the kernel devel package for your distribution
-- *** is installed. If you are building with a custom kernel, make sure the
-- *** kernel is configured, built, and the '--with-linux=PATH' configure
-- *** option refers to the location of the kernel source.])
-+ *** is installed. If you are building with a custom kernel, make sure
-+ *** the kernel is configured, built, and the '--with-linux=PATH'
-+ *** configure option refers to the location of the kernel source.
-+ ])
- ])
- ], [
- LINUX_SYMBOLS=NONE
-@@ -285,12 +372,16 @@ AC_DEFUN([ZFS_AC_KERNEL], [
-
- AS_IF([test -z "$kernsrcver"], [
- AC_MSG_RESULT([Not found])
-- AC_MSG_ERROR([*** Cannot determine kernel version.])
-+ AC_MSG_ERROR([
-+ *** Cannot determine kernel version.
-+ ])
- ])
- ], [
- AC_MSG_RESULT([Not found])
- if test "x$enable_linux_builtin" != xyes; then
-- AC_MSG_ERROR([*** Cannot find UTS_RELEASE definition.])
-+ AC_MSG_ERROR([
-+ *** Cannot find UTS_RELEASE definition.
-+ ])
- else
- AC_MSG_ERROR([
- *** Cannot find UTS_RELEASE definition.
-@@ -312,24 +403,27 @@ AC_DEFUN([ZFS_AC_KERNEL], [
- ])
-
- dnl #
--dnl # Detect the QAT module to be built against
--dnl # QAT provides hardware acceleration for data compression:
--dnl # https://01.org/intel-quickassist-technology
--dnl # * Download and install QAT driver from the above link
--dnl # * Start QAT driver in your system:
--dnl # service qat_service start
--dnl # * Enable QAT in ZFS, e.g.:
--dnl # ./configure --with-qat=<qat-driver-path>/QAT1.6
--dnl # make
--dnl # * Set GZIP compression in ZFS dataset:
--dnl # zfs set compression = gzip <dataset>
--dnl # Then the data written to this ZFS pool is compressed
--dnl # by QAT accelerator automatically, and de-compressed by
--dnl # QAT when read from the pool.
--dnl # * Get QAT hardware statistics by:
--dnl # cat /proc/icp_dh895xcc_dev/qat
--dnl # * To disable QAT:
--dnl # insmod zfs.ko zfs_qat_disable=1
-+dnl # Detect the QAT module to be built against, QAT provides hardware
-+dnl # acceleration for data compression:
-+dnl #
-+dnl # https://01.org/intel-quickassist-technology
-+dnl #
-+dnl # 1) Download and install QAT driver from the above link
-+dnl # 2) Start QAT driver in your system:
-+dnl # service qat_service start
-+dnl # 3) Enable QAT in ZFS, e.g.:
-+dnl # ./configure --with-qat=<qat-driver-path>/QAT1.6
-+dnl # make
-+dnl # 4) Set GZIP compression in ZFS dataset:
-+dnl # zfs set compression = gzip <dataset>
-+dnl #
-+dnl # Then the data written to this ZFS pool is compressed by QAT accelerator
-+dnl # automatically, and de-compressed by QAT when read from the pool.
-+dnl #
-+dnl # 1) Get QAT hardware statistics with:
-+dnl # cat /proc/icp_dh895xcc_dev/qat
-+dnl # 2) To disable QAT:
-+dnl # insmod zfs.ko zfs_qat_disable=1
- dnl #
- AC_DEFUN([ZFS_AC_QAT], [
- AC_ARG_WITH([qat],
-@@ -350,11 +444,11 @@ AC_DEFUN([ZFS_AC_QAT], [
- QAT_SRC="${qatsrc}/quickassist"
- AS_IF([ test ! -e "$QAT_SRC/include/cpa.h"], [
- AC_MSG_ERROR([
-- *** Please make sure the qat driver package is installed
-- *** and specify the location of the qat source with the
-- *** '--with-qat=PATH' option then try again. Failed to
-- *** find cpa.h in:
-- ${QAT_SRC}/include])
-+ *** Please make sure the qat driver package is installed
-+ *** and specify the location of the qat source with the
-+ *** '--with-qat=PATH' option then try again. Failed to
-+ *** find cpa.h in:
-+ ${QAT_SRC}/include])
- ])
- ])
-
-@@ -368,9 +462,9 @@ AC_DEFUN([ZFS_AC_QAT], [
- QAT_OBJ=${qatbuild}
- AS_IF([ ! test -e "$QAT_OBJ/icp_qa_al.ko" && ! test -e "$QAT_OBJ/qat_api.ko"], [
- AC_MSG_ERROR([
-- *** Please make sure the qat driver is installed then try again.
-- *** Failed to find icp_qa_al.ko or qat_api.ko in:
-- $QAT_OBJ])
-+ *** Please make sure the qat driver is installed then try again.
-+ *** Failed to find icp_qa_al.ko or qat_api.ko in:
-+ $QAT_OBJ])
- ])
-
- AC_SUBST(QAT_SRC)
-@@ -391,10 +485,10 @@ AC_DEFUN([ZFS_AC_QAT], [
- AC_MSG_RESULT([$QAT_SYMBOLS])
- AC_SUBST(QAT_SYMBOLS)
- ],[
-- AC_MSG_ERROR([
-- *** Please make sure the qat driver is installed then try again.
-- *** Failed to find Module.symvers in:
-- $QAT_SYMBOLS])
-+ AC_MSG_ERROR([
-+ *** Please make sure the qat driver is installed then try again.
-+ *** Failed to find Module.symvers in:
-+ $QAT_SYMBOLS
- ])
- ])
- ])
-@@ -403,14 +497,16 @@ AC_DEFUN([ZFS_AC_QAT], [
- dnl #
- dnl # Basic toolchain sanity check.
- dnl #
--AC_DEFUN([ZFS_AC_TEST_MODULE], [
-+AC_DEFUN([ZFS_AC_KERNEL_TEST_MODULE], [
- AC_MSG_CHECKING([whether modules can be built])
-- ZFS_LINUX_TRY_COMPILE([],[],[
-+ ZFS_LINUX_TRY_COMPILE([], [], [
- AC_MSG_RESULT([yes])
- ],[
- AC_MSG_RESULT([no])
- if test "x$enable_linux_builtin" != xyes; then
-- AC_MSG_ERROR([*** Unable to build an empty module.])
-+ AC_MSG_ERROR([
-+ *** Unable to build an empty module.
-+ ])
- else
- AC_MSG_ERROR([
- *** Unable to build an empty module.
-@@ -420,207 +516,313 @@ AC_DEFUN([ZFS_AC_TEST_MODULE], [
- ])
-
- dnl #
--dnl # Certain kernel build options are not supported. These must be
--dnl # detected at configure time and cause a build failure. Otherwise
--dnl # modules may be successfully built that behave incorrectly.
-+dnl # ZFS_LINUX_CONFTEST_H
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CONFIG], [
-- AS_IF([test "x$cross_compiling" != xyes], [
-- AC_RUN_IFELSE([
-- AC_LANG_PROGRAM([
-- #include "$LINUX/include/linux/license.h"
-- ], [
-- return !license_is_gpl_compatible("$ZFS_META_LICENSE");
-- ])
-- ], [
-- AC_DEFINE([ZFS_IS_GPL_COMPATIBLE], [1],
-- [Define to 1 if GPL-only symbols can be used])
-- ], [
-- ])
-- ])
-+AC_DEFUN([ZFS_LINUX_CONFTEST_H], [
-+test -d build/$2 || mkdir -p build/$2
-+cat - <<_ACEOF >build/$2/$2.h
-+$1
-+_ACEOF
-+])
-
-- ZFS_AC_KERNEL_CONFIG_THREAD_SIZE
-- ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC
-- ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS
-- ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE
-- ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE
-+dnl #
-+dnl # ZFS_LINUX_CONFTEST_C
-+dnl #
-+AC_DEFUN([ZFS_LINUX_CONFTEST_C], [
-+test -d build/$2 || mkdir -p build/$2
-+cat confdefs.h - <<_ACEOF >build/$2/$2.c
-+$1
-+_ACEOF
- ])
-
- dnl #
--dnl # Check configured THREAD_SIZE
-+dnl # ZFS_LINUX_CONFTEST_MAKEFILE
- dnl #
--dnl # The stack size will vary by architecture, but as of Linux 3.15 on x86_64
--dnl # the default thread stack size was increased to 16K from 8K. Therefore,
--dnl # on newer kernels and some architectures stack usage optimizations can be
--dnl # conditionally applied to improve performance without negatively impacting
--dnl # stability.
-+dnl # $1 - test case name
-+dnl # $2 - add to top-level Makefile
-+dnl # $3 - additional build flags
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CONFIG_THREAD_SIZE], [
-- AC_MSG_CHECKING([whether kernel was built with 16K or larger stacks])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/module.h>
-- ],[
-- #if (THREAD_SIZE < 16384)
-- #error "THREAD_SIZE is less than 16K"
-- #endif
-- ],[
-- AC_MSG_RESULT([yes])
-- AC_DEFINE(HAVE_LARGE_STACKS, 1, [kernel has large stacks])
-- ],[
-- AC_MSG_RESULT([no])
-- ])
-+AC_DEFUN([ZFS_LINUX_CONFTEST_MAKEFILE], [
-+ test -d build || mkdir -p build
-+ test -d build/$1 || mkdir -p build/$1
-+
-+ file=build/$1/Makefile
-+
-+ dnl # Example command line to manually build source.
-+ cat - <<_ACEOF >$file
-+# Example command line to manually build source
-+# make modules -C $LINUX_OBJ $ARCH_UM M=$PWD/build/$1
-+
-+ccflags-y := -Werror $FRAME_LARGER_THAN
-+_ACEOF
-+
-+ dnl # Additional custom CFLAGS as requested.
-+ m4_ifval($3, [echo "ccflags-y += $3" >>$file], [])
-+
-+ dnl # Test case source
-+ echo "obj-m := $1.o" >>$file
-+
-+ AS_IF([test "x$2" = "xyes"], [echo "obj-m += $1/" >>build/Makefile], [])
- ])
-
- dnl #
--dnl # Check CONFIG_DEBUG_LOCK_ALLOC
-+dnl # ZFS_LINUX_TEST_PROGRAM(C)([PROLOGUE], [BODY])
- dnl #
--dnl # This is typically only set for debug kernels because it comes with
--dnl # a performance penalty. However, when it is set it maps the non-GPL
--dnl # symbol mutex_lock() to the GPL-only mutex_lock_nested() symbol.
--dnl # This will cause a failure at link time which we'd rather know about
--dnl # at compile time.
-+m4_define([ZFS_LINUX_TEST_PROGRAM], [
-+$1
-+int
-+main (void)
-+{
-+$2
-+ ;
-+ return 0;
-+}
-+])
-+
- dnl #
--dnl # Since we plan to pursue making mutex_lock_nested() a non-GPL symbol
--dnl # with the upstream community we add a check to detect this case.
-+dnl # ZFS_LINUX_TEST_REMOVE
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [
--
-- ZFS_LINUX_CONFIG([DEBUG_LOCK_ALLOC], [
-- AC_MSG_CHECKING([whether mutex_lock() is GPL-only])
-- tmp_flags="$EXTRA_KCFLAGS"
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/module.h>
-- #include <linux/mutex.h>
--
-- MODULE_LICENSE("$ZFS_META_LICENSE");
-- ],[
-- struct mutex lock;
-+dnl # Removes the specified test source and results.
-+dnl #
-+AC_DEFUN([ZFS_LINUX_TEST_REMOVE], [
-+ test -d build/$1 && rm -Rf build/$1
-+ test -f build/Makefile && sed '/$1/d' build/Makefile
-+])
-
-- mutex_init(&lock);
-- mutex_lock(&lock);
-- mutex_unlock(&lock);
-- ],[
-- AC_MSG_RESULT(no)
-- ],[
-- AC_MSG_RESULT(yes)
-- AC_MSG_ERROR([
-- *** Kernel built with CONFIG_DEBUG_LOCK_ALLOC which is incompatible
-- *** with the CDDL license and will prevent the module linking stage
-- *** from succeeding. You must rebuild your kernel without this
-- *** option enabled.])
-- ])
-- EXTRA_KCFLAGS="$tmp_flags"
-- ], [])
-+dnl #
-+dnl # ZFS_LINUX_COMPILE
-+dnl #
-+dnl # $1 - build dir
-+dnl # $2 - test command
-+dnl # $3 - pass command
-+dnl # $4 - fail command
-+dnl # $5 - set KBUILD_MODPOST_NOFINAL='yes'
-+dnl # $6 - set KBUILD_MODPOST_WARN='yes'
-+dnl #
-+dnl # Used internally by ZFS_LINUX_TEST_{COMPILE,MODPOST}
-+dnl #
-+AC_DEFUN([ZFS_LINUX_COMPILE], [
-+ AC_TRY_COMMAND([
-+ KBUILD_MODPOST_NOFINAL="$5" KBUILD_MODPOST_WARN="$6"
-+ make modules -k -j$TEST_JOBS -C $LINUX_OBJ $ARCH_UM
-+ M=$PWD/$1 &>$1/build.log])
-+ AS_IF([AC_TRY_COMMAND([$2])], [$3], [$4])
- ])
-
- dnl #
--dnl # Check CONFIG_TRIM_UNUSED_KSYMS
-+dnl # ZFS_LINUX_TEST_COMPILE
- dnl #
--dnl # Verify the kernel has CONFIG_TRIM_UNUSED_KSYMS disabled.
-+dnl # Perform a full compile excluding the final modpost phase.
- dnl #
--AC_DEFUN([ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS], [
-- AC_MSG_CHECKING([whether CONFIG_TRIM_UNUSED_KSYM is disabled])
-- ZFS_LINUX_TRY_COMPILE([
-- #if defined(CONFIG_TRIM_UNUSED_KSYMS)
-- #error CONFIG_TRIM_UNUSED_KSYMS not defined
-- #endif
-- ],[ ],[
-- AC_MSG_RESULT([yes])
-+AC_DEFUN([ZFS_LINUX_TEST_COMPILE], [
-+ ZFS_LINUX_COMPILE([$2], [test -f $2/build.log], [
-+ mv $2/Makefile $2/Makefile.compile.$1
-+ mv $2/build.log $2/build.log.$1
- ],[
-- AC_MSG_RESULT([no])
-- AS_IF([test "x$enable_linux_builtin" != xyes], [
-- AC_MSG_ERROR([
-- *** This kernel has unused symbols trimming enabled, please disable.
-- *** Rebuild the kernel with CONFIG_TRIM_UNUSED_KSYMS=n set.])
-- ])])
-+ AC_MSG_ERROR([
-+ *** Unable to compile test source to determine kernel interfaces.])
-+ ], [yes], [])
- ])
-
- dnl #
--dnl # ZFS_LINUX_CONFTEST_H
-+dnl # ZFS_LINUX_TEST_MODPOST
- dnl #
--AC_DEFUN([ZFS_LINUX_CONFTEST_H], [
--cat - <<_ACEOF >conftest.h
--$1
--_ACEOF
-+dnl # Perform a full compile including the modpost phase. This may
-+dnl # be an incremental build if the objects have already been built.
-+dnl #
-+AC_DEFUN([ZFS_LINUX_TEST_MODPOST], [
-+ ZFS_LINUX_COMPILE([$2], [test -f $2/build.log], [
-+ mv $2/Makefile $2/Makefile.modpost.$1
-+ cat $2/build.log >>build/build.log.$1
-+ ],[
-+ AC_MSG_ERROR([
-+ *** Unable to modpost test source to determine kernel interfaces.])
-+ ], [], [yes])
- ])
-
- dnl #
--dnl # ZFS_LINUX_CONFTEST_C
-+dnl # Perform the compilation of the test cases in two phases.
- dnl #
--AC_DEFUN([ZFS_LINUX_CONFTEST_C], [
--cat confdefs.h - <<_ACEOF >conftest.c
--$1
--_ACEOF
-+dnl # Phase 1) attempt to build the object files for all of the tests
-+dnl # defined by the ZFS_LINUX_TEST_SRC macro. But do not
-+dnl # perform the final modpost stage.
-+dnl #
-+dnl # Phase 2) disable all tests which failed the initial compilation,
-+dnl # then invoke the final modpost step for the remaining tests.
-+dnl #
-+dnl # This allows us efficiently build the test cases in parallel while
-+dnl # remaining resilient to build failures which are expected when
-+dnl # detecting the available kernel interfaces.
-+dnl #
-+dnl # The maximum allowed parallelism can be controlled by setting the
-+dnl # TEST_JOBS environment variable. Otherwise, it default to $(nproc).
-+dnl #
-+AC_DEFUN([ZFS_LINUX_TEST_COMPILE_ALL], [
-+ dnl # Phase 1 - Compilation only, final linking is skipped.
-+ ZFS_LINUX_TEST_COMPILE([$1], [build])
-+
-+ dnl #
-+ dnl # Phase 2 - When building external modules disable test cases
-+ dnl # which failed to compile and invoke modpost to verify the
-+ dnl # final linking.
-+ dnl #
-+ dnl # Test names suffixed with '_license' call modpost independently
-+ dnl # to ensure that a single incompatibility does not result in the
-+ dnl # modpost phase exiting early. This check is not performed on
-+ dnl # every symbol since the majority are compatible and doing so
-+ dnl # would significantly slow down this phase.
-+ dnl #
-+ dnl # When configuring for builtin (--enable-linux-builtin)
-+ dnl # fake the linking step artificially create the expected .ko
-+ dnl # files for tests which did compile. This is required for
-+ dnl # kernels which do not have loadable module support or have
-+ dnl # not yet been built.
-+ dnl #
-+ AS_IF([test "x$enable_linux_builtin" = "xno"], [
-+ for dir in $(awk '/^obj-m/ { print [$]3 }' \
-+ build/Makefile.compile.$1); do
-+ name=${dir%/}
-+ AS_IF([test -f build/$name/$name.o], [
-+ AS_IF([test "${name##*_}" = "license"], [
-+ ZFS_LINUX_TEST_MODPOST([$1],
-+ [build/$name])
-+ echo "obj-n += $dir" >>build/Makefile
-+ ], [
-+ echo "obj-m += $dir" >>build/Makefile
-+ ])
-+ ], [
-+ echo "obj-n += $dir" >>build/Makefile
-+ ])
-+ done
-+
-+ ZFS_LINUX_TEST_MODPOST([$1], [build])
-+ ], [
-+ for dir in $(awk '/^obj-m/ { print [$]3 }' \
-+ build/Makefile.compile.$1); do
-+ name=${dir%/}
-+ AS_IF([test -f build/$name/$name.o], [
-+ touch build/$name/$name.ko
-+ ])
-+ done
-+ ])
- ])
-
- dnl #
--dnl # ZFS_LANG_PROGRAM(C)([PROLOGUE], [BODY])
-+dnl # ZFS_LINUX_TEST_SRC
- dnl #
--m4_define([ZFS_LANG_PROGRAM], [
--$1
--int
--main (void)
--{
--dnl Do *not* indent the following line: there may be CPP directives.
--dnl Don't move the `;' right after for the same reason.
--$2
-- ;
-- return 0;
--}
-+dnl # $1 - name
-+dnl # $2 - global
-+dnl # $3 - source
-+dnl # $4 - extra cflags
-+dnl # $5 - check license-compatibility
-+dnl #
-+dnl # N.B because all of the test cases are compiled in parallel they
-+dnl # must never depend on the results of previous tests. Each test
-+dnl # needs to be entirely independent.
-+dnl #
-+AC_DEFUN([ZFS_LINUX_TEST_SRC], [
-+ ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM([[$2]], [[$3]])], [$1])
-+ ZFS_LINUX_CONFTEST_MAKEFILE([$1], [yes], [$4])
-+
-+ AS_IF([ test -n "$5" ], [
-+ ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM([[
-+ #include <linux/module.h>
-+ MODULE_LICENSE("$5");
-+ $2]], [[$3]])], [$1_license])
-+ ZFS_LINUX_CONFTEST_MAKEFILE([$1_license], [yes], [$4])
-+ ])
- ])
-
- dnl #
--dnl # ZFS_LINUX_COMPILE_IFELSE / like AC_COMPILE_IFELSE
-+dnl # ZFS_LINUX_TEST_RESULT
- dnl #
--AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [
-- m4_ifvaln([$1], [ZFS_LINUX_CONFTEST_C([$1])])
-- m4_ifvaln([$6], [ZFS_LINUX_CONFTEST_H([$6])], [ZFS_LINUX_CONFTEST_H([])])
-- rm -Rf build && mkdir -p build && touch build/conftest.mod.c
-- echo "obj-m := conftest.o" >build/Makefile
-- modpost_flag=''
-- test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
-- AS_IF(
-- [AC_TRY_COMMAND(cp conftest.c conftest.h build && make [$2] -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $FRAME_LARGER_THAN $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag) >/dev/null && AC_TRY_COMMAND([$3])],
-- [$4],
-- [_AC_MSG_LOG_CONFTEST m4_ifvaln([$5],[$5])]
-- )
-- rm -Rf build
-+dnl # $1 - name of a test source (ZFS_LINUX_TEST_SRC)
-+dnl # $2 - run on success (valid .ko generated)
-+dnl # $3 - run on failure (unable to compile)
-+dnl #
-+AC_DEFUN([ZFS_LINUX_TEST_RESULT], [
-+ AS_IF([test -d build/$1], [
-+ AS_IF([test -f build/$1/$1.ko], [$2], [$3])
-+ ], [
-+ AC_MSG_ERROR([
-+ *** No matching source for the "$1" test, check that
-+ *** both the test source and result macros refer to the same name.
-+ ])
-+ ])
- ])
-
- dnl #
--dnl # ZFS_LINUX_TRY_COMPILE like AC_TRY_COMPILE
-+dnl # ZFS_LINUX_TEST_ERROR
- dnl #
--AC_DEFUN([ZFS_LINUX_TRY_COMPILE],
-- [ZFS_LINUX_COMPILE_IFELSE(
-- [AC_LANG_SOURCE([ZFS_LANG_PROGRAM([[$1]], [[$2]])])],
-- [modules],
-- [test -s build/conftest.o],
-- [$3], [$4])
-+dnl # Generic error message which can be used when none of the expected
-+dnl # kernel interfaces were detected.
-+dnl #
-+AC_DEFUN([ZFS_LINUX_TEST_ERROR], [
-+ AC_MSG_ERROR([
-+ *** None of the expected "$1" interfaces were detected.
-+ *** This may be because your kernel version is newer than what is
-+ *** supported, or you are using a patched custom kernel with
-+ *** incompatible modifications.
-+ ***
-+ *** ZFS Version: $ZFS_META_ALIAS
-+ *** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
-+ ])
- ])
-
- dnl #
--dnl # ZFS_LINUX_CONFIG
-+dnl # ZFS_LINUX_TEST_RESULT_SYMBOL
- dnl #
--AC_DEFUN([ZFS_LINUX_CONFIG],
-- [AC_MSG_CHECKING([whether kernel was built with CONFIG_$1])
-- ZFS_LINUX_TRY_COMPILE([
-- #include <linux/module.h>
-- ],[
-- #ifndef CONFIG_$1
-- #error CONFIG_$1 not #defined
-- #endif
-- ],[
-- AC_MSG_RESULT([yes])
-- $2
-- ],[
-- AC_MSG_RESULT([no])
-- $3
-+dnl # Like ZFS_LINUX_TEST_RESULT except ZFS_CHECK_SYMBOL_EXPORT is called to
-+dnl # verify symbol exports, unless --enable-linux-builtin was provided to
-+dnl # configure.
-+dnl #
-+AC_DEFUN([ZFS_LINUX_TEST_RESULT_SYMBOL], [
-+ AS_IF([ ! test -f build/$1/$1.ko], [
-+ $5
-+ ], [
-+ AS_IF([test "x$enable_linux_builtin" != "xyes"], [
-+ ZFS_CHECK_SYMBOL_EXPORT([$2], [$3], [$4], [$5])
-+ ], [
-+ $4
-+ ])
- ])
- ])
-
-+dnl #
-+dnl # ZFS_LINUX_COMPILE_IFELSE
-+dnl #
-+AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [
-+ ZFS_LINUX_TEST_REMOVE([conftest])
-+
-+ m4_ifvaln([$1], [ZFS_LINUX_CONFTEST_C([$1], [conftest])])
-+ m4_ifvaln([$5], [ZFS_LINUX_CONFTEST_H([$5], [conftest])],
-+ [ZFS_LINUX_CONFTEST_H([], [conftest])])
-+
-+ ZFS_LINUX_CONFTEST_MAKEFILE([conftest], [no],
-+ [m4_ifvaln([$5], [-I$PWD/build/conftest], [])])
-+ ZFS_LINUX_COMPILE([build/conftest], [$2], [$3], [$4], [], [])
-+])
-+
-+dnl #
-+dnl # ZFS_LINUX_TRY_COMPILE
-+dnl #
-+dnl # $1 - global
-+dnl # $2 - source
-+dnl # $3 - run on success (valid .ko generated)
-+dnl # $4 - run on failure (unable to compile)
-+dnl #
-+AC_DEFUN([ZFS_LINUX_TRY_COMPILE], [
-+ ZFS_LINUX_COMPILE_IFELSE(
-+ [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]])],
-+ [test -f build/conftest/conftest.ko],
-+ [$3], [$4])
-+])
-+
- dnl #
- dnl # ZFS_CHECK_SYMBOL_EXPORT
--dnl # check symbol exported or not
-+dnl #
-+dnl # Check if a symbol is exported on not by consulting the symbols
-+dnl # file, or optionally the source code.
- dnl #
- AC_DEFUN([ZFS_CHECK_SYMBOL_EXPORT], [
- grep -q -E '[[[:space:]]]$1[[[:space:]]]' \
-@@ -649,8 +851,10 @@ AC_DEFUN([ZFS_CHECK_SYMBOL_EXPORT], [
-
- dnl #
- dnl # ZFS_LINUX_TRY_COMPILE_SYMBOL
--dnl # like ZFS_LINUX_TRY_COMPILE, except ZFS_CHECK_SYMBOL_EXPORT
--dnl # is called if not compiling for builtin
-+dnl #
-+dnl # Like ZFS_LINUX_TRY_COMPILER except ZFS_CHECK_SYMBOL_EXPORT is called
-+dnl # to verify symbol exports, unless --enable-linux-builtin was provided
-+dnl # to configure.
- dnl #
- AC_DEFUN([ZFS_LINUX_TRY_COMPILE_SYMBOL], [
- ZFS_LINUX_TRY_COMPILE([$1], [$2], [rc=0], [rc=1])
-@@ -673,10 +877,9 @@ dnl # ZFS_LINUX_TRY_COMPILE_HEADER
- dnl # like ZFS_LINUX_TRY_COMPILE, except the contents conftest.h are
- dnl # provided via the fifth parameter
- dnl #
--AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER],
-- [ZFS_LINUX_COMPILE_IFELSE(
-- [AC_LANG_SOURCE([ZFS_LANG_PROGRAM([[$1]], [[$2]])])],
-- [modules],
-- [test -s build/conftest.o],
-- [$3], [$4], [$5])
-+AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [
-+ ZFS_LINUX_COMPILE_IFELSE(
-+ [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]])],
-+ [test -f build/conftest/conftest.ko],
-+ [$3], [$4], [$5])
- ])
-diff --git a/config/zfs-build.m4 b/config/zfs-build.m4
-index 8e221f2d7..d2c355425 100644
---- a/config/zfs-build.m4
-+++ b/config/zfs-build.m4
-@@ -166,6 +166,17 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
- ])
-
- AC_DEFUN([ZFS_AC_CONFIG], [
-+
-+ dnl # Remove the previous build test directory.
-+ rm -Rf build
-+
-+ AC_ARG_VAR([TEST_JOBS],
-+ [simultaneous jobs during configure (defaults to $(nproc))])
-+ if test "x$ac_cv_env_TEST_JOBS_set" != "xset"; then
-+ TEST_JOBS=$(nproc)
-+ fi
-+ AC_SUBST(TEST_JOBS)
-+
- ZFS_CONFIG=all
- AC_ARG_WITH([config],
- AS_HELP_STRING([--with-config=CONFIG],
-diff --git a/config/zfs-meta.m4 b/config/zfs-meta.m4
-index f525e2010..660d8ccb9 100644
---- a/config/zfs-meta.m4
-+++ b/config/zfs-meta.m4
-@@ -162,6 +162,24 @@ AC_DEFUN([ZFS_AC_META], [
- AC_SUBST([ZFS_META_AUTHOR])
- fi
-
-+ ZFS_META_KVER_MIN=_ZFS_AC_META_GETVAL([Linux-Minimum]);
-+ if test -n "$ZFS_META_KVER_MIN"; then
-+ AC_DEFINE_UNQUOTED([ZFS_META_KVER_MIN],
-+ ["$ZFS_META_KVER_MIN"],
-+ [Define the minimum compatible kernel version.]
-+ )
-+ AC_SUBST([ZFS_META_KVER_MIN])
-+ fi
-+
-+ ZFS_META_KVER_MAX=_ZFS_AC_META_GETVAL([Linux-Maximum]);
-+ if test -n "$ZFS_META_KVER_MAX"; then
-+ AC_DEFINE_UNQUOTED([ZFS_META_KVER_MAX],
-+ ["$ZFS_META_KVER_MAX"],
-+ [Define the maximum compatible kernel version.]
-+ )
-+ AC_SUBST([ZFS_META_KVER_MAX])
-+ fi
-+
- m4_pattern_allow([^LT_(CURRENT|REVISION|AGE)$])
- ZFS_META_LT_CURRENT=_ZFS_AC_META_GETVAL([LT_Current]);
- ZFS_META_LT_REVISION=_ZFS_AC_META_GETVAL([LT_Revision]);
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Matthew Macy <mmacy@mattmacy.io>
+Date: Thu, 5 Sep 2019 09:34:54 -0700
+Subject: [PATCH] OpenZFS restructuring - move platform specific headers
+
+Move platform specific Linux headers under include/os/linux/.
+Update the build system accordingly to detect the platform.
+This lays some of the initial groundwork to supporting building
+for other platforms.
+
+As part of this change it was necessary to create both a user
+and kernel space sys/simd.h header which can be included in
+either context. No functional change, the source has been
+refactored and the relevant #include's updated.
+
+Reviewed-by: Jorgen Lundman <lundman@lundman.net>
+Reviewed-by: Igor Kozhukhov <igor@dilos.org>
+Signed-off-by: Matthew Macy <mmacy@FreeBSD.org>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes #9198
+(cherry picked from commit 006e9a40882468be68f276c946bae812b74ac35c)
+Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+---
+ config/always-system.m4 | 26 +
+ config/zfs-build.m4 | 1 +
+ configure.ac | 13 +-
+ copy-builtin | 4 +-
+ include/.gitignore | 1 +
+ include/Makefile.am | 2 +-
+ include/linux/Makefile.am | 29 --
+ include/os/Makefile.am | 3 +
+ include/os/linux/Makefile.am | 1 +
+ include/os/linux/kernel/Makefile.am | 1 +
+ include/os/linux/kernel/linux/Makefile.am | 29 ++
+ .../linux/kernel}/linux/blkdev_compat.h | 0
+ .../linux/kernel}/linux/compiler_compat.h | 0
+ .../linux/kernel}/linux/dcache_compat.h | 0
+ .../{ => os/linux/kernel}/linux/kmap_compat.h | 0
+ .../{ => os/linux/kernel}/linux/mod_compat.h | 0
+ .../{ => os/linux/kernel}/linux/page_compat.h | 0
+ include/{ => os/linux/kernel}/linux/simd.h | 8 +-
+ .../linux/kernel}/linux/simd_aarch64.h | 18 +-
+ .../{ => os/linux/kernel}/linux/simd_x86.h | 357 ++------------
+ .../linux/kernel}/linux/utsname_compat.h | 0
+ .../{ => os/linux/kernel}/linux/vfs_compat.h | 0
+ .../linux/kernel}/linux/xattr_compat.h | 0
+ include/{ => os/linux}/spl/Makefile.am | 0
+ include/{ => os/linux}/spl/rpc/Makefile.am | 2 +-
+ include/{ => os/linux}/spl/rpc/xdr.h | 0
+ include/os/linux/spl/sys/Makefile.am | 62 +++
+ include/{ => os/linux}/spl/sys/acl.h | 0
+ include/{ => os/linux}/spl/sys/atomic.h | 0
+ include/{ => os/linux}/spl/sys/byteorder.h | 0
+ include/{ => os/linux}/spl/sys/callb.h | 0
+ include/{ => os/linux}/spl/sys/callo.h | 0
+ include/{ => os/linux}/spl/sys/cmn_err.h | 0
+ include/{ => os/linux}/spl/sys/condvar.h | 0
+ include/{ => os/linux}/spl/sys/console.h | 0
+ include/{ => os/linux}/spl/sys/cred.h | 0
+ include/{ => os/linux}/spl/sys/ctype.h | 0
+ include/{ => os/linux}/spl/sys/debug.h | 0
+ include/{ => os/linux}/spl/sys/disp.h | 0
+ include/{ => os/linux}/spl/sys/dkio.h | 0
+ include/{ => os/linux}/spl/sys/errno.h | 0
+ include/{ => os/linux}/spl/sys/fcntl.h | 0
+ include/{ => os/linux}/spl/sys/file.h | 0
+ include/{ => os/linux}/spl/sys/inttypes.h | 0
+ include/{ => os/linux}/spl/sys/isa_defs.h | 0
+ include/{ => os/linux}/spl/sys/kmem.h | 0
+ include/{ => os/linux}/spl/sys/kmem_cache.h | 0
+ include/{ => os/linux}/spl/sys/kobj.h | 0
+ include/{ => os/linux}/spl/sys/kstat.h | 0
+ include/{ => os/linux}/spl/sys/list.h | 0
+ include/{ => os/linux}/spl/sys/mode.h | 0
+ include/{ => os/linux}/spl/sys/mutex.h | 0
+ include/{ => os/linux}/spl/sys/param.h | 0
+ include/{ => os/linux}/spl/sys/proc.h | 0
+ include/{ => os/linux}/spl/sys/processor.h | 0
+ include/{ => os/linux}/spl/sys/procfs_list.h | 0
+ include/{ => os/linux}/spl/sys/random.h | 0
+ include/{ => os/linux}/spl/sys/rwlock.h | 0
+ include/{ => os/linux}/spl/sys/shrinker.h | 0
+ include/{ => os/linux}/spl/sys/sid.h | 0
+ include/{ => os/linux}/spl/sys/signal.h | 0
+ include/os/linux/spl/sys/simd.h | 31 ++
+ include/{ => os/linux}/spl/sys/stat.h | 0
+ include/{ => os/linux}/spl/sys/strings.h | 0
+ include/{ => os/linux}/spl/sys/sunddi.h | 0
+ include/{ => os/linux}/spl/sys/sysmacros.h | 0
+ include/{ => os/linux}/spl/sys/systeminfo.h | 0
+ include/{ => os/linux}/spl/sys/taskq.h | 0
+ include/{ => os/linux}/spl/sys/thread.h | 0
+ include/{ => os/linux}/spl/sys/time.h | 0
+ include/{ => os/linux}/spl/sys/timer.h | 0
+ include/{ => os/linux}/spl/sys/tsd.h | 0
+ include/{ => os/linux}/spl/sys/types.h | 0
+ include/{ => os/linux}/spl/sys/types32.h | 0
+ include/{ => os/linux}/spl/sys/uio.h | 0
+ include/{ => os/linux}/spl/sys/user.h | 0
+ include/{ => os/linux}/spl/sys/vfs.h | 0
+ include/{ => os/linux}/spl/sys/vmem.h | 0
+ include/{ => os/linux}/spl/sys/vmsystm.h | 0
+ include/{ => os/linux}/spl/sys/vnode.h | 0
+ include/{ => os/linux}/spl/sys/wait.h | 0
+ include/{ => os/linux}/spl/sys/zmod.h | 0
+ include/{ => os/linux}/spl/sys/zone.h | 0
+ include/os/linux/zfs/Makefile.am | 1 +
+ include/os/linux/zfs/sys/Makefile.am | 12 +
+ include/{ => os/linux/zfs}/sys/policy.h | 0
+ include/{ => os/linux/zfs}/sys/zfs_ctldir.h | 0
+ include/{ => os/linux/zfs}/sys/zfs_dir.h | 0
+ include/{ => os/linux/zfs}/sys/zfs_vfsops.h | 0
+ include/{ => os/linux/zfs}/sys/zfs_vnops.h | 0
+ include/{ => os/linux/zfs}/sys/zpl.h | 0
+ include/spl/sys/Makefile.am | 61 ---
+ include/sys/Makefile.am | 6 -
+ lib/libspl/include/sys/Makefile.am | 1 +
+ lib/libspl/include/sys/simd.h | 448 ++++++++++++++++++
+ module/Makefile.in | 4 +-
+ module/icp/algs/aes/aes_impl.c | 2 +-
+ module/icp/algs/aes/aes_impl_aesni.c | 3 +-
+ module/icp/algs/aes/aes_impl_x86-64.c | 2 +-
+ module/icp/algs/modes/gcm.c | 2 +-
+ module/icp/algs/modes/gcm_pclmulqdq.c | 4 +-
+ module/icp/io/aes.c | 4 +-
+ module/spl/spl-taskq.c | 2 +-
+ module/spl/spl-thread.c | 2 +-
+ module/zcommon/zfs_fletcher.c | 4 +-
+ module/zcommon/zfs_fletcher_aarch64_neon.c | 2 +-
+ module/zcommon/zfs_fletcher_avx512.c | 2 +-
+ module/zcommon/zfs_fletcher_intel.c | 2 +-
+ module/zcommon/zfs_fletcher_sse.c | 2 +-
+ module/zfs/vdev_raidz_math.c | 2 +-
+ .../zfs/vdev_raidz_math_aarch64_neon_common.h | 2 +-
+ module/zfs/vdev_raidz_math_avx2.c | 2 +-
+ module/zfs/vdev_raidz_math_avx512bw.c | 2 +-
+ module/zfs/vdev_raidz_math_avx512f.c | 2 +-
+ module/zfs/vdev_raidz_math_sse2.c | 2 +-
+ module/zfs/vdev_raidz_math_ssse3.c | 2 +-
+ 116 files changed, 699 insertions(+), 469 deletions(-)
+ create mode 100644 config/always-system.m4
+ delete mode 100644 include/linux/Makefile.am
+ create mode 100644 include/os/Makefile.am
+ create mode 100644 include/os/linux/Makefile.am
+ create mode 100644 include/os/linux/kernel/Makefile.am
+ create mode 100644 include/os/linux/kernel/linux/Makefile.am
+ rename include/{ => os/linux/kernel}/linux/blkdev_compat.h (100%)
+ rename include/{ => os/linux/kernel}/linux/compiler_compat.h (100%)
+ rename include/{ => os/linux/kernel}/linux/dcache_compat.h (100%)
+ rename include/{ => os/linux/kernel}/linux/kmap_compat.h (100%)
+ rename include/{ => os/linux/kernel}/linux/mod_compat.h (100%)
+ rename include/{ => os/linux/kernel}/linux/page_compat.h (100%)
+ rename include/{ => os/linux/kernel}/linux/simd.h (92%)
+ rename include/{ => os/linux/kernel}/linux/simd_aarch64.h (79%)
+ rename include/{ => os/linux/kernel}/linux/simd_x86.h (62%)
+ rename include/{ => os/linux/kernel}/linux/utsname_compat.h (100%)
+ rename include/{ => os/linux/kernel}/linux/vfs_compat.h (100%)
+ rename include/{ => os/linux/kernel}/linux/xattr_compat.h (100%)
+ rename include/{ => os/linux}/spl/Makefile.am (100%)
+ rename include/{ => os/linux}/spl/rpc/Makefile.am (72%)
+ rename include/{ => os/linux}/spl/rpc/xdr.h (100%)
+ create mode 100644 include/os/linux/spl/sys/Makefile.am
+ rename include/{ => os/linux}/spl/sys/acl.h (100%)
+ rename include/{ => os/linux}/spl/sys/atomic.h (100%)
+ rename include/{ => os/linux}/spl/sys/byteorder.h (100%)
+ rename include/{ => os/linux}/spl/sys/callb.h (100%)
+ rename include/{ => os/linux}/spl/sys/callo.h (100%)
+ rename include/{ => os/linux}/spl/sys/cmn_err.h (100%)
+ rename include/{ => os/linux}/spl/sys/condvar.h (100%)
+ rename include/{ => os/linux}/spl/sys/console.h (100%)
+ rename include/{ => os/linux}/spl/sys/cred.h (100%)
+ rename include/{ => os/linux}/spl/sys/ctype.h (100%)
+ rename include/{ => os/linux}/spl/sys/debug.h (100%)
+ rename include/{ => os/linux}/spl/sys/disp.h (100%)
+ rename include/{ => os/linux}/spl/sys/dkio.h (100%)
+ rename include/{ => os/linux}/spl/sys/errno.h (100%)
+ rename include/{ => os/linux}/spl/sys/fcntl.h (100%)
+ rename include/{ => os/linux}/spl/sys/file.h (100%)
+ rename include/{ => os/linux}/spl/sys/inttypes.h (100%)
+ rename include/{ => os/linux}/spl/sys/isa_defs.h (100%)
+ rename include/{ => os/linux}/spl/sys/kmem.h (100%)
+ rename include/{ => os/linux}/spl/sys/kmem_cache.h (100%)
+ rename include/{ => os/linux}/spl/sys/kobj.h (100%)
+ rename include/{ => os/linux}/spl/sys/kstat.h (100%)
+ rename include/{ => os/linux}/spl/sys/list.h (100%)
+ rename include/{ => os/linux}/spl/sys/mode.h (100%)
+ rename include/{ => os/linux}/spl/sys/mutex.h (100%)
+ rename include/{ => os/linux}/spl/sys/param.h (100%)
+ rename include/{ => os/linux}/spl/sys/proc.h (100%)
+ rename include/{ => os/linux}/spl/sys/processor.h (100%)
+ rename include/{ => os/linux}/spl/sys/procfs_list.h (100%)
+ rename include/{ => os/linux}/spl/sys/random.h (100%)
+ rename include/{ => os/linux}/spl/sys/rwlock.h (100%)
+ rename include/{ => os/linux}/spl/sys/shrinker.h (100%)
+ rename include/{ => os/linux}/spl/sys/sid.h (100%)
+ rename include/{ => os/linux}/spl/sys/signal.h (100%)
+ create mode 100644 include/os/linux/spl/sys/simd.h
+ rename include/{ => os/linux}/spl/sys/stat.h (100%)
+ rename include/{ => os/linux}/spl/sys/strings.h (100%)
+ rename include/{ => os/linux}/spl/sys/sunddi.h (100%)
+ rename include/{ => os/linux}/spl/sys/sysmacros.h (100%)
+ rename include/{ => os/linux}/spl/sys/systeminfo.h (100%)
+ rename include/{ => os/linux}/spl/sys/taskq.h (100%)
+ rename include/{ => os/linux}/spl/sys/thread.h (100%)
+ rename include/{ => os/linux}/spl/sys/time.h (100%)
+ rename include/{ => os/linux}/spl/sys/timer.h (100%)
+ rename include/{ => os/linux}/spl/sys/tsd.h (100%)
+ rename include/{ => os/linux}/spl/sys/types.h (100%)
+ rename include/{ => os/linux}/spl/sys/types32.h (100%)
+ rename include/{ => os/linux}/spl/sys/uio.h (100%)
+ rename include/{ => os/linux}/spl/sys/user.h (100%)
+ rename include/{ => os/linux}/spl/sys/vfs.h (100%)
+ rename include/{ => os/linux}/spl/sys/vmem.h (100%)
+ rename include/{ => os/linux}/spl/sys/vmsystm.h (100%)
+ rename include/{ => os/linux}/spl/sys/vnode.h (100%)
+ rename include/{ => os/linux}/spl/sys/wait.h (100%)
+ rename include/{ => os/linux}/spl/sys/zmod.h (100%)
+ rename include/{ => os/linux}/spl/sys/zone.h (100%)
+ create mode 100644 include/os/linux/zfs/Makefile.am
+ create mode 100644 include/os/linux/zfs/sys/Makefile.am
+ rename include/{ => os/linux/zfs}/sys/policy.h (100%)
+ rename include/{ => os/linux/zfs}/sys/zfs_ctldir.h (100%)
+ rename include/{ => os/linux/zfs}/sys/zfs_dir.h (100%)
+ rename include/{ => os/linux/zfs}/sys/zfs_vfsops.h (100%)
+ rename include/{ => os/linux/zfs}/sys/zfs_vnops.h (100%)
+ rename include/{ => os/linux/zfs}/sys/zpl.h (100%)
+ delete mode 100644 include/spl/sys/Makefile.am
+ create mode 100644 lib/libspl/include/sys/simd.h
+
+diff --git a/config/always-system.m4 b/config/always-system.m4
+new file mode 100644
+index 000000000..3225a52af
+--- /dev/null
++++ b/config/always-system.m4
+@@ -0,0 +1,26 @@
++dnl #
++dnl # Set the target system
++dnl #
++AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_SYSTEM], [
++ AC_MSG_CHECKING([for system type ($host_os)])
++ case $host_os in
++ *linux*)
++ AC_DEFINE([SYSTEM_LINUX], [1],
++ [True if ZFS is to be compiled for a Linux system])
++ ac_system="Linux"
++ ;;
++ *freebsd*)
++ AC_DEFINE([SYSTEM_FREEBSD], [1],
++ [True if ZFS is to be compiled for a FreeBSD system])
++ ac_system="FreeBSD"
++ ;;
++ *)
++ ac_system="unknown"
++ ;;
++ esac
++ AC_MSG_RESULT([$ac_system])
++ AC_SUBST([ac_system])
++
++ AM_CONDITIONAL([BUILD_LINUX], [test "x$ac_system" = "xLinux"])
++ AM_CONDITIONAL([BUILD_FREEBSD], [test "x$ac_system" = "xFreeBSD"])
++])
+diff --git a/config/zfs-build.m4 b/config/zfs-build.m4
+index d2c355425..f4cb97689 100644
+--- a/config/zfs-build.m4
++++ b/config/zfs-build.m4
+@@ -160,6 +160,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
+ ZFS_AC_CONFIG_ALWAYS_CC_NO_OMIT_FRAME_POINTER
+ ZFS_AC_CONFIG_ALWAYS_CC_ASAN
+ ZFS_AC_CONFIG_ALWAYS_TOOLCHAIN_SIMD
++ ZFS_AC_CONFIG_ALWAYS_SYSTEM
+ ZFS_AC_CONFIG_ALWAYS_ARCH
+ ZFS_AC_CONFIG_ALWAYS_PYTHON
+ ZFS_AC_CONFIG_ALWAYS_PYZFS
+diff --git a/configure.ac b/configure.ac
+index a3ac134ff..4b51118ab 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -145,10 +145,15 @@ AC_CONFIG_FILES([
+ module/icp/Makefile
+ module/spl/Makefile
+ include/Makefile
+- include/linux/Makefile
+- include/spl/Makefile
+- include/spl/rpc/Makefile
+- include/spl/sys/Makefile
++ include/os/Makefile
++ include/os/linux/Makefile
++ include/os/linux/kernel/Makefile
++ include/os/linux/kernel/linux/Makefile
++ include/os/linux/spl/Makefile
++ include/os/linux/spl/rpc/Makefile
++ include/os/linux/spl/sys/Makefile
++ include/os/linux/zfs/Makefile
++ include/os/linux/zfs/sys/Makefile
+ include/sys/Makefile
+ include/sys/fs/Makefile
+ include/sys/fm/Makefile
+diff --git a/copy-builtin b/copy-builtin
+index 1dcfcb961..adb3bd544 100755
+--- a/copy-builtin
++++ b/copy-builtin
+@@ -62,7 +62,9 @@ EOF
+ {
+ cat <<-"EOF"
+ ZFS_MODULE_CFLAGS = -I$(srctree)/include/zfs
+- ZFS_MODULE_CFLAGS += -I$(srctree)/include/zfs/spl
++ ZFS_MODULE_CFLAGS += -I$(srctree)/include/zfs/os/linux/spl
++ ZFS_MODULE_CFLAGS += -I$(srctree)/include/zfs/os/linux/zfs
++ ZFS_MODULE_CFLAGS += -I$(srctree)/include/zfs/os/linux/kernel
+ ZFS_MODULE_CFLAGS += -include $(srctree)/include/zfs/zfs_config.h
+ ZFS_MODULE_CFLAGS += -std=gnu99 -Wno-declaration-after-statement
+ ZFS_MODULE_CPPFLAGS = -D_KERNEL
+diff --git a/include/.gitignore b/include/.gitignore
+index e6eb2116f..416f36b9e 100644
+--- a/include/.gitignore
++++ b/include/.gitignore
+@@ -1 +1,2 @@
+ /zfs_gitrev.h
++/spl
+diff --git a/include/Makefile.am b/include/Makefile.am
+index bac47d98d..5b37dc765 100644
+--- a/include/Makefile.am
++++ b/include/Makefile.am
+@@ -1,4 +1,4 @@
+-SUBDIRS = linux spl sys
++SUBDIRS = sys os
+
+ COMMON_H = \
+ $(top_srcdir)/include/zfeature_common.h \
+diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am
+deleted file mode 100644
+index 2455759e8..000000000
+--- a/include/linux/Makefile.am
++++ /dev/null
+@@ -1,29 +0,0 @@
+-COMMON_H =
+-
+-KERNEL_H = \
+- $(top_srcdir)/include/linux/dcache_compat.h \
+- $(top_srcdir)/include/linux/xattr_compat.h \
+- $(top_srcdir)/include/linux/vfs_compat.h \
+- $(top_srcdir)/include/linux/blkdev_compat.h \
+- $(top_srcdir)/include/linux/utsname_compat.h \
+- $(top_srcdir)/include/linux/kmap_compat.h \
+- $(top_srcdir)/include/linux/simd.h \
+- $(top_srcdir)/include/linux/simd_x86.h \
+- $(top_srcdir)/include/linux/simd_aarch64.h \
+- $(top_srcdir)/include/linux/mod_compat.h \
+- $(top_srcdir)/include/linux/page_compat.h \
+- $(top_srcdir)/include/linux/compiler_compat.h
+-
+-USER_H =
+-
+-EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
+-
+-if CONFIG_USER
+-libzfsdir = $(includedir)/libzfs/linux
+-libzfs_HEADERS = $(COMMON_H) $(USER_H)
+-endif
+-
+-if CONFIG_KERNEL
+-kerneldir = @prefix@/src/zfs-$(VERSION)/include/linux
+-kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
+-endif
+diff --git a/include/os/Makefile.am b/include/os/Makefile.am
+new file mode 100644
+index 000000000..09c0beec4
+--- /dev/null
++++ b/include/os/Makefile.am
+@@ -0,0 +1,3 @@
++if BUILD_LINUX
++SUBDIRS = linux
++endif
+diff --git a/include/os/linux/Makefile.am b/include/os/linux/Makefile.am
+new file mode 100644
+index 000000000..605a1fcb7
+--- /dev/null
++++ b/include/os/linux/Makefile.am
+@@ -0,0 +1 @@
++SUBDIRS = kernel spl zfs
+diff --git a/include/os/linux/kernel/Makefile.am b/include/os/linux/kernel/Makefile.am
+new file mode 100644
+index 000000000..08b2f5fc5
+--- /dev/null
++++ b/include/os/linux/kernel/Makefile.am
+@@ -0,0 +1 @@
++SUBDIRS = linux
+diff --git a/include/os/linux/kernel/linux/Makefile.am b/include/os/linux/kernel/linux/Makefile.am
+new file mode 100644
+index 000000000..06ce7c7aa
+--- /dev/null
++++ b/include/os/linux/kernel/linux/Makefile.am
+@@ -0,0 +1,29 @@
++COMMON_H =
++
++KERNEL_H = \
++ $(top_srcdir)/include/os/linux/kernel/linux/dcache_compat.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/xattr_compat.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/vfs_compat.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/blkdev_compat.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/utsname_compat.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/kmap_compat.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/simd.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/simd_x86.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/simd_aarch64.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/mod_compat.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/page_compat.h \
++ $(top_srcdir)/include/os/linux/kernel/linux/compiler_compat.h
++
++USER_H =
++
++EXTRA_DIST = $(COMMON_H) $(KERNEL_H) $(USER_H)
++
++if CONFIG_USER
++libzfsdir = $(includedir)/libzfs/linux
++libzfs_HEADERS = $(COMMON_H) $(USER_H)
++endif
++
++if CONFIG_KERNEL
++kerneldir = @prefix@/src/zfs-$(VERSION)/include/linux
++kernel_HEADERS = $(COMMON_H) $(KERNEL_H)
++endif
+diff --git a/include/linux/blkdev_compat.h b/include/os/linux/kernel/linux/blkdev_compat.h
+similarity index 100%
+rename from include/linux/blkdev_compat.h
+rename to include/os/linux/kernel/linux/blkdev_compat.h
+diff --git a/include/linux/compiler_compat.h b/include/os/linux/kernel/linux/compiler_compat.h
+similarity index 100%
+rename from include/linux/compiler_compat.h
+rename to include/os/linux/kernel/linux/compiler_compat.h
+diff --git a/include/linux/dcache_compat.h b/include/os/linux/kernel/linux/dcache_compat.h
+similarity index 100%
+rename from include/linux/dcache_compat.h
+rename to include/os/linux/kernel/linux/dcache_compat.h
+diff --git a/include/linux/kmap_compat.h b/include/os/linux/kernel/linux/kmap_compat.h
+similarity index 100%
+rename from include/linux/kmap_compat.h
+rename to include/os/linux/kernel/linux/kmap_compat.h
+diff --git a/include/linux/mod_compat.h b/include/os/linux/kernel/linux/mod_compat.h
+similarity index 100%
+rename from include/linux/mod_compat.h
+rename to include/os/linux/kernel/linux/mod_compat.h
+diff --git a/include/linux/page_compat.h b/include/os/linux/kernel/linux/page_compat.h
+similarity index 100%
+rename from include/linux/page_compat.h
+rename to include/os/linux/kernel/linux/page_compat.h
+diff --git a/include/linux/simd.h b/include/os/linux/kernel/linux/simd.h
+similarity index 92%
+rename from include/linux/simd.h
+rename to include/os/linux/kernel/linux/simd.h
+index d2b60996a..1f6574a90 100644
+--- a/include/linux/simd.h
++++ b/include/os/linux/kernel/linux/simd.h
+@@ -22,8 +22,8 @@
+ * Copyright (C) 2019 Lawrence Livermore National Security, LLC.
+ */
+
+-#ifndef _SIMD_H
+-#define _SIMD_H
++#ifndef _LINUX_SIMD_H
++#define _LINUX_SIMD_H
+
+ #if defined(__x86)
+ #include <linux/simd_x86.h>
+@@ -32,10 +32,10 @@
+ #include <linux/simd_aarch64.h>
+ #else
+
+-#define kfpu_allowed() 1
++#define kfpu_allowed() 0
+ #define kfpu_initialize(tsk) do {} while (0)
+ #define kfpu_begin() do {} while (0)
+ #define kfpu_end() do {} while (0)
+
+ #endif
+-#endif /* _SIMD_H */
++#endif /* _LINUX_SIMD_H */
+diff --git a/include/linux/simd_aarch64.h b/include/os/linux/kernel/linux/simd_aarch64.h
+similarity index 79%
+rename from include/linux/simd_aarch64.h
+rename to include/os/linux/kernel/linux/simd_aarch64.h
+index b45d31c48..ac530d920 100644
+--- a/include/linux/simd_aarch64.h
++++ b/include/os/linux/kernel/linux/simd_aarch64.h
+@@ -32,31 +32,21 @@
+ * kfpu_end()
+ */
+
+-#ifndef _SIMD_AARCH64_H
+-#define _SIMD_AARCH64_H
++#ifndef _LINUX_SIMD_AARCH64_H
++#define _LINUX_SIMD_AARCH64_H
+
+ #include <sys/isa_defs.h>
+
+ #if defined(__aarch64__)
+
+ #include <sys/types.h>
+-
+-#if defined(_KERNEL)
+ #include <asm/neon.h>
++
+ #define kfpu_allowed() 1
+ #define kfpu_initialize(tsk) do {} while (0)
+ #define kfpu_begin() kernel_neon_begin()
+ #define kfpu_end() kernel_neon_end()
+-#else
+-/*
+- * fpu dummy methods for userspace
+- */
+-#define kfpu_allowed() 1
+-#define kfpu_initialize(tsk) do {} while (0)
+-#define kfpu_begin() do {} while (0)
+-#define kfpu_end() do {} while (0)
+-#endif /* defined(_KERNEL) */
+
+ #endif /* __aarch64__ */
+
+-#endif /* _SIMD_AARCH64_H */
++#endif /* _LINUX_SIMD_AARCH64_H */
+diff --git a/include/linux/simd_x86.h b/include/os/linux/kernel/linux/simd_x86.h
+similarity index 62%
+rename from include/linux/simd_x86.h
+rename to include/os/linux/kernel/linux/simd_x86.h
+index b32bccc41..486e31845 100644
+--- a/include/linux/simd_x86.h
++++ b/include/os/linux/kernel/linux/simd_x86.h
+@@ -66,23 +66,14 @@
+ * also add zfs_avx512vl_available() to feature check.
+ */
+
+-#ifndef _SIMD_X86_H
+-#define _SIMD_X86_H
+-
+-#include <sys/isa_defs.h>
++#ifndef _LINUX_SIMD_X86_H
++#define _LINUX_SIMD_X86_H
+
+ /* only for __x86 */
+ #if defined(__x86)
+
+ #include <sys/types.h>
+-
+-#if defined(_KERNEL)
+ #include <asm/cpufeature.h>
+-#else
+-#include <cpuid.h>
+-#endif
+-
+-#if defined(_KERNEL)
+
+ /*
+ * Disable the WARN_ON_FPU() macro to prevent additional dependencies
+@@ -292,185 +283,9 @@ kfpu_end(void)
+ #endif /* defined(HAVE_KERNEL_FPU_INTERNAL) */
+ #endif /* defined(KERNEL_EXPORTS_X86_FPU) */
+
+-#else /* defined(_KERNEL) */
+ /*
+- * FPU dummy methods for user space.
++ * Linux kernel provides an interface for CPU feature testing.
+ */
+-#define kfpu_allowed() 1
+-#define kfpu_initialize(tsk) do {} while (0)
+-#define kfpu_begin() do {} while (0)
+-#define kfpu_end() do {} while (0)
+-#endif /* defined(_KERNEL) */
+-
+-/*
+- * CPUID feature tests for user-space. Linux kernel provides an interface for
+- * CPU feature testing.
+- */
+-#if !defined(_KERNEL)
+-
+-/*
+- * x86 registers used implicitly by CPUID
+- */
+-typedef enum cpuid_regs {
+- EAX = 0,
+- EBX,
+- ECX,
+- EDX,
+- CPUID_REG_CNT = 4
+-} cpuid_regs_t;
+-
+-/*
+- * List of instruction sets identified by CPUID
+- */
+-typedef enum cpuid_inst_sets {
+- SSE = 0,
+- SSE2,
+- SSE3,
+- SSSE3,
+- SSE4_1,
+- SSE4_2,
+- OSXSAVE,
+- AVX,
+- AVX2,
+- BMI1,
+- BMI2,
+- AVX512F,
+- AVX512CD,
+- AVX512DQ,
+- AVX512BW,
+- AVX512IFMA,
+- AVX512VBMI,
+- AVX512PF,
+- AVX512ER,
+- AVX512VL,
+- AES,
+- PCLMULQDQ
+-} cpuid_inst_sets_t;
+-
+-/*
+- * Instruction set descriptor.
+- */
+-typedef struct cpuid_feature_desc {
+- uint32_t leaf; /* CPUID leaf */
+- uint32_t subleaf; /* CPUID sub-leaf */
+- uint32_t flag; /* bit mask of the feature */
+- cpuid_regs_t reg; /* which CPUID return register to test */
+-} cpuid_feature_desc_t;
+-
+-#define _AVX512F_BIT (1U << 16)
+-#define _AVX512CD_BIT (_AVX512F_BIT | (1U << 28))
+-#define _AVX512DQ_BIT (_AVX512F_BIT | (1U << 17))
+-#define _AVX512BW_BIT (_AVX512F_BIT | (1U << 30))
+-#define _AVX512IFMA_BIT (_AVX512F_BIT | (1U << 21))
+-#define _AVX512VBMI_BIT (1U << 1) /* AVX512F_BIT is on another leaf */
+-#define _AVX512PF_BIT (_AVX512F_BIT | (1U << 26))
+-#define _AVX512ER_BIT (_AVX512F_BIT | (1U << 27))
+-#define _AVX512VL_BIT (1U << 31) /* if used also check other levels */
+-#define _AES_BIT (1U << 25)
+-#define _PCLMULQDQ_BIT (1U << 1)
+-
+-/*
+- * Descriptions of supported instruction sets
+- */
+-static const cpuid_feature_desc_t cpuid_features[] = {
+- [SSE] = {1U, 0U, 1U << 25, EDX },
+- [SSE2] = {1U, 0U, 1U << 26, EDX },
+- [SSE3] = {1U, 0U, 1U << 0, ECX },
+- [SSSE3] = {1U, 0U, 1U << 9, ECX },
+- [SSE4_1] = {1U, 0U, 1U << 19, ECX },
+- [SSE4_2] = {1U, 0U, 1U << 20, ECX },
+- [OSXSAVE] = {1U, 0U, 1U << 27, ECX },
+- [AVX] = {1U, 0U, 1U << 28, ECX },
+- [AVX2] = {7U, 0U, 1U << 5, EBX },
+- [BMI1] = {7U, 0U, 1U << 3, EBX },
+- [BMI2] = {7U, 0U, 1U << 8, EBX },
+- [AVX512F] = {7U, 0U, _AVX512F_BIT, EBX },
+- [AVX512CD] = {7U, 0U, _AVX512CD_BIT, EBX },
+- [AVX512DQ] = {7U, 0U, _AVX512DQ_BIT, EBX },
+- [AVX512BW] = {7U, 0U, _AVX512BW_BIT, EBX },
+- [AVX512IFMA] = {7U, 0U, _AVX512IFMA_BIT, EBX },
+- [AVX512VBMI] = {7U, 0U, _AVX512VBMI_BIT, ECX },
+- [AVX512PF] = {7U, 0U, _AVX512PF_BIT, EBX },
+- [AVX512ER] = {7U, 0U, _AVX512ER_BIT, EBX },
+- [AVX512VL] = {7U, 0U, _AVX512ER_BIT, EBX },
+- [AES] = {1U, 0U, _AES_BIT, ECX },
+- [PCLMULQDQ] = {1U, 0U, _PCLMULQDQ_BIT, ECX },
+-};
+-
+-/*
+- * Check if OS supports AVX and AVX2 by checking XCR0
+- * Only call this function if CPUID indicates that AVX feature is
+- * supported by the CPU, otherwise it might be an illegal instruction.
+- */
+-static inline uint64_t
+-xgetbv(uint32_t index)
+-{
+- uint32_t eax, edx;
+- /* xgetbv - instruction byte code */
+- __asm__ __volatile__(".byte 0x0f; .byte 0x01; .byte 0xd0"
+- : "=a" (eax), "=d" (edx)
+- : "c" (index));
+-
+- return ((((uint64_t)edx)<<32) | (uint64_t)eax);
+-}
+-
+-/*
+- * Check if CPU supports a feature
+- */
+-static inline boolean_t
+-__cpuid_check_feature(const cpuid_feature_desc_t *desc)
+-{
+- uint32_t r[CPUID_REG_CNT];
+-
+- if (__get_cpuid_max(0, NULL) >= desc->leaf) {
+- /*
+- * __cpuid_count is needed to properly check
+- * for AVX2. It is a macro, so return parameters
+- * are passed by value.
+- */
+- __cpuid_count(desc->leaf, desc->subleaf,
+- r[EAX], r[EBX], r[ECX], r[EDX]);
+- return ((r[desc->reg] & desc->flag) == desc->flag);
+- }
+- return (B_FALSE);
+-}
+-
+-#define CPUID_FEATURE_CHECK(name, id) \
+-static inline boolean_t \
+-__cpuid_has_ ## name(void) \
+-{ \
+- return (__cpuid_check_feature(&cpuid_features[id])); \
+-}
+-
+-/*
+- * Define functions for user-space CPUID features testing
+- */
+-CPUID_FEATURE_CHECK(sse, SSE);
+-CPUID_FEATURE_CHECK(sse2, SSE2);
+-CPUID_FEATURE_CHECK(sse3, SSE3);
+-CPUID_FEATURE_CHECK(ssse3, SSSE3);
+-CPUID_FEATURE_CHECK(sse4_1, SSE4_1);
+-CPUID_FEATURE_CHECK(sse4_2, SSE4_2);
+-CPUID_FEATURE_CHECK(avx, AVX);
+-CPUID_FEATURE_CHECK(avx2, AVX2);
+-CPUID_FEATURE_CHECK(osxsave, OSXSAVE);
+-CPUID_FEATURE_CHECK(bmi1, BMI1);
+-CPUID_FEATURE_CHECK(bmi2, BMI2);
+-CPUID_FEATURE_CHECK(avx512f, AVX512F);
+-CPUID_FEATURE_CHECK(avx512cd, AVX512CD);
+-CPUID_FEATURE_CHECK(avx512dq, AVX512DQ);
+-CPUID_FEATURE_CHECK(avx512bw, AVX512BW);
+-CPUID_FEATURE_CHECK(avx512ifma, AVX512IFMA);
+-CPUID_FEATURE_CHECK(avx512vbmi, AVX512VBMI);
+-CPUID_FEATURE_CHECK(avx512pf, AVX512PF);
+-CPUID_FEATURE_CHECK(avx512er, AVX512ER);
+-CPUID_FEATURE_CHECK(avx512vl, AVX512VL);
+-CPUID_FEATURE_CHECK(aes, AES);
+-CPUID_FEATURE_CHECK(pclmulqdq, PCLMULQDQ);
+-
+-#endif /* !defined(_KERNEL) */
+-
+-
+ /*
+ * Detect register set support
+ */
+@@ -480,16 +295,11 @@ __simd_state_enabled(const uint64_t state)
+ boolean_t has_osxsave;
+ uint64_t xcr0;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_OSXSAVE)
+ has_osxsave = !!boot_cpu_has(X86_FEATURE_OSXSAVE);
+ #else
+ has_osxsave = B_FALSE;
+ #endif
+-#elif !defined(_KERNEL)
+- has_osxsave = __cpuid_has_osxsave();
+-#endif
+-
+ if (!has_osxsave)
+ return (B_FALSE);
+
+@@ -503,18 +313,13 @@ __simd_state_enabled(const uint64_t state)
+ #define __ymm_enabled() __simd_state_enabled(_XSTATE_SSE_AVX)
+ #define __zmm_enabled() __simd_state_enabled(_XSTATE_AVX512)
+
+-
+ /*
+ * Check if SSE instruction set is available
+ */
+ static inline boolean_t
+ zfs_sse_available(void)
+ {
+-#if defined(_KERNEL)
+ return (!!boot_cpu_has(X86_FEATURE_XMM));
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_sse());
+-#endif
+ }
+
+ /*
+@@ -523,11 +328,7 @@ zfs_sse_available(void)
+ static inline boolean_t
+ zfs_sse2_available(void)
+ {
+-#if defined(_KERNEL)
+ return (!!boot_cpu_has(X86_FEATURE_XMM2));
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_sse2());
+-#endif
+ }
+
+ /*
+@@ -536,11 +337,7 @@ zfs_sse2_available(void)
+ static inline boolean_t
+ zfs_sse3_available(void)
+ {
+-#if defined(_KERNEL)
+ return (!!boot_cpu_has(X86_FEATURE_XMM3));
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_sse3());
+-#endif
+ }
+
+ /*
+@@ -549,11 +346,7 @@ zfs_sse3_available(void)
+ static inline boolean_t
+ zfs_ssse3_available(void)
+ {
+-#if defined(_KERNEL)
+ return (!!boot_cpu_has(X86_FEATURE_SSSE3));
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_ssse3());
+-#endif
+ }
+
+ /*
+@@ -562,11 +355,7 @@ zfs_ssse3_available(void)
+ static inline boolean_t
+ zfs_sse4_1_available(void)
+ {
+-#if defined(_KERNEL)
+ return (!!boot_cpu_has(X86_FEATURE_XMM4_1));
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_sse4_1());
+-#endif
+ }
+
+ /*
+@@ -575,11 +364,7 @@ zfs_sse4_1_available(void)
+ static inline boolean_t
+ zfs_sse4_2_available(void)
+ {
+-#if defined(_KERNEL)
+ return (!!boot_cpu_has(X86_FEATURE_XMM4_2));
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_sse4_2());
+-#endif
+ }
+
+ /*
+@@ -588,14 +373,7 @@ zfs_sse4_2_available(void)
+ static inline boolean_t
+ zfs_avx_available(void)
+ {
+- boolean_t has_avx;
+-#if defined(_KERNEL)
+- has_avx = !!boot_cpu_has(X86_FEATURE_AVX);
+-#elif !defined(_KERNEL)
+- has_avx = __cpuid_has_avx();
+-#endif
+-
+- return (has_avx && __ymm_enabled());
++ return (boot_cpu_has(X86_FEATURE_AVX) && __ymm_enabled());
+ }
+
+ /*
+@@ -604,14 +382,7 @@ zfs_avx_available(void)
+ static inline boolean_t
+ zfs_avx2_available(void)
+ {
+- boolean_t has_avx2;
+-#if defined(_KERNEL)
+- has_avx2 = !!boot_cpu_has(X86_FEATURE_AVX2);
+-#elif !defined(_KERNEL)
+- has_avx2 = __cpuid_has_avx2();
+-#endif
+-
+- return (has_avx2 && __ymm_enabled());
++ return (boot_cpu_has(X86_FEATURE_AVX2) && __ymm_enabled());
+ }
+
+ /*
+@@ -620,15 +391,11 @@ zfs_avx2_available(void)
+ static inline boolean_t
+ zfs_bmi1_available(void)
+ {
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_BMI1)
+ return (!!boot_cpu_has(X86_FEATURE_BMI1));
+ #else
+ return (B_FALSE);
+ #endif
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_bmi1());
+-#endif
+ }
+
+ /*
+@@ -637,15 +404,11 @@ zfs_bmi1_available(void)
+ static inline boolean_t
+ zfs_bmi2_available(void)
+ {
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_BMI2)
+ return (!!boot_cpu_has(X86_FEATURE_BMI2));
+ #else
+ return (B_FALSE);
+ #endif
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_bmi2());
+-#endif
+ }
+
+ /*
+@@ -654,15 +417,11 @@ zfs_bmi2_available(void)
+ static inline boolean_t
+ zfs_aes_available(void)
+ {
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AES)
+ return (!!boot_cpu_has(X86_FEATURE_AES));
+ #else
+ return (B_FALSE);
+ #endif
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_aes());
+-#endif
+ }
+
+ /*
+@@ -671,15 +430,11 @@ zfs_aes_available(void)
+ static inline boolean_t
+ zfs_pclmulqdq_available(void)
+ {
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_PCLMULQDQ)
+ return (!!boot_cpu_has(X86_FEATURE_PCLMULQDQ));
+ #else
+ return (B_FALSE);
+ #endif
+-#elif !defined(_KERNEL)
+- return (__cpuid_has_pclmulqdq());
+-#endif
+ }
+
+ /*
+@@ -698,187 +453,141 @@ zfs_pclmulqdq_available(void)
+ * AVX512VBMI Vector Byte Manipulation Instructions
+ */
+
+-
+-/* Check if AVX512F instruction set is available */
++/*
++ * Check if AVX512F instruction set is available
++ */
+ static inline boolean_t
+ zfs_avx512f_available(void)
+ {
+ boolean_t has_avx512 = B_FALSE;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AVX512F)
+ has_avx512 = !!boot_cpu_has(X86_FEATURE_AVX512F);
+-#else
+- has_avx512 = B_FALSE;
+-#endif
+-#elif !defined(_KERNEL)
+- has_avx512 = __cpuid_has_avx512f();
+ #endif
+-
+ return (has_avx512 && __zmm_enabled());
+ }
+
+-/* Check if AVX512CD instruction set is available */
++/*
++ * Check if AVX512CD instruction set is available
++ */
+ static inline boolean_t
+ zfs_avx512cd_available(void)
+ {
+ boolean_t has_avx512 = B_FALSE;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AVX512CD)
+ has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
+ boot_cpu_has(X86_FEATURE_AVX512CD);
+-#else
+- has_avx512 = B_FALSE;
+ #endif
+-#elif !defined(_KERNEL)
+- has_avx512 = __cpuid_has_avx512cd();
+-#endif
+-
+ return (has_avx512 && __zmm_enabled());
+ }
+
+-/* Check if AVX512ER instruction set is available */
++/*
++ * Check if AVX512ER instruction set is available
++ */
+ static inline boolean_t
+ zfs_avx512er_available(void)
+ {
+ boolean_t has_avx512 = B_FALSE;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AVX512ER)
+ has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
+ boot_cpu_has(X86_FEATURE_AVX512ER);
+-#else
+- has_avx512 = B_FALSE;
+-#endif
+-#elif !defined(_KERNEL)
+- has_avx512 = __cpuid_has_avx512er();
+ #endif
+-
+ return (has_avx512 && __zmm_enabled());
+ }
+
+-/* Check if AVX512PF instruction set is available */
++/*
++ * Check if AVX512PF instruction set is available
++ */
+ static inline boolean_t
+ zfs_avx512pf_available(void)
+ {
+ boolean_t has_avx512 = B_FALSE;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AVX512PF)
+ has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
+ boot_cpu_has(X86_FEATURE_AVX512PF);
+-#else
+- has_avx512 = B_FALSE;
+-#endif
+-#elif !defined(_KERNEL)
+- has_avx512 = __cpuid_has_avx512pf();
+ #endif
+-
+ return (has_avx512 && __zmm_enabled());
+ }
+
+-/* Check if AVX512BW instruction set is available */
++/*
++ * Check if AVX512BW instruction set is available
++ */
+ static inline boolean_t
+ zfs_avx512bw_available(void)
+ {
+ boolean_t has_avx512 = B_FALSE;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AVX512BW)
+ has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
+ boot_cpu_has(X86_FEATURE_AVX512BW);
+-#else
+- has_avx512 = B_FALSE;
+-#endif
+-#elif !defined(_KERNEL)
+- has_avx512 = __cpuid_has_avx512bw();
+ #endif
+
+ return (has_avx512 && __zmm_enabled());
+ }
+
+-/* Check if AVX512DQ instruction set is available */
++/*
++ * Check if AVX512DQ instruction set is available
++ */
+ static inline boolean_t
+ zfs_avx512dq_available(void)
+ {
+ boolean_t has_avx512 = B_FALSE;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AVX512DQ)
+ has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
+ boot_cpu_has(X86_FEATURE_AVX512DQ);
+-#else
+- has_avx512 = B_FALSE;
+-#endif
+-#elif !defined(_KERNEL)
+- has_avx512 = __cpuid_has_avx512dq();
+ #endif
+-
+ return (has_avx512 && __zmm_enabled());
+ }
+
+-/* Check if AVX512VL instruction set is available */
++/*
++ * Check if AVX512VL instruction set is available
++ */
+ static inline boolean_t
+ zfs_avx512vl_available(void)
+ {
+ boolean_t has_avx512 = B_FALSE;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AVX512VL)
+ has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
+ boot_cpu_has(X86_FEATURE_AVX512VL);
+-#else
+- has_avx512 = B_FALSE;
+-#endif
+-#elif !defined(_KERNEL)
+- has_avx512 = __cpuid_has_avx512vl();
+ #endif
+-
+ return (has_avx512 && __zmm_enabled());
+ }
+
+-/* Check if AVX512IFMA instruction set is available */
++/*
++ * Check if AVX512IFMA instruction set is available
++ */
+ static inline boolean_t
+ zfs_avx512ifma_available(void)
+ {
+ boolean_t has_avx512 = B_FALSE;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AVX512IFMA)
+ has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
+ boot_cpu_has(X86_FEATURE_AVX512IFMA);
+-#else
+- has_avx512 = B_FALSE;
+-#endif
+-#elif !defined(_KERNEL)
+- has_avx512 = __cpuid_has_avx512ifma();
+ #endif
+-
+ return (has_avx512 && __zmm_enabled());
+ }
+
+-/* Check if AVX512VBMI instruction set is available */
++/*
++ * Check if AVX512VBMI instruction set is available
++ */
+ static inline boolean_t
+ zfs_avx512vbmi_available(void)
+ {
+ boolean_t has_avx512 = B_FALSE;
+
+-#if defined(_KERNEL)
+ #if defined(X86_FEATURE_AVX512VBMI)
+ has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
+ boot_cpu_has(X86_FEATURE_AVX512VBMI);
+-#else
+- has_avx512 = B_FALSE;
+ #endif
+-#elif !defined(_KERNEL)
+- has_avx512 = __cpuid_has_avx512f() &&
+- __cpuid_has_avx512vbmi();
+-#endif
+-
+ return (has_avx512 && __zmm_enabled());
+ }
+
+ #endif /* defined(__x86) */
+
+-#endif /* _SIMD_X86_H */
++#endif /* _LINUX_SIMD_X86_H */
+diff --git a/include/linux/utsname_compat.h b/include/os/linux/kernel/linux/utsname_compat.h
+similarity index 100%
+rename from include/linux/utsname_compat.h
+rename to include/os/linux/kernel/linux/utsname_compat.h
+diff --git a/include/linux/vfs_compat.h b/include/os/linux/kernel/linux/vfs_compat.h
+similarity index 100%
+rename from include/linux/vfs_compat.h
+rename to include/os/linux/kernel/linux/vfs_compat.h
+diff --git a/include/linux/xattr_compat.h b/include/os/linux/kernel/linux/xattr_compat.h
+similarity index 100%
+rename from include/linux/xattr_compat.h
+rename to include/os/linux/kernel/linux/xattr_compat.h
+diff --git a/include/spl/Makefile.am b/include/os/linux/spl/Makefile.am
+similarity index 100%
+rename from include/spl/Makefile.am
+rename to include/os/linux/spl/Makefile.am
+diff --git a/include/spl/rpc/Makefile.am b/include/os/linux/spl/rpc/Makefile.am
+similarity index 72%
+rename from include/spl/rpc/Makefile.am
+rename to include/os/linux/spl/rpc/Makefile.am
+index 5110cc0f0..9477dd59d 100644
+--- a/include/spl/rpc/Makefile.am
++++ b/include/os/linux/spl/rpc/Makefile.am
+@@ -1,5 +1,5 @@
+ KERNEL_H = \
+- $(top_srcdir)/include/spl/rpc/xdr.h
++ $(top_srcdir)/include/os/linux/spl/rpc/xdr.h
+
+ if CONFIG_KERNEL
+ kerneldir = @prefix@/src/zfs-$(VERSION)/include/spl/rpc
+diff --git a/include/spl/rpc/xdr.h b/include/os/linux/spl/rpc/xdr.h
+similarity index 100%
+rename from include/spl/rpc/xdr.h
+rename to include/os/linux/spl/rpc/xdr.h
+diff --git a/include/os/linux/spl/sys/Makefile.am b/include/os/linux/spl/sys/Makefile.am
+new file mode 100644
+index 000000000..de2f74d8c
+--- /dev/null
++++ b/include/os/linux/spl/sys/Makefile.am
+@@ -0,0 +1,62 @@
++KERNEL_H = \
++ $(top_srcdir)/include/os/linux/spl/sys/acl.h \
++ $(top_srcdir)/include/os/linux/spl/sys/atomic.h \
++ $(top_srcdir)/include/os/linux/spl/sys/byteorder.h \
++ $(top_srcdir)/include/os/linux/spl/sys/callb.h \
++ $(top_srcdir)/include/os/linux/spl/sys/callo.h \
++ $(top_srcdir)/include/os/linux/spl/sys/cmn_err.h \
++ $(top_srcdir)/include/os/linux/spl/sys/condvar.h \
++ $(top_srcdir)/include/os/linux/spl/sys/console.h \
++ $(top_srcdir)/include/os/linux/spl/sys/cred.h \
++ $(top_srcdir)/include/os/linux/spl/sys/ctype.h \
++ $(top_srcdir)/include/os/linux/spl/sys/debug.h \
++ $(top_srcdir)/include/os/linux/spl/sys/disp.h \
++ $(top_srcdir)/include/os/linux/spl/sys/dkio.h \
++ $(top_srcdir)/include/os/linux/spl/sys/errno.h \
++ $(top_srcdir)/include/os/linux/spl/sys/fcntl.h \
++ $(top_srcdir)/include/os/linux/spl/sys/file.h \
++ $(top_srcdir)/include/os/linux/spl/sys/inttypes.h \
++ $(top_srcdir)/include/os/linux/spl/sys/isa_defs.h \
++ $(top_srcdir)/include/os/linux/spl/sys/kmem_cache.h \
++ $(top_srcdir)/include/os/linux/spl/sys/kmem.h \
++ $(top_srcdir)/include/os/linux/spl/sys/kobj.h \
++ $(top_srcdir)/include/os/linux/spl/sys/kstat.h \
++ $(top_srcdir)/include/os/linux/spl/sys/list.h \
++ $(top_srcdir)/include/os/linux/spl/sys/mode.h \
++ $(top_srcdir)/include/os/linux/spl/sys/mutex.h \
++ $(top_srcdir)/include/os/linux/spl/sys/param.h \
++ $(top_srcdir)/include/os/linux/spl/sys/processor.h \
++ $(top_srcdir)/include/os/linux/spl/sys/proc.h \
++ $(top_srcdir)/include/os/linux/spl/sys/procfs_list.h \
++ $(top_srcdir)/include/os/linux/spl/sys/random.h \
++ $(top_srcdir)/include/os/linux/spl/sys/rwlock.h \
++ $(top_srcdir)/include/os/linux/spl/sys/shrinker.h \
++ $(top_srcdir)/include/os/linux/spl/sys/sid.h \
++ $(top_srcdir)/include/os/linux/spl/sys/signal.h \
++ $(top_srcdir)/include/os/linux/spl/sys/simd.h \
++ $(top_srcdir)/include/os/linux/spl/sys/stat.h \
++ $(top_srcdir)/include/os/linux/spl/sys/strings.h \
++ $(top_srcdir)/include/os/linux/spl/sys/sunddi.h \
++ $(top_srcdir)/include/os/linux/spl/sys/sysmacros.h \
++ $(top_srcdir)/include/os/linux/spl/sys/systeminfo.h \
++ $(top_srcdir)/include/os/linux/spl/sys/taskq.h \
++ $(top_srcdir)/include/os/linux/spl/sys/thread.h \
++ $(top_srcdir)/include/os/linux/spl/sys/time.h \
++ $(top_srcdir)/include/os/linux/spl/sys/timer.h \
++ $(top_srcdir)/include/os/linux/spl/sys/tsd.h \
++ $(top_srcdir)/include/os/linux/spl/sys/types32.h \
++ $(top_srcdir)/include/os/linux/spl/sys/types.h \
++ $(top_srcdir)/include/os/linux/spl/sys/uio.h \
++ $(top_srcdir)/include/os/linux/spl/sys/user.h \
++ $(top_srcdir)/include/os/linux/spl/sys/vfs.h \
++ $(top_srcdir)/include/os/linux/spl/sys/vmem.h \
++ $(top_srcdir)/include/os/linux/spl/sys/vmsystm.h \
++ $(top_srcdir)/include/os/linux/spl/sys/vnode.h \
++ $(top_srcdir)/include/os/linux/spl/sys/wait.h \
++ $(top_srcdir)/include/os/linux/spl/sys/zmod.h \
++ $(top_srcdir)/include/os/linux/spl/sys/zone.h
++
++if CONFIG_KERNEL
++kerneldir = @prefix@/src/zfs-$(VERSION)/include/spl/sys
++kernel_HEADERS = $(KERNEL_H)
++endif
+diff --git a/include/spl/sys/acl.h b/include/os/linux/spl/sys/acl.h
+similarity index 100%
+rename from include/spl/sys/acl.h
+rename to include/os/linux/spl/sys/acl.h
+diff --git a/include/spl/sys/atomic.h b/include/os/linux/spl/sys/atomic.h
+similarity index 100%
+rename from include/spl/sys/atomic.h
+rename to include/os/linux/spl/sys/atomic.h
+diff --git a/include/spl/sys/byteorder.h b/include/os/linux/spl/sys/byteorder.h
+similarity index 100%
+rename from include/spl/sys/byteorder.h
+rename to include/os/linux/spl/sys/byteorder.h
+diff --git a/include/spl/sys/callb.h b/include/os/linux/spl/sys/callb.h
+similarity index 100%
+rename from include/spl/sys/callb.h
+rename to include/os/linux/spl/sys/callb.h
+diff --git a/include/spl/sys/callo.h b/include/os/linux/spl/sys/callo.h
+similarity index 100%
+rename from include/spl/sys/callo.h
+rename to include/os/linux/spl/sys/callo.h
+diff --git a/include/spl/sys/cmn_err.h b/include/os/linux/spl/sys/cmn_err.h
+similarity index 100%
+rename from include/spl/sys/cmn_err.h
+rename to include/os/linux/spl/sys/cmn_err.h
+diff --git a/include/spl/sys/condvar.h b/include/os/linux/spl/sys/condvar.h
+similarity index 100%
+rename from include/spl/sys/condvar.h
+rename to include/os/linux/spl/sys/condvar.h
+diff --git a/include/spl/sys/console.h b/include/os/linux/spl/sys/console.h
+similarity index 100%
+rename from include/spl/sys/console.h
+rename to include/os/linux/spl/sys/console.h
+diff --git a/include/spl/sys/cred.h b/include/os/linux/spl/sys/cred.h
+similarity index 100%
+rename from include/spl/sys/cred.h
+rename to include/os/linux/spl/sys/cred.h
+diff --git a/include/spl/sys/ctype.h b/include/os/linux/spl/sys/ctype.h
+similarity index 100%
+rename from include/spl/sys/ctype.h
+rename to include/os/linux/spl/sys/ctype.h
+diff --git a/include/spl/sys/debug.h b/include/os/linux/spl/sys/debug.h
+similarity index 100%
+rename from include/spl/sys/debug.h
+rename to include/os/linux/spl/sys/debug.h
+diff --git a/include/spl/sys/disp.h b/include/os/linux/spl/sys/disp.h
+similarity index 100%
+rename from include/spl/sys/disp.h
+rename to include/os/linux/spl/sys/disp.h
+diff --git a/include/spl/sys/dkio.h b/include/os/linux/spl/sys/dkio.h
+similarity index 100%
+rename from include/spl/sys/dkio.h
+rename to include/os/linux/spl/sys/dkio.h
+diff --git a/include/spl/sys/errno.h b/include/os/linux/spl/sys/errno.h
+similarity index 100%
+rename from include/spl/sys/errno.h
+rename to include/os/linux/spl/sys/errno.h
+diff --git a/include/spl/sys/fcntl.h b/include/os/linux/spl/sys/fcntl.h
+similarity index 100%
+rename from include/spl/sys/fcntl.h
+rename to include/os/linux/spl/sys/fcntl.h
+diff --git a/include/spl/sys/file.h b/include/os/linux/spl/sys/file.h
+similarity index 100%
+rename from include/spl/sys/file.h
+rename to include/os/linux/spl/sys/file.h
+diff --git a/include/spl/sys/inttypes.h b/include/os/linux/spl/sys/inttypes.h
+similarity index 100%
+rename from include/spl/sys/inttypes.h
+rename to include/os/linux/spl/sys/inttypes.h
+diff --git a/include/spl/sys/isa_defs.h b/include/os/linux/spl/sys/isa_defs.h
+similarity index 100%
+rename from include/spl/sys/isa_defs.h
+rename to include/os/linux/spl/sys/isa_defs.h
+diff --git a/include/spl/sys/kmem.h b/include/os/linux/spl/sys/kmem.h
+similarity index 100%
+rename from include/spl/sys/kmem.h
+rename to include/os/linux/spl/sys/kmem.h
+diff --git a/include/spl/sys/kmem_cache.h b/include/os/linux/spl/sys/kmem_cache.h
+similarity index 100%
+rename from include/spl/sys/kmem_cache.h
+rename to include/os/linux/spl/sys/kmem_cache.h
+diff --git a/include/spl/sys/kobj.h b/include/os/linux/spl/sys/kobj.h
+similarity index 100%
+rename from include/spl/sys/kobj.h
+rename to include/os/linux/spl/sys/kobj.h
+diff --git a/include/spl/sys/kstat.h b/include/os/linux/spl/sys/kstat.h
+similarity index 100%
+rename from include/spl/sys/kstat.h
+rename to include/os/linux/spl/sys/kstat.h
+diff --git a/include/spl/sys/list.h b/include/os/linux/spl/sys/list.h
+similarity index 100%
+rename from include/spl/sys/list.h
+rename to include/os/linux/spl/sys/list.h
+diff --git a/include/spl/sys/mode.h b/include/os/linux/spl/sys/mode.h
+similarity index 100%
+rename from include/spl/sys/mode.h
+rename to include/os/linux/spl/sys/mode.h
+diff --git a/include/spl/sys/mutex.h b/include/os/linux/spl/sys/mutex.h
+similarity index 100%
+rename from include/spl/sys/mutex.h
+rename to include/os/linux/spl/sys/mutex.h
+diff --git a/include/spl/sys/param.h b/include/os/linux/spl/sys/param.h
+similarity index 100%
+rename from include/spl/sys/param.h
+rename to include/os/linux/spl/sys/param.h
+diff --git a/include/spl/sys/proc.h b/include/os/linux/spl/sys/proc.h
+similarity index 100%
+rename from include/spl/sys/proc.h
+rename to include/os/linux/spl/sys/proc.h
+diff --git a/include/spl/sys/processor.h b/include/os/linux/spl/sys/processor.h
+similarity index 100%
+rename from include/spl/sys/processor.h
+rename to include/os/linux/spl/sys/processor.h
+diff --git a/include/spl/sys/procfs_list.h b/include/os/linux/spl/sys/procfs_list.h
+similarity index 100%
+rename from include/spl/sys/procfs_list.h
+rename to include/os/linux/spl/sys/procfs_list.h
+diff --git a/include/spl/sys/random.h b/include/os/linux/spl/sys/random.h
+similarity index 100%
+rename from include/spl/sys/random.h
+rename to include/os/linux/spl/sys/random.h
+diff --git a/include/spl/sys/rwlock.h b/include/os/linux/spl/sys/rwlock.h
+similarity index 100%
+rename from include/spl/sys/rwlock.h
+rename to include/os/linux/spl/sys/rwlock.h
+diff --git a/include/spl/sys/shrinker.h b/include/os/linux/spl/sys/shrinker.h
+similarity index 100%
+rename from include/spl/sys/shrinker.h
+rename to include/os/linux/spl/sys/shrinker.h
+diff --git a/include/spl/sys/sid.h b/include/os/linux/spl/sys/sid.h
+similarity index 100%
+rename from include/spl/sys/sid.h
+rename to include/os/linux/spl/sys/sid.h
+diff --git a/include/spl/sys/signal.h b/include/os/linux/spl/sys/signal.h
+similarity index 100%
+rename from include/spl/sys/signal.h
+rename to include/os/linux/spl/sys/signal.h
+diff --git a/include/os/linux/spl/sys/simd.h b/include/os/linux/spl/sys/simd.h
+new file mode 100644
+index 000000000..f2048d9e1
+--- /dev/null
++++ b/include/os/linux/spl/sys/simd.h
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
++ * Copyright (C) 2007 The Regents of the University of California.
++ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
++ * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
++ * UCRL-CODE-235197
++ *
++ * This file is part of the SPL, Solaris Porting Layer.
++ * For details, see <http://zfsonlinux.org/>.
++ *
++ * The SPL is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * The SPL is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with the SPL. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#ifndef _SPL_SYS_SIMD_H
++#define _SPL_SYS_SIMD_H
++
++#include <sys/isa_defs.h>
++#include <linux/simd.h>
++
++#endif /* _SPL_SYS_SIMD_H */
+diff --git a/include/spl/sys/stat.h b/include/os/linux/spl/sys/stat.h
+similarity index 100%
+rename from include/spl/sys/stat.h
+rename to include/os/linux/spl/sys/stat.h
+diff --git a/include/spl/sys/strings.h b/include/os/linux/spl/sys/strings.h
+similarity index 100%
+rename from include/spl/sys/strings.h
+rename to include/os/linux/spl/sys/strings.h
+diff --git a/include/spl/sys/sunddi.h b/include/os/linux/spl/sys/sunddi.h
+similarity index 100%
+rename from include/spl/sys/sunddi.h
+rename to include/os/linux/spl/sys/sunddi.h
+diff --git a/include/spl/sys/sysmacros.h b/include/os/linux/spl/sys/sysmacros.h
+similarity index 100%
+rename from include/spl/sys/sysmacros.h
+rename to include/os/linux/spl/sys/sysmacros.h
+diff --git a/include/spl/sys/systeminfo.h b/include/os/linux/spl/sys/systeminfo.h
+similarity index 100%
+rename from include/spl/sys/systeminfo.h
+rename to include/os/linux/spl/sys/systeminfo.h
+diff --git a/include/spl/sys/taskq.h b/include/os/linux/spl/sys/taskq.h
+similarity index 100%
+rename from include/spl/sys/taskq.h
+rename to include/os/linux/spl/sys/taskq.h
+diff --git a/include/spl/sys/thread.h b/include/os/linux/spl/sys/thread.h
+similarity index 100%
+rename from include/spl/sys/thread.h
+rename to include/os/linux/spl/sys/thread.h
+diff --git a/include/spl/sys/time.h b/include/os/linux/spl/sys/time.h
+similarity index 100%
+rename from include/spl/sys/time.h
+rename to include/os/linux/spl/sys/time.h
+diff --git a/include/spl/sys/timer.h b/include/os/linux/spl/sys/timer.h
+similarity index 100%
+rename from include/spl/sys/timer.h
+rename to include/os/linux/spl/sys/timer.h
+diff --git a/include/spl/sys/tsd.h b/include/os/linux/spl/sys/tsd.h
+similarity index 100%
+rename from include/spl/sys/tsd.h
+rename to include/os/linux/spl/sys/tsd.h
+diff --git a/include/spl/sys/types.h b/include/os/linux/spl/sys/types.h
+similarity index 100%
+rename from include/spl/sys/types.h
+rename to include/os/linux/spl/sys/types.h
+diff --git a/include/spl/sys/types32.h b/include/os/linux/spl/sys/types32.h
+similarity index 100%
+rename from include/spl/sys/types32.h
+rename to include/os/linux/spl/sys/types32.h
+diff --git a/include/spl/sys/uio.h b/include/os/linux/spl/sys/uio.h
+similarity index 100%
+rename from include/spl/sys/uio.h
+rename to include/os/linux/spl/sys/uio.h
+diff --git a/include/spl/sys/user.h b/include/os/linux/spl/sys/user.h
+similarity index 100%
+rename from include/spl/sys/user.h
+rename to include/os/linux/spl/sys/user.h
+diff --git a/include/spl/sys/vfs.h b/include/os/linux/spl/sys/vfs.h
+similarity index 100%
+rename from include/spl/sys/vfs.h
+rename to include/os/linux/spl/sys/vfs.h
+diff --git a/include/spl/sys/vmem.h b/include/os/linux/spl/sys/vmem.h
+similarity index 100%
+rename from include/spl/sys/vmem.h
+rename to include/os/linux/spl/sys/vmem.h
+diff --git a/include/spl/sys/vmsystm.h b/include/os/linux/spl/sys/vmsystm.h
+similarity index 100%
+rename from include/spl/sys/vmsystm.h
+rename to include/os/linux/spl/sys/vmsystm.h
+diff --git a/include/spl/sys/vnode.h b/include/os/linux/spl/sys/vnode.h
+similarity index 100%
+rename from include/spl/sys/vnode.h
+rename to include/os/linux/spl/sys/vnode.h
+diff --git a/include/spl/sys/wait.h b/include/os/linux/spl/sys/wait.h
+similarity index 100%
+rename from include/spl/sys/wait.h
+rename to include/os/linux/spl/sys/wait.h
+diff --git a/include/spl/sys/zmod.h b/include/os/linux/spl/sys/zmod.h
+similarity index 100%
+rename from include/spl/sys/zmod.h
+rename to include/os/linux/spl/sys/zmod.h
+diff --git a/include/spl/sys/zone.h b/include/os/linux/spl/sys/zone.h
+similarity index 100%
+rename from include/spl/sys/zone.h
+rename to include/os/linux/spl/sys/zone.h
+diff --git a/include/os/linux/zfs/Makefile.am b/include/os/linux/zfs/Makefile.am
+new file mode 100644
+index 000000000..081839c48
+--- /dev/null
++++ b/include/os/linux/zfs/Makefile.am
+@@ -0,0 +1 @@
++SUBDIRS = sys
+diff --git a/include/os/linux/zfs/sys/Makefile.am b/include/os/linux/zfs/sys/Makefile.am
+new file mode 100644
+index 000000000..5aa87da37
+--- /dev/null
++++ b/include/os/linux/zfs/sys/Makefile.am
+@@ -0,0 +1,12 @@
++KERNEL_H = \
++ $(top_srcdir)/include/os/linux/zfs/sys/policy.h \
++ $(top_srcdir)/include/os/linux/zfs/sys/zfs_ctldir.h \
++ $(top_srcdir)/include/os/linux/zfs/sys/zfs_dir.h \
++ $(top_srcdir)/include/os/linux/zfs/sys/zfs_vfsops.h \
++ $(top_srcdir)/include/os/linux/zfs/sys/zfs_vnops.h \
++ $(top_srcdir)/include/os/linux/zfs/sys/zpl.h
++
++if CONFIG_KERNEL
++kerneldir = @prefix@/src/zfs-$(VERSION)/include/sys
++kernel_HEADERS = $(KERNEL_H)
++endif
+diff --git a/include/sys/policy.h b/include/os/linux/zfs/sys/policy.h
+similarity index 100%
+rename from include/sys/policy.h
+rename to include/os/linux/zfs/sys/policy.h
+diff --git a/include/sys/zfs_ctldir.h b/include/os/linux/zfs/sys/zfs_ctldir.h
+similarity index 100%
+rename from include/sys/zfs_ctldir.h
+rename to include/os/linux/zfs/sys/zfs_ctldir.h
+diff --git a/include/sys/zfs_dir.h b/include/os/linux/zfs/sys/zfs_dir.h
+similarity index 100%
+rename from include/sys/zfs_dir.h
+rename to include/os/linux/zfs/sys/zfs_dir.h
+diff --git a/include/sys/zfs_vfsops.h b/include/os/linux/zfs/sys/zfs_vfsops.h
+similarity index 100%
+rename from include/sys/zfs_vfsops.h
+rename to include/os/linux/zfs/sys/zfs_vfsops.h
+diff --git a/include/sys/zfs_vnops.h b/include/os/linux/zfs/sys/zfs_vnops.h
+similarity index 100%
+rename from include/sys/zfs_vnops.h
+rename to include/os/linux/zfs/sys/zfs_vnops.h
+diff --git a/include/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h
+similarity index 100%
+rename from include/sys/zpl.h
+rename to include/os/linux/zfs/sys/zpl.h
+diff --git a/include/spl/sys/Makefile.am b/include/spl/sys/Makefile.am
+deleted file mode 100644
+index 3b5b2755a..000000000
+--- a/include/spl/sys/Makefile.am
++++ /dev/null
+@@ -1,61 +0,0 @@
+-KERNEL_H = \
+- $(top_srcdir)/include/spl/sys/acl.h \
+- $(top_srcdir)/include/spl/sys/atomic.h \
+- $(top_srcdir)/include/spl/sys/byteorder.h \
+- $(top_srcdir)/include/spl/sys/callb.h \
+- $(top_srcdir)/include/spl/sys/callo.h \
+- $(top_srcdir)/include/spl/sys/cmn_err.h \
+- $(top_srcdir)/include/spl/sys/condvar.h \
+- $(top_srcdir)/include/spl/sys/console.h \
+- $(top_srcdir)/include/spl/sys/cred.h \
+- $(top_srcdir)/include/spl/sys/ctype.h \
+- $(top_srcdir)/include/spl/sys/debug.h \
+- $(top_srcdir)/include/spl/sys/disp.h \
+- $(top_srcdir)/include/spl/sys/dkio.h \
+- $(top_srcdir)/include/spl/sys/errno.h \
+- $(top_srcdir)/include/spl/sys/fcntl.h \
+- $(top_srcdir)/include/spl/sys/file.h \
+- $(top_srcdir)/include/spl/sys/inttypes.h \
+- $(top_srcdir)/include/spl/sys/isa_defs.h \
+- $(top_srcdir)/include/spl/sys/kmem_cache.h \
+- $(top_srcdir)/include/spl/sys/kmem.h \
+- $(top_srcdir)/include/spl/sys/kobj.h \
+- $(top_srcdir)/include/spl/sys/kstat.h \
+- $(top_srcdir)/include/spl/sys/list.h \
+- $(top_srcdir)/include/spl/sys/mode.h \
+- $(top_srcdir)/include/spl/sys/mutex.h \
+- $(top_srcdir)/include/spl/sys/param.h \
+- $(top_srcdir)/include/spl/sys/processor.h \
+- $(top_srcdir)/include/spl/sys/proc.h \
+- $(top_srcdir)/include/spl/sys/procfs_list.h \
+- $(top_srcdir)/include/spl/sys/random.h \
+- $(top_srcdir)/include/spl/sys/rwlock.h \
+- $(top_srcdir)/include/spl/sys/shrinker.h \
+- $(top_srcdir)/include/spl/sys/sid.h \
+- $(top_srcdir)/include/spl/sys/signal.h \
+- $(top_srcdir)/include/spl/sys/stat.h \
+- $(top_srcdir)/include/spl/sys/strings.h \
+- $(top_srcdir)/include/spl/sys/sunddi.h \
+- $(top_srcdir)/include/spl/sys/sysmacros.h \
+- $(top_srcdir)/include/spl/sys/systeminfo.h \
+- $(top_srcdir)/include/spl/sys/taskq.h \
+- $(top_srcdir)/include/spl/sys/thread.h \
+- $(top_srcdir)/include/spl/sys/time.h \
+- $(top_srcdir)/include/spl/sys/timer.h \
+- $(top_srcdir)/include/spl/sys/tsd.h \
+- $(top_srcdir)/include/spl/sys/types32.h \
+- $(top_srcdir)/include/spl/sys/types.h \
+- $(top_srcdir)/include/spl/sys/uio.h \
+- $(top_srcdir)/include/spl/sys/user.h \
+- $(top_srcdir)/include/spl/sys/vfs.h \
+- $(top_srcdir)/include/spl/sys/vmem.h \
+- $(top_srcdir)/include/spl/sys/vmsystm.h \
+- $(top_srcdir)/include/spl/sys/vnode.h \
+- $(top_srcdir)/include/spl/sys/wait.h \
+- $(top_srcdir)/include/spl/sys/zmod.h \
+- $(top_srcdir)/include/spl/sys/zone.h
+-
+-if CONFIG_KERNEL
+-kerneldir = @prefix@/src/zfs-$(VERSION)/include/spl/sys
+-kernel_HEADERS = $(KERNEL_H)
+-endif
+diff --git a/include/sys/Makefile.am b/include/sys/Makefile.am
+index 31ffdfb4a..25ede0929 100644
+--- a/include/sys/Makefile.am
++++ b/include/sys/Makefile.am
+@@ -51,7 +51,6 @@ COMMON_H = \
+ $(top_srcdir)/include/sys/nvpair.h \
+ $(top_srcdir)/include/sys/nvpair_impl.h \
+ $(top_srcdir)/include/sys/pathname.h \
+- $(top_srcdir)/include/sys/policy.h \
+ $(top_srcdir)/include/sys/range_tree.h \
+ $(top_srcdir)/include/sys/refcount.h \
+ $(top_srcdir)/include/sys/rrwlock.h \
+@@ -112,10 +111,8 @@ COMMON_H = \
+ $(top_srcdir)/include/sys/zfeature.h \
+ $(top_srcdir)/include/sys/zfs_acl.h \
+ $(top_srcdir)/include/sys/zfs_context.h \
+- $(top_srcdir)/include/sys/zfs_ctldir.h \
+ $(top_srcdir)/include/sys/zfs_debug.h \
+ $(top_srcdir)/include/sys/zfs_delay.h \
+- $(top_srcdir)/include/sys/zfs_dir.h \
+ $(top_srcdir)/include/sys/zfs_fuid.h \
+ $(top_srcdir)/include/sys/zfs_project.h \
+ $(top_srcdir)/include/sys/zfs_ratelimit.h \
+@@ -123,8 +120,6 @@ COMMON_H = \
+ $(top_srcdir)/include/sys/zfs_sa.h \
+ $(top_srcdir)/include/sys/zfs_stat.h \
+ $(top_srcdir)/include/sys/zfs_sysfs.h \
+- $(top_srcdir)/include/sys/zfs_vfsops.h \
+- $(top_srcdir)/include/sys/zfs_vnops.h \
+ $(top_srcdir)/include/sys/zfs_znode.h \
+ $(top_srcdir)/include/sys/zil.h \
+ $(top_srcdir)/include/sys/zil_impl.h \
+@@ -140,7 +135,6 @@ COMMON_H = \
+ KERNEL_H = \
+ $(top_srcdir)/include/sys/zfs_ioctl.h \
+ $(top_srcdir)/include/sys/zfs_onexit.h \
+- ${top_srcdir}/include/sys/zpl.h \
+ $(top_srcdir)/include/sys/zvol.h
+
+ USER_H =
+diff --git a/lib/libspl/include/sys/Makefile.am b/lib/libspl/include/sys/Makefile.am
+index e7af317e0..5156e2912 100644
+--- a/lib/libspl/include/sys/Makefile.am
++++ b/lib/libspl/include/sys/Makefile.am
+@@ -33,6 +33,7 @@ libspl_HEADERS = \
+ $(top_srcdir)/lib/libspl/include/sys/priv.h \
+ $(top_srcdir)/lib/libspl/include/sys/processor.h \
+ $(top_srcdir)/lib/libspl/include/sys/signal.h \
++ $(top_srcdir)/lib/libspl/include/sys/simd.h \
+ $(top_srcdir)/lib/libspl/include/sys/stack.h \
+ $(top_srcdir)/lib/libspl/include/sys/stat.h \
+ $(top_srcdir)/lib/libspl/include/sys/stdtypes.h \
+diff --git a/lib/libspl/include/sys/simd.h b/lib/libspl/include/sys/simd.h
+new file mode 100644
+index 000000000..6a2b3a022
+--- /dev/null
++++ b/lib/libspl/include/sys/simd.h
+@@ -0,0 +1,448 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License, Version 1.0 only
++ * (the "License"). You may not use this file except in compliance
++ * with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++/*
++ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
++
++#ifndef _LIBSPL_SYS_SIMD_H
++#define _LIBSPL_SYS_SIMD_H
++
++#include <sys/isa_defs.h>
++#include <sys/types.h>
++
++#if defined(__x86)
++#include <cpuid.h>
++
++#define kfpu_allowed() 1
++#define kfpu_initialize(tsk) do {} while (0)
++#define kfpu_begin() do {} while (0)
++#define kfpu_end() do {} while (0)
++
++/*
++ * CPUID feature tests for user-space.
++ *
++ * x86 registers used implicitly by CPUID
++ */
++typedef enum cpuid_regs {
++ EAX = 0,
++ EBX,
++ ECX,
++ EDX,
++ CPUID_REG_CNT = 4
++} cpuid_regs_t;
++
++/*
++ * List of instruction sets identified by CPUID
++ */
++typedef enum cpuid_inst_sets {
++ SSE = 0,
++ SSE2,
++ SSE3,
++ SSSE3,
++ SSE4_1,
++ SSE4_2,
++ OSXSAVE,
++ AVX,
++ AVX2,
++ BMI1,
++ BMI2,
++ AVX512F,
++ AVX512CD,
++ AVX512DQ,
++ AVX512BW,
++ AVX512IFMA,
++ AVX512VBMI,
++ AVX512PF,
++ AVX512ER,
++ AVX512VL,
++ AES,
++ PCLMULQDQ
++} cpuid_inst_sets_t;
++
++/*
++ * Instruction set descriptor.
++ */
++typedef struct cpuid_feature_desc {
++ uint32_t leaf; /* CPUID leaf */
++ uint32_t subleaf; /* CPUID sub-leaf */
++ uint32_t flag; /* bit mask of the feature */
++ cpuid_regs_t reg; /* which CPUID return register to test */
++} cpuid_feature_desc_t;
++
++#define _AVX512F_BIT (1U << 16)
++#define _AVX512CD_BIT (_AVX512F_BIT | (1U << 28))
++#define _AVX512DQ_BIT (_AVX512F_BIT | (1U << 17))
++#define _AVX512BW_BIT (_AVX512F_BIT | (1U << 30))
++#define _AVX512IFMA_BIT (_AVX512F_BIT | (1U << 21))
++#define _AVX512VBMI_BIT (1U << 1) /* AVX512F_BIT is on another leaf */
++#define _AVX512PF_BIT (_AVX512F_BIT | (1U << 26))
++#define _AVX512ER_BIT (_AVX512F_BIT | (1U << 27))
++#define _AVX512VL_BIT (1U << 31) /* if used also check other levels */
++#define _AES_BIT (1U << 25)
++#define _PCLMULQDQ_BIT (1U << 1)
++
++/*
++ * Descriptions of supported instruction sets
++ */
++static const cpuid_feature_desc_t cpuid_features[] = {
++ [SSE] = {1U, 0U, 1U << 25, EDX },
++ [SSE2] = {1U, 0U, 1U << 26, EDX },
++ [SSE3] = {1U, 0U, 1U << 0, ECX },
++ [SSSE3] = {1U, 0U, 1U << 9, ECX },
++ [SSE4_1] = {1U, 0U, 1U << 19, ECX },
++ [SSE4_2] = {1U, 0U, 1U << 20, ECX },
++ [OSXSAVE] = {1U, 0U, 1U << 27, ECX },
++ [AVX] = {1U, 0U, 1U << 28, ECX },
++ [AVX2] = {7U, 0U, 1U << 5, EBX },
++ [BMI1] = {7U, 0U, 1U << 3, EBX },
++ [BMI2] = {7U, 0U, 1U << 8, EBX },
++ [AVX512F] = {7U, 0U, _AVX512F_BIT, EBX },
++ [AVX512CD] = {7U, 0U, _AVX512CD_BIT, EBX },
++ [AVX512DQ] = {7U, 0U, _AVX512DQ_BIT, EBX },
++ [AVX512BW] = {7U, 0U, _AVX512BW_BIT, EBX },
++ [AVX512IFMA] = {7U, 0U, _AVX512IFMA_BIT, EBX },
++ [AVX512VBMI] = {7U, 0U, _AVX512VBMI_BIT, ECX },
++ [AVX512PF] = {7U, 0U, _AVX512PF_BIT, EBX },
++ [AVX512ER] = {7U, 0U, _AVX512ER_BIT, EBX },
++ [AVX512VL] = {7U, 0U, _AVX512ER_BIT, EBX },
++ [AES] = {1U, 0U, _AES_BIT, ECX },
++ [PCLMULQDQ] = {1U, 0U, _PCLMULQDQ_BIT, ECX },
++};
++
++/*
++ * Check if OS supports AVX and AVX2 by checking XCR0
++ * Only call this function if CPUID indicates that AVX feature is
++ * supported by the CPU, otherwise it might be an illegal instruction.
++ */
++static inline uint64_t
++xgetbv(uint32_t index)
++{
++ uint32_t eax, edx;
++ /* xgetbv - instruction byte code */
++ __asm__ __volatile__(".byte 0x0f; .byte 0x01; .byte 0xd0"
++ : "=a" (eax), "=d" (edx)
++ : "c" (index));
++
++ return ((((uint64_t)edx)<<32) | (uint64_t)eax);
++}
++
++/*
++ * Check if CPU supports a feature
++ */
++static inline boolean_t
++__cpuid_check_feature(const cpuid_feature_desc_t *desc)
++{
++ uint32_t r[CPUID_REG_CNT];
++
++ if (__get_cpuid_max(0, NULL) >= desc->leaf) {
++ /*
++ * __cpuid_count is needed to properly check
++ * for AVX2. It is a macro, so return parameters
++ * are passed by value.
++ */
++ __cpuid_count(desc->leaf, desc->subleaf,
++ r[EAX], r[EBX], r[ECX], r[EDX]);
++ return ((r[desc->reg] & desc->flag) == desc->flag);
++ }
++ return (B_FALSE);
++}
++
++#define CPUID_FEATURE_CHECK(name, id) \
++static inline boolean_t \
++__cpuid_has_ ## name(void) \
++{ \
++ return (__cpuid_check_feature(&cpuid_features[id])); \
++}
++
++/*
++ * Define functions for user-space CPUID features testing
++ */
++CPUID_FEATURE_CHECK(sse, SSE);
++CPUID_FEATURE_CHECK(sse2, SSE2);
++CPUID_FEATURE_CHECK(sse3, SSE3);
++CPUID_FEATURE_CHECK(ssse3, SSSE3);
++CPUID_FEATURE_CHECK(sse4_1, SSE4_1);
++CPUID_FEATURE_CHECK(sse4_2, SSE4_2);
++CPUID_FEATURE_CHECK(avx, AVX);
++CPUID_FEATURE_CHECK(avx2, AVX2);
++CPUID_FEATURE_CHECK(osxsave, OSXSAVE);
++CPUID_FEATURE_CHECK(bmi1, BMI1);
++CPUID_FEATURE_CHECK(bmi2, BMI2);
++CPUID_FEATURE_CHECK(avx512f, AVX512F);
++CPUID_FEATURE_CHECK(avx512cd, AVX512CD);
++CPUID_FEATURE_CHECK(avx512dq, AVX512DQ);
++CPUID_FEATURE_CHECK(avx512bw, AVX512BW);
++CPUID_FEATURE_CHECK(avx512ifma, AVX512IFMA);
++CPUID_FEATURE_CHECK(avx512vbmi, AVX512VBMI);
++CPUID_FEATURE_CHECK(avx512pf, AVX512PF);
++CPUID_FEATURE_CHECK(avx512er, AVX512ER);
++CPUID_FEATURE_CHECK(avx512vl, AVX512VL);
++CPUID_FEATURE_CHECK(aes, AES);
++CPUID_FEATURE_CHECK(pclmulqdq, PCLMULQDQ);
++
++/*
++ * Detect register set support
++ */
++static inline boolean_t
++__simd_state_enabled(const uint64_t state)
++{
++ boolean_t has_osxsave;
++ uint64_t xcr0;
++
++ has_osxsave = __cpuid_has_osxsave();
++ if (!has_osxsave)
++ return (B_FALSE);
++
++ xcr0 = xgetbv(0);
++ return ((xcr0 & state) == state);
++}
++
++#define _XSTATE_SSE_AVX (0x2 | 0x4)
++#define _XSTATE_AVX512 (0xE0 | _XSTATE_SSE_AVX)
++
++#define __ymm_enabled() __simd_state_enabled(_XSTATE_SSE_AVX)
++#define __zmm_enabled() __simd_state_enabled(_XSTATE_AVX512)
++
++/*
++ * Check if SSE instruction set is available
++ */
++static inline boolean_t
++zfs_sse_available(void)
++{
++ return (__cpuid_has_sse());
++}
++
++/*
++ * Check if SSE2 instruction set is available
++ */
++static inline boolean_t
++zfs_sse2_available(void)
++{
++ return (__cpuid_has_sse2());
++}
++
++/*
++ * Check if SSE3 instruction set is available
++ */
++static inline boolean_t
++zfs_sse3_available(void)
++{
++ return (__cpuid_has_sse3());
++}
++
++/*
++ * Check if SSSE3 instruction set is available
++ */
++static inline boolean_t
++zfs_ssse3_available(void)
++{
++ return (__cpuid_has_ssse3());
++}
++
++/*
++ * Check if SSE4.1 instruction set is available
++ */
++static inline boolean_t
++zfs_sse4_1_available(void)
++{
++ return (__cpuid_has_sse4_1());
++}
++
++/*
++ * Check if SSE4.2 instruction set is available
++ */
++static inline boolean_t
++zfs_sse4_2_available(void)
++{
++ return (__cpuid_has_sse4_2());
++}
++
++/*
++ * Check if AVX instruction set is available
++ */
++static inline boolean_t
++zfs_avx_available(void)
++{
++ return (__cpuid_has_avx() && __ymm_enabled());
++}
++
++/*
++ * Check if AVX2 instruction set is available
++ */
++static inline boolean_t
++zfs_avx2_available(void)
++{
++ return (__cpuid_has_avx2() && __ymm_enabled());
++}
++
++/*
++ * Check if BMI1 instruction set is available
++ */
++static inline boolean_t
++zfs_bmi1_available(void)
++{
++ return (__cpuid_has_bmi1());
++}
++
++/*
++ * Check if BMI2 instruction set is available
++ */
++static inline boolean_t
++zfs_bmi2_available(void)
++{
++ return (__cpuid_has_bmi2());
++}
++
++/*
++ * Check if AES instruction set is available
++ */
++static inline boolean_t
++zfs_aes_available(void)
++{
++ return (__cpuid_has_aes());
++}
++
++/*
++ * Check if PCLMULQDQ instruction set is available
++ */
++static inline boolean_t
++zfs_pclmulqdq_available(void)
++{
++ return (__cpuid_has_pclmulqdq());
++}
++
++/*
++ * AVX-512 family of instruction sets:
++ *
++ * AVX512F Foundation
++ * AVX512CD Conflict Detection Instructions
++ * AVX512ER Exponential and Reciprocal Instructions
++ * AVX512PF Prefetch Instructions
++ *
++ * AVX512BW Byte and Word Instructions
++ * AVX512DQ Double-word and Quadword Instructions
++ * AVX512VL Vector Length Extensions
++ *
++ * AVX512IFMA Integer Fused Multiply Add (Not supported by kernel 4.4)
++ * AVX512VBMI Vector Byte Manipulation Instructions
++ */
++
++/*
++ * Check if AVX512F instruction set is available
++ */
++static inline boolean_t
++zfs_avx512f_available(void)
++{
++ return (__cpuid_has_avx512f() && __zmm_enabled());
++}
++
++/*
++ * Check if AVX512CD instruction set is available
++ */
++static inline boolean_t
++zfs_avx512cd_available(void)
++{
++ return (__cpuid_has_avx512cd() && __zmm_enabled());
++}
++
++/*
++ * Check if AVX512ER instruction set is available
++ */
++static inline boolean_t
++zfs_avx512er_available(void)
++{
++ return (__cpuid_has_avx512er() && __zmm_enabled());
++}
++
++/*
++ * Check if AVX512PF instruction set is available
++ */
++static inline boolean_t
++zfs_avx512pf_available(void)
++{
++ return (__cpuid_has_avx512pf() && __zmm_enabled());
++}
++
++/*
++ * Check if AVX512BW instruction set is available
++ */
++static inline boolean_t
++zfs_avx512bw_available(void)
++{
++ return (__cpuid_has_avx512bw() && __zmm_enabled());
++}
++
++/*
++ * Check if AVX512DQ instruction set is available
++ */
++static inline boolean_t
++zfs_avx512dq_available(void)
++{
++ return (__cpuid_has_avx512dq() && __zmm_enabled());
++}
++
++/*
++ * Check if AVX512VL instruction set is available
++ */
++static inline boolean_t
++zfs_avx512vl_available(void)
++{
++ return (__cpuid_has_avx512vl() && __zmm_enabled());
++}
++
++/*
++ * Check if AVX512IFMA instruction set is available
++ */
++static inline boolean_t
++zfs_avx512ifma_available(void)
++{
++ return (__cpuid_has_avx512ifma() && __zmm_enabled());
++}
++
++/*
++ * Check if AVX512VBMI instruction set is available
++ */
++static inline boolean_t
++zfs_avx512vbmi_available(void)
++{
++ return (__cpuid_has_avx512f() && __cpuid_has_avx512vbmi() &&
++ __zmm_enabled());
++}
++
++#elif defined(__aarch64__)
++
++#define kfpu_allowed() 1
++#define kfpu_initialize(tsk) do {} while (0)
++#define kfpu_begin() do {} while (0)
++#define kfpu_end() do {} while (0)
++
++#else
++
++#define kfpu_allowed() 0
++#define kfpu_initialize(tsk) do {} while (0)
++#define kfpu_begin() do {} while (0)
++#define kfpu_end() do {} while (0)
++
++#endif
++
++#endif /* _LIBSPL_SYS_SIMD_H */
+diff --git a/module/Makefile.in b/module/Makefile.in
+index 7477dbe56..bf0eb101c 100644
+--- a/module/Makefile.in
++++ b/module/Makefile.in
+@@ -12,7 +12,9 @@ INSTALL_MOD_DIR ?= extra
+ ZFS_MODULE_CFLAGS += -std=gnu99 -Wno-declaration-after-statement
+ ZFS_MODULE_CFLAGS += @KERNEL_DEBUG_CFLAGS@
+ ZFS_MODULE_CFLAGS += -include @abs_top_builddir@/zfs_config.h
+-ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/include/spl
++ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/include/os/linux/kernel
++ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/include/os/linux/spl
++ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/include/os/linux/zfs
+ ZFS_MODULE_CFLAGS += -I@abs_top_srcdir@/include
+
+ ZFS_MODULE_CPPFLAGS += -D_KERNEL
+diff --git a/module/icp/algs/aes/aes_impl.c b/module/icp/algs/aes/aes_impl.c
+index 0f11f9999..b60b16cc0 100644
+--- a/module/icp/algs/aes/aes_impl.c
++++ b/module/icp/algs/aes/aes_impl.c
+@@ -25,9 +25,9 @@
+ #include <sys/zfs_context.h>
+ #include <sys/crypto/icp.h>
+ #include <sys/crypto/spi.h>
++#include <sys/simd.h>
+ #include <modes/modes.h>
+ #include <aes/aes_impl.h>
+-#include <linux/simd.h>
+
+ /*
+ * Initialize AES encryption and decryption key schedules.
+diff --git a/module/icp/algs/aes/aes_impl_aesni.c b/module/icp/algs/aes/aes_impl_aesni.c
+index 222c176aa..4b5eefd71 100644
+--- a/module/icp/algs/aes/aes_impl_aesni.c
++++ b/module/icp/algs/aes/aes_impl_aesni.c
+@@ -24,7 +24,8 @@
+
+ #if defined(__x86_64) && defined(HAVE_AES)
+
+-#include <linux/simd_x86.h>
++#include <sys/simd.h>
++#include <sys/types.h>
+
+ /* These functions are used to execute AES-NI instructions: */
+ extern int rijndael_key_setup_enc_intel(uint32_t rk[],
+diff --git a/module/icp/algs/aes/aes_impl_x86-64.c b/module/icp/algs/aes/aes_impl_x86-64.c
+index b4515fa22..0ee7ee99c 100644
+--- a/module/icp/algs/aes/aes_impl_x86-64.c
++++ b/module/icp/algs/aes/aes_impl_x86-64.c
+@@ -24,7 +24,7 @@
+
+ #if defined(__x86_64)
+
+-#include <linux/simd_x86.h>
++#include <sys/simd.h>
+
+ /* These functions are used to execute amd64 instructions for AMD or Intel: */
+ extern int rijndael_key_setup_enc_amd64(uint32_t rk[],
+diff --git a/module/icp/algs/modes/gcm.c b/module/icp/algs/modes/gcm.c
+index 423b70e2c..1fb8e256a 100644
+--- a/module/icp/algs/modes/gcm.c
++++ b/module/icp/algs/modes/gcm.c
+@@ -28,8 +28,8 @@
+ #include <sys/crypto/icp.h>
+ #include <sys/crypto/impl.h>
+ #include <sys/byteorder.h>
++#include <sys/simd.h>
+ #include <modes/gcm_impl.h>
+-#include <linux/simd.h>
+
+ #define GHASH(c, d, t, o) \
+ xor_block((uint8_t *)(d), (uint8_t *)(c)->gcm_ghash); \
+diff --git a/module/icp/algs/modes/gcm_pclmulqdq.c b/module/icp/algs/modes/gcm_pclmulqdq.c
+index 8a43ba33a..05920115c 100644
+--- a/module/icp/algs/modes/gcm_pclmulqdq.c
++++ b/module/icp/algs/modes/gcm_pclmulqdq.c
+@@ -24,12 +24,12 @@
+
+ #if defined(__x86_64) && defined(HAVE_PCLMULQDQ)
+
+-#include <linux/simd_x86.h>
++#include <sys/types.h>
++#include <sys/simd.h>
+
+ /* These functions are used to execute pclmulqdq based assembly methods */
+ extern void gcm_mul_pclmulqdq(uint64_t *, uint64_t *, uint64_t *);
+
+-
+ #include <modes/gcm_impl.h>
+
+ /*
+diff --git a/module/icp/io/aes.c b/module/icp/io/aes.c
+index 51538bc60..4b2dbd6e1 100644
+--- a/module/icp/io/aes.c
++++ b/module/icp/io/aes.c
+@@ -212,8 +212,8 @@ aes_mod_init(void)
+ * are run in dedicated kernel threads to allow Linux 5.0+ kernels
+ * to use SIMD operations. If for some reason this isn't possible,
+ * fallback to the generic implementations. See the comment in
+- * include/linux/simd_x86.h for additional details. Additionally,
+- * this has the benefit of allowing them to be run in parallel.
++ * linux/simd_x86.h for additional details. Additionally, this has
++ * the benefit of allowing them to be run in parallel.
+ */
+ taskqid_t aes_id = taskq_dispatch(system_taskq, aes_impl_init,
+ NULL, TQ_SLEEP);
+diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c
+index 69d591ff7..90e1d0a4d 100644
+--- a/module/spl/spl-taskq.c
++++ b/module/spl/spl-taskq.c
+@@ -28,7 +28,7 @@
+ #include <sys/taskq.h>
+ #include <sys/kmem.h>
+ #include <sys/tsd.h>
+-#include <linux/simd.h>
++#include <sys/simd.h>
+
+ int spl_taskq_thread_bind = 0;
+ module_param(spl_taskq_thread_bind, int, 0644);
+diff --git a/module/spl/spl-thread.c b/module/spl/spl-thread.c
+index 07e3a1bff..29de9252a 100644
+--- a/module/spl/spl-thread.c
++++ b/module/spl/spl-thread.c
+@@ -27,7 +27,7 @@
+ #include <sys/thread.h>
+ #include <sys/kmem.h>
+ #include <sys/tsd.h>
+-#include <linux/simd.h>
++#include <sys/simd.h>
+
+ /*
+ * Thread interfaces
+diff --git a/module/zcommon/zfs_fletcher.c b/module/zcommon/zfs_fletcher.c
+index 9187a7c1e..c14c95fa2 100644
+--- a/module/zcommon/zfs_fletcher.c
++++ b/module/zcommon/zfs_fletcher.c
+@@ -137,10 +137,10 @@
+ #include <sys/sysmacros.h>
+ #include <sys/byteorder.h>
+ #include <sys/spa.h>
++#include <sys/simd.h>
+ #include <sys/zio_checksum.h>
+ #include <sys/zfs_context.h>
+ #include <zfs_fletcher.h>
+-#include <linux/simd.h>
+
+ #define FLETCHER_MIN_SIMD_SIZE 64
+
+@@ -773,7 +773,7 @@ fletcher_4_init(void)
+ /*
+ * For 5.0 and latter Linux kernels the fletcher 4 benchmarks are
+ * run in a kernel threads. This is needed to take advantage of the
+- * SIMD functionality, see include/linux/simd_x86.h for details.
++ * SIMD functionality, see linux/simd_x86.h for details.
+ */
+ taskqid_t id = taskq_dispatch(system_taskq, fletcher_4_benchmark,
+ NULL, TQ_SLEEP);
+diff --git a/module/zcommon/zfs_fletcher_aarch64_neon.c b/module/zcommon/zfs_fletcher_aarch64_neon.c
+index 3b3c1b52b..c95a71681 100644
+--- a/module/zcommon/zfs_fletcher_aarch64_neon.c
++++ b/module/zcommon/zfs_fletcher_aarch64_neon.c
+@@ -43,7 +43,7 @@
+
+ #if defined(__aarch64__)
+
+-#include <linux/simd_aarch64.h>
++#include <sys/simd.h>
+ #include <sys/spa_checksum.h>
+ #include <sys/strings.h>
+ #include <zfs_fletcher.h>
+diff --git a/module/zcommon/zfs_fletcher_avx512.c b/module/zcommon/zfs_fletcher_avx512.c
+index 0d4cff21a..43806f264 100644
+--- a/module/zcommon/zfs_fletcher_avx512.c
++++ b/module/zcommon/zfs_fletcher_avx512.c
+@@ -24,11 +24,11 @@
+
+ #if defined(__x86_64) && defined(HAVE_AVX512F)
+
+-#include <linux/simd_x86.h>
+ #include <sys/byteorder.h>
+ #include <sys/frame.h>
+ #include <sys/spa_checksum.h>
+ #include <sys/strings.h>
++#include <sys/simd.h>
+ #include <zfs_fletcher.h>
+
+ #define __asm __asm__ __volatile__
+diff --git a/module/zcommon/zfs_fletcher_intel.c b/module/zcommon/zfs_fletcher_intel.c
+index 7f12efe6d..5136a01ec 100644
+--- a/module/zcommon/zfs_fletcher_intel.c
++++ b/module/zcommon/zfs_fletcher_intel.c
+@@ -42,8 +42,8 @@
+
+ #if defined(HAVE_AVX) && defined(HAVE_AVX2)
+
+-#include <linux/simd_x86.h>
+ #include <sys/spa_checksum.h>
++#include <sys/simd.h>
+ #include <sys/strings.h>
+ #include <zfs_fletcher.h>
+
+diff --git a/module/zcommon/zfs_fletcher_sse.c b/module/zcommon/zfs_fletcher_sse.c
+index e6389d6e5..15ce9b07f 100644
+--- a/module/zcommon/zfs_fletcher_sse.c
++++ b/module/zcommon/zfs_fletcher_sse.c
+@@ -43,7 +43,7 @@
+
+ #if defined(HAVE_SSE2)
+
+-#include <linux/simd_x86.h>
++#include <sys/simd.h>
+ #include <sys/spa_checksum.h>
+ #include <sys/byteorder.h>
+ #include <sys/strings.h>
+diff --git a/module/zfs/vdev_raidz_math.c b/module/zfs/vdev_raidz_math.c
+index ef514e9e1..86d4aabdc 100644
+--- a/module/zfs/vdev_raidz_math.c
++++ b/module/zfs/vdev_raidz_math.c
+@@ -29,7 +29,7 @@
+ #include <sys/zfs_debug.h>
+ #include <sys/vdev_raidz.h>
+ #include <sys/vdev_raidz_impl.h>
+-#include <linux/simd.h>
++#include <sys/simd.h>
+
+ extern boolean_t raidz_will_scalar_work(void);
+
+diff --git a/module/zfs/vdev_raidz_math_aarch64_neon_common.h b/module/zfs/vdev_raidz_math_aarch64_neon_common.h
+index 024917417..f47446753 100644
+--- a/module/zfs/vdev_raidz_math_aarch64_neon_common.h
++++ b/module/zfs/vdev_raidz_math_aarch64_neon_common.h
+@@ -23,7 +23,7 @@
+ */
+
+ #include <sys/types.h>
+-#include <linux/simd_aarch64.h>
++#include <sys/simd.h>
+
+ #define __asm __asm__ __volatile__
+
+diff --git a/module/zfs/vdev_raidz_math_avx2.c b/module/zfs/vdev_raidz_math_avx2.c
+index a12eb6720..008e848d4 100644
+--- a/module/zfs/vdev_raidz_math_avx2.c
++++ b/module/zfs/vdev_raidz_math_avx2.c
+@@ -26,7 +26,7 @@
+ #if defined(__x86_64) && defined(HAVE_AVX2)
+
+ #include <sys/types.h>
+-#include <linux/simd_x86.h>
++#include <sys/simd.h>
+
+ #define __asm __asm__ __volatile__
+
+diff --git a/module/zfs/vdev_raidz_math_avx512bw.c b/module/zfs/vdev_raidz_math_avx512bw.c
+index 2f545c9ec..38cdbedf7 100644
+--- a/module/zfs/vdev_raidz_math_avx512bw.c
++++ b/module/zfs/vdev_raidz_math_avx512bw.c
+@@ -28,7 +28,7 @@
+ #if defined(__x86_64) && defined(HAVE_AVX512BW)
+
+ #include <sys/types.h>
+-#include <linux/simd_x86.h>
++#include <sys/simd.h>
+
+ #define __asm __asm__ __volatile__
+
+diff --git a/module/zfs/vdev_raidz_math_avx512f.c b/module/zfs/vdev_raidz_math_avx512f.c
+index 75af7a8ee..adbe9b0ef 100644
+--- a/module/zfs/vdev_raidz_math_avx512f.c
++++ b/module/zfs/vdev_raidz_math_avx512f.c
+@@ -28,7 +28,7 @@
+ #if defined(__x86_64) && defined(HAVE_AVX512F)
+
+ #include <sys/types.h>
+-#include <linux/simd_x86.h>
++#include <sys/simd.h>
+
+ #define __asm __asm__ __volatile__
+
+diff --git a/module/zfs/vdev_raidz_math_sse2.c b/module/zfs/vdev_raidz_math_sse2.c
+index 5b3a9385c..70a21c10c 100644
+--- a/module/zfs/vdev_raidz_math_sse2.c
++++ b/module/zfs/vdev_raidz_math_sse2.c
+@@ -27,7 +27,7 @@
+ #if defined(__x86_64) && defined(HAVE_SSE2)
+
+ #include <sys/types.h>
+-#include <linux/simd_x86.h>
++#include <sys/simd.h>
+
+ #define __asm __asm__ __volatile__
+
+diff --git a/module/zfs/vdev_raidz_math_ssse3.c b/module/zfs/vdev_raidz_math_ssse3.c
+index 62247cf8e..d5776a38a 100644
+--- a/module/zfs/vdev_raidz_math_ssse3.c
++++ b/module/zfs/vdev_raidz_math_ssse3.c
+@@ -27,7 +27,7 @@
+ #if defined(__x86_64) && defined(HAVE_SSSE3)
+
+ #include <sys/types.h>
+-#include <linux/simd_x86.h>
++#include <sys/simd.h>
+
+ #define __asm __asm__ __volatile__
+
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Brian Behlendorf <behlendorf1@llnl.gov>
+Date: Wed, 9 Oct 2019 22:36:19 +0000
+Subject: [PATCH] Allow FPU usage in user and kernel thread contexts
+
+Even for dedicated kernel threads we apparently cannot be
+guaranteed that the kernel won't modify the FPU state which
+we saved in the task struck. Allocate our own per-cpu state
+to preserve the saved register state. Aside from correctness,
+this allows use of the FPU in user threads again.
+
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+(cherry picked from commit 11170d9073edcbb613f5a4c992293cbb4e3c8e31)
+Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+---
+ config/kernel-fpu.m4 | 7 --
+ include/os/linux/kernel/linux/simd.h | 1 -
+ include/os/linux/kernel/linux/simd_aarch64.h | 2 -
+ include/os/linux/kernel/linux/simd_x86.h | 87 +++++++++++++-------
+ module/spl/spl-taskq.c | 2 -
+ module/spl/spl-thread.c | 2 -
+ module/zcommon/zfs_prop.c | 18 ++++
+ 7 files changed, 73 insertions(+), 46 deletions(-)
+
+diff --git a/config/kernel-fpu.m4 b/config/kernel-fpu.m4
+index 9ed9b14ad..15bea3c22 100644
+--- a/config/kernel-fpu.m4
++++ b/config/kernel-fpu.m4
+@@ -67,12 +67,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
+ #error Unsupported architecture
+ #endif
+
+- #include <linux/sched.h>
+-
+- #if !defined(PF_KTHREAD)
+- #error PF_KTHREAD not defined
+- #endif
+-
+ #ifdef HAVE_KERNEL_FPU_API_HEADER
+ #include <asm/fpu/api.h>
+ #include <asm/fpu/internal.h>
+@@ -94,7 +88,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [
+ struct fregs_state *fr __attribute__ ((unused)) = &st->fsave;
+ struct fxregs_state *fxr __attribute__ ((unused)) = &st->fxsave;
+ struct xregs_state *xr __attribute__ ((unused)) = &st->xsave;
+- fpu->last_cpu = -1;
+ ])
+ ])
+
+diff --git a/include/os/linux/kernel/linux/simd.h b/include/os/linux/kernel/linux/simd.h
+index 1f6574a90..5138a908b 100644
+--- a/include/os/linux/kernel/linux/simd.h
++++ b/include/os/linux/kernel/linux/simd.h
+@@ -33,7 +33,6 @@
+ #else
+
+ #define kfpu_allowed() 0
+-#define kfpu_initialize(tsk) do {} while (0)
+ #define kfpu_begin() do {} while (0)
+ #define kfpu_end() do {} while (0)
+
+diff --git a/include/os/linux/kernel/linux/simd_aarch64.h b/include/os/linux/kernel/linux/simd_aarch64.h
+index ac530d920..f6cf3c377 100644
+--- a/include/os/linux/kernel/linux/simd_aarch64.h
++++ b/include/os/linux/kernel/linux/simd_aarch64.h
+@@ -27,7 +27,6 @@
+ *
+ * Kernel fpu methods:
+ * kfpu_allowed()
+- * kfpu_initialize()
+ * kfpu_begin()
+ * kfpu_end()
+ */
+@@ -43,7 +42,6 @@
+ #include <asm/neon.h>
+
+ #define kfpu_allowed() 1
+-#define kfpu_initialize(tsk) do {} while (0)
+ #define kfpu_begin() kernel_neon_begin()
+ #define kfpu_end() kernel_neon_end()
+
+diff --git a/include/os/linux/kernel/linux/simd_x86.h b/include/os/linux/kernel/linux/simd_x86.h
+index 486e31845..c42ea918e 100644
+--- a/include/os/linux/kernel/linux/simd_x86.h
++++ b/include/os/linux/kernel/linux/simd_x86.h
+@@ -27,7 +27,6 @@
+ *
+ * Kernel fpu methods:
+ * kfpu_allowed()
+- * kfpu_initialize()
+ * kfpu_begin()
+ * kfpu_end()
+ *
+@@ -99,7 +98,6 @@
+ #if defined(KERNEL_EXPORTS_X86_FPU)
+
+ #define kfpu_allowed() 1
+-#define kfpu_initialize(tsk) do {} while (0)
+
+ #if defined(HAVE_UNDERSCORE_KERNEL_FPU)
+ #define kfpu_begin() \
+@@ -129,16 +127,52 @@
+
+ /*
+ * When the kernel_fpu_* symbols are unavailable then provide our own
+- * versions which allow the FPU to be safely used in kernel threads.
+- * In practice, this is not a significant restriction for ZFS since the
+- * vast majority of SIMD operations are performed by the IO pipeline.
++ * versions which allow the FPU to be safely used.
+ */
+ #if defined(HAVE_KERNEL_FPU_INTERNAL)
+
++extern struct fpu **zfs_kfpu_fpregs;
++
+ /*
+- * FPU usage only allowed in dedicated kernel threads.
++ * Initialize per-cpu variables to store FPU state.
+ */
+-#define kfpu_allowed() (current->flags & PF_KTHREAD)
++static inline void
++kfpu_fini(void)
++{
++ int cpu;
++
++ for_each_possible_cpu(cpu) {
++ if (zfs_kfpu_fpregs[cpu] != NULL) {
++ kfree(zfs_kfpu_fpregs[cpu]);
++ }
++ }
++
++ kfree(zfs_kfpu_fpregs);
++}
++
++static inline int
++kfpu_init(void)
++{
++ int cpu;
++
++ zfs_kfpu_fpregs = kzalloc(num_possible_cpus() *
++ sizeof (struct fpu *), GFP_KERNEL);
++ if (zfs_kfpu_fpregs == NULL)
++ return (ENOMEM);
++
++ for_each_possible_cpu(cpu) {
++ zfs_kfpu_fpregs[cpu] = kmalloc_node(sizeof (struct fpu),
++ GFP_KERNEL, cpu_to_node(cpu));
++ if (zfs_kfpu_fpregs[cpu] == NULL) {
++ kfpu_fini();
++ return (ENOMEM);
++ }
++ }
++
++ return (0);
++}
++
++#define kfpu_allowed() 1
+ #define ex_handler_fprestore ex_handler_default
+
+ /*
+@@ -154,15 +188,6 @@
+ #define kfpu_fxsr_clean(rval) __asm("fnclex; emms; fildl %P[addr]" \
+ : : [addr] "m" (rval));
+
+-static inline void
+-kfpu_initialize(void)
+-{
+- WARN_ON_ONCE(!(current->flags & PF_KTHREAD));
+-
+- /* Invalidate the task's FPU state */
+- current->thread.fpu.last_cpu = -1;
+-}
+-
+ static inline void
+ kfpu_save_xsave(struct xregs_state *addr, uint64_t mask)
+ {
+@@ -193,8 +218,6 @@ kfpu_save_fsave(struct fregs_state *addr)
+ static inline void
+ kfpu_begin(void)
+ {
+- WARN_ON_ONCE(!kfpu_allowed());
+-
+ /*
+ * Preemption and interrupts must be disabled for the critical
+ * region where the FPU state is being modified.
+@@ -204,20 +227,18 @@ kfpu_begin(void)
+
+ /*
+ * The current FPU registers need to be preserved by kfpu_begin()
+- * and restored by kfpu_end(). This is always required because we
+- * can not call __cpu_invalidate_fpregs_state() to invalidate the
+- * per-cpu FPU state and force them to be restored. Furthermore,
+- * this implementation relies on the space provided in the task
+- * structure to store the user FPU state. As such, it can only
+- * be used with dedicated kernels which by definition will never
+- * store user FPU state.
++ * and restored by kfpu_end(). They are stored in a dedicated
++ * per-cpu variable, not in the task struct, this allows any user
++ * FPU state to be correctly preserved and restored.
+ */
++ struct fpu *fpu = zfs_kfpu_fpregs[smp_processor_id()];
++
+ if (static_cpu_has(X86_FEATURE_XSAVE)) {
+- kfpu_save_xsave(¤t->thread.fpu.state.xsave, ~0);
++ kfpu_save_xsave(&fpu->state.xsave, ~0);
+ } else if (static_cpu_has(X86_FEATURE_FXSR)) {
+- kfpu_save_fxsr(¤t->thread.fpu.state.fxsave);
++ kfpu_save_fxsr(&fpu->state.fxsave);
+ } else {
+- kfpu_save_fsave(¤t->thread.fpu.state.fsave);
++ kfpu_save_fsave(&fpu->state.fsave);
+ }
+ }
+
+@@ -258,12 +279,14 @@ kfpu_restore_fsave(struct fregs_state *addr)
+ static inline void
+ kfpu_end(void)
+ {
++ struct fpu *fpu = zfs_kfpu_fpregs[smp_processor_id()];
++
+ if (static_cpu_has(X86_FEATURE_XSAVE)) {
+- kfpu_restore_xsave(¤t->thread.fpu.state.xsave, ~0);
++ kfpu_restore_xsave(&fpu->state.xsave, ~0);
+ } else if (static_cpu_has(X86_FEATURE_FXSR)) {
+- kfpu_restore_fxsr(¤t->thread.fpu.state.fxsave);
++ kfpu_restore_fxsr(&fpu->state.fxsave);
+ } else {
+- kfpu_restore_fsave(¤t->thread.fpu.state.fsave);
++ kfpu_restore_fsave(&fpu->state.fsave);
+ }
+
+ local_irq_enable();
+@@ -276,7 +299,6 @@ kfpu_end(void)
+ * FPU support is unavailable.
+ */
+ #define kfpu_allowed() 0
+-#define kfpu_initialize(tsk) do {} while (0)
+ #define kfpu_begin() do {} while (0)
+ #define kfpu_end() do {} while (0)
+
+@@ -286,6 +308,7 @@ kfpu_end(void)
+ /*
+ * Linux kernel provides an interface for CPU feature testing.
+ */
++
+ /*
+ * Detect register set support
+ */
+diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c
+index 90e1d0a4d..a39f94e4c 100644
+--- a/module/spl/spl-taskq.c
++++ b/module/spl/spl-taskq.c
+@@ -28,7 +28,6 @@
+ #include <sys/taskq.h>
+ #include <sys/kmem.h>
+ #include <sys/tsd.h>
+-#include <sys/simd.h>
+
+ int spl_taskq_thread_bind = 0;
+ module_param(spl_taskq_thread_bind, int, 0644);
+@@ -854,7 +853,6 @@ taskq_thread(void *args)
+ sigfillset(&blocked);
+ sigprocmask(SIG_BLOCK, &blocked, NULL);
+ flush_signals(current);
+- kfpu_initialize();
+
+ tsd_set(taskq_tsd, tq);
+ spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
+diff --git a/module/spl/spl-thread.c b/module/spl/spl-thread.c
+index 29de9252a..0352a31ea 100644
+--- a/module/spl/spl-thread.c
++++ b/module/spl/spl-thread.c
+@@ -27,7 +27,6 @@
+ #include <sys/thread.h>
+ #include <sys/kmem.h>
+ #include <sys/tsd.h>
+-#include <sys/simd.h>
+
+ /*
+ * Thread interfaces
+@@ -55,7 +54,6 @@ thread_generic_wrapper(void *arg)
+ args = tp->tp_args;
+ set_current_state(tp->tp_state);
+ set_user_nice((kthread_t *)current, PRIO_TO_NICE(tp->tp_pri));
+- kfpu_initialize();
+ kmem_free(tp->tp_name, tp->tp_name_size);
+ kmem_free(tp, sizeof (thread_priv_t));
+
+diff --git a/module/zcommon/zfs_prop.c b/module/zcommon/zfs_prop.c
+index dab749138..b5fa1c2f4 100644
+--- a/module/zcommon/zfs_prop.c
++++ b/module/zcommon/zfs_prop.c
+@@ -853,10 +853,27 @@ zfs_prop_align_right(zfs_prop_t prop)
+ #endif
+
+ #if defined(_KERNEL)
++
++#if defined(HAVE_KERNEL_FPU_INTERNAL)
++#include <linux/simd.h>
++
++struct fpu **zfs_kfpu_fpregs;
++EXPORT_SYMBOL(zfs_kfpu_fpregs);
++
++#else
++#define kfpu_init() 0
++#define kfpu_fini() ((void) 0)
++#endif /* HAVE_KERNEL_FPU_INTERNAL */
++
+ static int __init
+ zcommon_init(void)
+ {
++ int error = kfpu_init();
++ if (error)
++ return (-error);
++
+ fletcher_4_init();
++
+ return (0);
+ }
+
+@@ -864,6 +881,7 @@ static void __exit
+ zcommon_fini(void)
+ {
+ fletcher_4_fini();
++ kfpu_fini();
+ }
+
+ module_init(zcommon_init);
0004-import-with-d-dev-disk-by-id-in-scan-service.patch
0005-Enable-zed-emails.patch
0006-Linux-5.0-compat-SIMD-compatibility.patch
-0007-Fix-CONFIG_X86_DEBUG_FPU-build-failure.patch
-0008-SIMD-FPU-register-save-restore-is-also-required-on-5.patch
-0009-Perform-KABI-checks-in-parallel.patch
+0007-Perform-KABI-checks-in-parallel.patch
+0008-Linux-4.14-4.19-5.0-compat-SIMD-save-restore.patch
+0009-Fix-CONFIG_X86_DEBUG_FPU-build-failure.patch
+0010-OpenZFS-restructuring-move-platform-specific-headers.patch
+0011-Allow-FPU-usage-in-user-and-kernel-thread-contexts.patch