From 75b07eca3ee987c959f0d5e28479368fc134b94d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Tue, 3 Apr 2018 14:25:21 +0200 Subject: [PATCH] update ZFS to 0.7.7 by importing the upstream release as patches. replace user namespace patch with version which has been applied usptream. --- ...r-namespaces-for-FSETID-policy-check.patch | 67 -- ...0003-always-load-ZFS-module-on-boot.patch} | 0 ...ble-debug-fail-when-given-bogus-args.patch | 89 ++ ...-enable-debuginfo-to-force-debuginfo.patch | 122 +++ ...igure-option-to-enable-gcov-analysis.patch | 121 +++ ...nline-compile-option-more-accessible.patch | 43 + ...port-for-enable-code-coverage-option.patch | 399 +++++++++ zfs-patches/0009-Update-codecov.yml.patch | 97 +++ ...Fix-enable-code-coverage-debug-build.patch | 35 + ...e-vn_rename-and-vn_remove-dependency.patch | 153 ++++ ...d-on-Debian-based-distributions-6963.patch | 102 +++ ...13-ZTS-Fix-create-o_ashift-test-case.patch | 137 +++ ...ror-message-before-MMP-suspends-pool.patch | 49 ++ ...-macros-usage-on-Debian-based-distri.patch | 85 ++ ...at_compress.c-for-vmalloc-addr-check.patch | 39 + ...Fix-default-libdir-for-Debian-Ubuntu.patch | 52 ++ ...recated-zfs_arc_p_aggressive_disable.patch | 71 ++ ...rce-file-zfs_acl.c-function-zfs_acls.patch | 51 ++ ...Linux-4.16-compat-inode_set_iversion.patch | 145 ++++ ...ompat-avoid-refcount_t-name-conflict.patch | 53 ++ ...traverse-stop-on-damaged-objset-root.patch | 116 +++ ...x-zle_decompress-out-of-bound-access.patch | 40 + ...racy-assignment-of-zcb.zcb_haderrors.patch | 59 ++ .../0025-Fix-zdb-R-decompression.patch | 130 +++ zfs-patches/0026-Fix-zdb-E-segfault.patch | 50 ++ ...x-zdb-ed-on-objset-for-exported-pool.patch | 217 +++++ ...-zap_add-failures-in-mixed-case-mode.patch | 553 ++++++++++++ ...use-a-fixed-tag-for-spa_config-locks.patch | 56 ++ ...rib-initramfs-add-missing-conf.d-zfs.patch | 66 ++ ...s-receive-fails-with-dataset-is-busy.patch | 90 ++ ..._remove_child-panic-due-to-already-d.patch | 247 ++++++ ...3-Clarify-zinject-8-explanation-of-e.patch | 40 + ...config-issues-frame-size-and-headers.patch | 199 +++++ ...rrect-count_uberblocks-in-mmp.kshlib.patch | 38 + ...dd-SMART-attributes-for-SSD-and-NVMe.patch | 131 +++ ...e-to-fail-when-called-within-systemd.patch | 52 ++ ....16-compat-use-correct-_dec_and_test.patch | 85 ++ ...e-MMP-writes-while-pool-is-suspended.patch | 39 + ...ion-and-error-in-mmp_history-entries.patch | 237 ++++++ ...Fix-free-memory-calculation-on-v3.14.patch | 451 ++++++++++ ...-Add-scrub-after-resilver-zed-script.patch | 516 ++++++++++++ ...-self-test-results-to-zpool-status-c.patch | 322 +++++++ ...-list-example-to-match-actual-format.patch | 66 ++ zfs-patches/0045-Fix-some-typos.patch | 275 ++++++ ...ment-zil_itx_needcopy_bytes-properly.patch | 46 + ...e-checksum-IO-delay-ratelimit-values.patch | 201 +++++ ...inux-4.16-compat-get_disk_and_module.patch | 98 +++ ...-long-config-lock-acquisition-in-mmp.patch | 46 + ...spaces-into-account-in-policy-checks.patch | 786 ++++++++++++++++++ ...use-tests-don-t-pass-with-real-disks.patch | 232 ++++++ ...-zfs-kmod-builds-when-using-rpm-4.14.patch | 39 + .../0053-Handle-zio_resume-and-mmp-off.patch | 60 ++ ...-MMP-write-frequency-for-large-pools.patch | 72 ++ zfs-patches/0055-Tag-zfs-0.7.7.patch | 63 ++ zfs-patches/series | 55 +- 55 files changed, 7614 insertions(+), 69 deletions(-) delete mode 100644 zfs-patches/0003-Use-user-namespaces-for-FSETID-policy-check.patch rename zfs-patches/{0004-always-load-ZFS-module-on-boot.patch => 0003-always-load-ZFS-module-on-boot.patch} (100%) create mode 100644 zfs-patches/0004-Make-enable-debug-fail-when-given-bogus-args.patch create mode 100644 zfs-patches/0005-Implement-enable-debuginfo-to-force-debuginfo.patch create mode 100644 zfs-patches/0006-Add-configure-option-to-enable-gcov-analysis.patch create mode 100644 zfs-patches/0007-Make-fno-inline-compile-option-more-accessible.patch create mode 100644 zfs-patches/0008-Add-support-for-enable-code-coverage-option.patch create mode 100644 zfs-patches/0009-Update-codecov.yml.patch create mode 100644 zfs-patches/0010-Fix-enable-code-coverage-debug-build.patch create mode 100644 zfs-patches/0011-Remove-vn_rename-and-vn_remove-dependency.patch create mode 100644 zfs-patches/0012-Fix-with-systemd-on-Debian-based-distributions-6963.patch create mode 100644 zfs-patches/0013-ZTS-Fix-create-o_ashift-test-case.patch create mode 100644 zfs-patches/0014-Emit-an-error-message-before-MMP-suspends-pool.patch create mode 100644 zfs-patches/0015-Fix-systemd_-RPM-macros-usage-on-Debian-based-distri.patch create mode 100644 zfs-patches/0016-Bug-fix-in-qat_compress.c-for-vmalloc-addr-check.patch create mode 100644 zfs-patches/0017-Fix-default-libdir-for-Debian-Ubuntu.patch create mode 100644 zfs-patches/0018-Remove-deprecated-zfs_arc_p_aggressive_disable.patch create mode 100644 zfs-patches/0019-OpenZFS-8966-Source-file-zfs_acl.c-function-zfs_acls.patch create mode 100644 zfs-patches/0020-Linux-4.16-compat-inode_set_iversion.patch create mode 100644 zfs-patches/0021-Linux-4.11-compat-avoid-refcount_t-name-conflict.patch create mode 100644 zfs-patches/0022-Fix-zdb-c-traverse-stop-on-damaged-objset-root.patch create mode 100644 zfs-patches/0023-Fix-zle_decompress-out-of-bound-access.patch create mode 100644 zfs-patches/0024-Fix-racy-assignment-of-zcb.zcb_haderrors.patch create mode 100644 zfs-patches/0025-Fix-zdb-R-decompression.patch create mode 100644 zfs-patches/0026-Fix-zdb-E-segfault.patch create mode 100644 zfs-patches/0027-Fix-zdb-ed-on-objset-for-exported-pool.patch create mode 100644 zfs-patches/0028-Handle-zap_add-failures-in-mixed-case-mode.patch create mode 100644 zfs-patches/0029-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch create mode 100644 zfs-patches/0030-contrib-initramfs-add-missing-conf.d-zfs.patch create mode 100644 zfs-patches/0031-zfs-receive-fails-with-dataset-is-busy.patch create mode 100644 zfs-patches/0032-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch create mode 100644 zfs-patches/0033-Clarify-zinject-8-explanation-of-e.patch create mode 100644 zfs-patches/0034-Fix-config-issues-frame-size-and-headers.patch create mode 100644 zfs-patches/0035-Correct-count_uberblocks-in-mmp.kshlib.patch create mode 100644 zfs-patches/0036-Add-SMART-attributes-for-SSD-and-NVMe.patch create mode 100644 zfs-patches/0037-Allow-modprobe-to-fail-when-called-within-systemd.patch create mode 100644 zfs-patches/0038-Linux-4.16-compat-use-correct-_dec_and_test.patch create mode 100644 zfs-patches/0039-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch create mode 100644 zfs-patches/0040-Report-duration-and-error-in-mmp_history-entries.patch create mode 100644 zfs-patches/0041-Fix-free-memory-calculation-on-v3.14.patch create mode 100644 zfs-patches/0042-Add-scrub-after-resilver-zed-script.patch create mode 100644 zfs-patches/0043-Add-SMART-self-test-results-to-zpool-status-c.patch create mode 100644 zfs-patches/0044-Fix-zpool-8-list-example-to-match-actual-format.patch create mode 100644 zfs-patches/0045-Fix-some-typos.patch create mode 100644 zfs-patches/0046-Increment-zil_itx_needcopy_bytes-properly.patch create mode 100644 zfs-patches/0047-Change-checksum-IO-delay-ratelimit-values.patch create mode 100644 zfs-patches/0048-Linux-4.16-compat-get_disk_and_module.patch create mode 100644 zfs-patches/0049-Detect-long-config-lock-acquisition-in-mmp.patch create mode 100644 zfs-patches/0050-Take-user-namespaces-into-account-in-policy-checks.patch create mode 100644 zfs-patches/0051-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch create mode 100644 zfs-patches/0052-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch create mode 100644 zfs-patches/0053-Handle-zio_resume-and-mmp-off.patch create mode 100644 zfs-patches/0054-Fix-MMP-write-frequency-for-large-pools.patch create mode 100644 zfs-patches/0055-Tag-zfs-0.7.7.patch diff --git a/zfs-patches/0003-Use-user-namespaces-for-FSETID-policy-check.patch b/zfs-patches/0003-Use-user-namespaces-for-FSETID-policy-check.patch deleted file mode 100644 index b076ef6..0000000 --- a/zfs-patches/0003-Use-user-namespaces-for-FSETID-policy-check.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Wolfgang Bumiller -Date: Tue, 31 Oct 2017 09:08:42 +0100 -Subject: [PATCH] Use user namespaces for FSETID policy check. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With this we also need to verify the group id of a file with -the setgid flag has a valid mapping in the current -namespace. - -Signed-off-by: Wolfgang Bumiller -Signed-off-by: Fabian Grünbichler ---- - module/zfs/policy.c | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - -diff --git a/module/zfs/policy.c b/module/zfs/policy.c -index 03e8f748b..dbbcfefa3 100644 ---- a/module/zfs/policy.c -+++ b/module/zfs/policy.c -@@ -42,19 +42,26 @@ - * all other cases this function must fail and return the passed err. - */ - static int --priv_policy(const cred_t *cr, int capability, boolean_t all, int err) -+priv_policy_ns(const cred_t *cr, int capability, boolean_t all, int err, -+ struct user_namespace *ns) - { - ASSERT3S(all, ==, B_FALSE); - - if (cr != CRED() && (cr != kcred)) - return (err); - -- if (!capable(capability)) -+ if (!(ns ? ns_capable(ns, capability) : capable(capability))) - return (err); - - return (0); - } - -+static int -+priv_policy(const cred_t *cr, int capability, boolean_t all, int err) -+{ -+ return priv_policy_ns(cr, capability, all, err, NULL); -+} -+ - /* - * Checks for operations that are either client-only or are used by - * both clients and servers. -@@ -175,8 +182,11 @@ secpolicy_vnode_setid_retain(const cred_t *cr, boolean_t issuidroot) - int - secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid) - { -+ if (!kgid_has_mapping(cr->user_ns, SGID_TO_KGID(gid))) -+ return (EPERM); - if (crgetfsgid(cr) != gid && !groupmember(gid, cr)) -- return (priv_policy(cr, CAP_FSETID, B_FALSE, EPERM)); -+ return (priv_policy_ns(cr, CAP_FSETID, B_FALSE, EPERM, -+ cr->user_ns)); - - return (0); - } --- -2.14.2 - diff --git a/zfs-patches/0004-always-load-ZFS-module-on-boot.patch b/zfs-patches/0003-always-load-ZFS-module-on-boot.patch similarity index 100% rename from zfs-patches/0004-always-load-ZFS-module-on-boot.patch rename to zfs-patches/0003-always-load-ZFS-module-on-boot.patch diff --git a/zfs-patches/0004-Make-enable-debug-fail-when-given-bogus-args.patch b/zfs-patches/0004-Make-enable-debug-fail-when-given-bogus-args.patch new file mode 100644 index 0000000..d751a53 --- /dev/null +++ b/zfs-patches/0004-Make-enable-debug-fail-when-given-bogus-args.patch @@ -0,0 +1,89 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Richard Yao +Date: Tue, 23 Sep 2014 13:31:33 -0400 +Subject: [PATCH] Make --enable-debug fail when given bogus args +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently, bogus options to --enable-debug become --disable-debug. That +means that passing --enable-debug=true is analogous to --disable-debug, +but the result is counterintuitive. We switch to AS_CASE to allow us to +fail when given a bogus option. + +Also, we modify the text printed to clarify that --enable-debug enables +assertions. + +Reviewed-by: Chunwei Chen +Reviewed-by: Brian Behlendorf +Signed-off-by: Richard Yao +Closes #2734 +(cherry picked from commit 0f1ff38476ba255eb1f066f675c8721168ff2295) +Signed-off-by: Fabian Grünbichler +--- + config/zfs-build.m4 | 43 +++++++++++++++++++++++++------------------ + 1 file changed, 25 insertions(+), 18 deletions(-) + +diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 +index 7651dc2c1..78a87aef7 100644 +--- a/config/zfs-build.m4 ++++ b/config/zfs-build.m4 +@@ -6,30 +6,37 @@ AC_DEFUN([ZFS_AC_LICENSE], [ + AC_MSG_RESULT([$ZFS_META_LICENSE]) + ]) + ++AC_DEFUN([ZFS_AC_DEBUG_ENABLE], [ ++ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG -Werror" ++ HOSTCFLAGS="${HOSTCFLAGS} -DDEBUG -Werror" ++ DEBUG_CFLAGS="-DDEBUG -Werror" ++ DEBUG_STACKFLAGS="-fstack-check" ++ DEBUG_ZFS="_with_debug" ++ AC_DEFINE(ZFS_DEBUG, 1, [zfs debugging enabled]) ++]) ++ ++AC_DEFUN([ZFS_AC_DEBUG_DISABLE], [ ++ KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG " ++ HOSTCFLAGS="${HOSTCFLAGS} -DNDEBUG " ++ DEBUG_CFLAGS="-DNDEBUG" ++ DEBUG_STACKFLAGS="" ++ DEBUG_ZFS="_without_debug" ++]) ++ + AC_DEFUN([ZFS_AC_DEBUG], [ +- AC_MSG_CHECKING([whether debugging is enabled]) ++ AC_MSG_CHECKING([whether assertion support will be enabled]) + AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], +- [Enable generic debug support @<:@default=no@:>@])], ++ [Enable assertion support @<:@default=no@:>@])], + [], + [enable_debug=no]) + +- AS_IF([test "x$enable_debug" = xyes], +- [ +- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG -Werror" +- HOSTCFLAGS="${HOSTCFLAGS} -DDEBUG -Werror" +- DEBUG_CFLAGS="-DDEBUG -Werror" +- DEBUG_STACKFLAGS="-fstack-check" +- DEBUG_ZFS="_with_debug" +- AC_DEFINE(ZFS_DEBUG, 1, [zfs debugging enabled]) +- ], +- [ +- KERNELCPPFLAGS="${KERNELCPPFLAGS} -DNDEBUG " +- HOSTCFLAGS="${HOSTCFLAGS} -DNDEBUG " +- DEBUG_CFLAGS="-DNDEBUG" +- DEBUG_STACKFLAGS="" +- DEBUG_ZFS="_without_debug" +- ]) ++ AS_CASE(["x$enable_debug"], ++ ["xyes"], ++ [ZFS_AC_DEBUG_ENABLE], ++ ["xno"], ++ [ZFS_AC_DEBUG_DISABLE], ++ [AC_MSG_ERROR([Unknown option $enable_debug])]) + + AC_SUBST(DEBUG_CFLAGS) + AC_SUBST(DEBUG_STACKFLAGS) +-- +2.14.2 + diff --git a/zfs-patches/0005-Implement-enable-debuginfo-to-force-debuginfo.patch b/zfs-patches/0005-Implement-enable-debuginfo-to-force-debuginfo.patch new file mode 100644 index 0000000..83ad9d8 --- /dev/null +++ b/zfs-patches/0005-Implement-enable-debuginfo-to-force-debuginfo.patch @@ -0,0 +1,122 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Richard Yao +Date: Tue, 23 Sep 2014 14:29:30 -0400 +Subject: [PATCH] Implement --enable-debuginfo to force debuginfo +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Inspection of a Ubuntu 14.04 x64 system revealed that the config file +used to build the kernel image differs from the config file used to +build kernel modules by the presence of CONFIG_DEBUG_INFO=y: + +This in itself is insufficient to show that the kernel is built with +debuginfo, but a cursory analysis of the debuginfo provided and the +size of the kernel strongly suggests that it was built with +CONFIG_DEBUG_INFO=y while the modules were not. Installing +linux-image-$(uname -r)-dbgsym had no obvious effect on the debuginfo +provided by either the modules or the kernel. + +The consequence is that issue reports from distributions such as Ubuntu +and its derivatives build kernel modules without debuginfo contain +nonsensical backtraces. It is therefore desireable to force generation +of debuginfo, so we implement --enable-debuginfo. Since the build system +can build both userspace components and kernel modules, the generic +--enable-debuginfo option will force debuginfo for both. However, it +also supports --enable-debuginfo=kernel and --enable-debuginfo=user for +finer grained control. + +Enabling debuginfo for the kernel modules works by injecting +CONFIG_DEBUG_INFO=y into the make environment. This is enables +generation of debuginfo by the kernel build systems on all Linux +kernels, but the build environment is slightly different int hat +CONFIG_DEBUG_INFO has not been in the CPP. Adding -DCONFIG_DEBUG_INFO +would fix that, but it would also cause build failures on kernels where +CONFIG_DEBUG_INFO=y is already set. That would complicate its use in +DKMS environments that support a range of kernels and is therefore +undesireable. We could write a compatibility shim to enable +CONFIG_DEBUG_INFO only when it is explicitly disabled, but we forgo +doing that because it is unnecessary. Nothing in ZoL or the kernel uses +CONFIG_DEBUG_INFO in the CPP at this time and that is unlikely to +change. + +Enabling debuginfo for the userspace components is done by injecting -g +into CPPFLAGS. This is not necessary because the build system honors the +environment's CPPFLAGS by appending them to the actual CPPFLAGS used, +but it is supported for consistency. + +Reviewed-by: Chunwei Chen +Reviewed-by: Brian Behlendorf +Signed-off-by: Richard Yao +Closes #2734 +(cherry picked from commit 834815e9f767c9c5e7220ff84f29b1f069822a4d) +Signed-off-by: Fabian Grünbichler +--- + configure.ac | 1 + + config/zfs-build.m4 | 33 ++++++++++++++++++++++++++++++++- + 2 files changed, 33 insertions(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 0c7977ef8..e145aa370 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -55,6 +55,7 @@ ZFS_AC_LICENSE + ZFS_AC_PACKAGE + ZFS_AC_CONFIG + ZFS_AC_DEBUG ++ZFS_AC_DEBUGINFO + + AC_CONFIG_FILES([ + Makefile +diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 +index 78a87aef7..a8609b829 100644 +--- a/config/zfs-build.m4 ++++ b/config/zfs-build.m4 +@@ -38,12 +38,43 @@ AC_DEFUN([ZFS_AC_DEBUG], [ + [ZFS_AC_DEBUG_DISABLE], + [AC_MSG_ERROR([Unknown option $enable_debug])]) + +- AC_SUBST(DEBUG_CFLAGS) + AC_SUBST(DEBUG_STACKFLAGS) + AC_SUBST(DEBUG_ZFS) + AC_MSG_RESULT([$enable_debug]) + ]) + ++AC_DEFUN([ZFS_AC_DEBUGINFO_KERNEL], [ ++ KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS CONFIG_DEBUG_INFO=y" ++]) ++ ++AC_DEFUN([ZFS_AC_DEBUGINFO_USER], [ ++ DEBUG_CFLAGS="$DEBUG_CFLAGS -g" ++]) ++ ++AC_DEFUN([ZFS_AC_DEBUGINFO], [ ++ AC_MSG_CHECKING([whether debuginfo support will be forced]) ++ AC_ARG_ENABLE([debuginfo], ++ [AS_HELP_STRING([--enable-debuginfo], ++ [Force generation of debuginfo @<:@default=no@:>@])], ++ [], ++ [enable_debuginfo=no]) ++ ++ AS_CASE(["x$enable_debuginfo"], ++ ["xyes"], ++ [ZFS_AC_DEBUGINFO_KERNEL ++ ZFS_AC_DEBUGINFO_USER], ++ ["xkernel"], ++ [ZFS_AC_DEBUGINFO_KERNEL], ++ ["xuser"], ++ [ZFS_AC_DEBUGINFO_USER], ++ ["xno"], ++ [], ++ [AC_MSG_ERROR([Unknown option $enable_debug])]) ++ ++ AC_SUBST(DEBUG_CFLAGS) ++ AC_MSG_RESULT([$enable_debuginfo]) ++]) ++ + AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [ + ZFS_AC_CONFIG_ALWAYS_NO_UNUSED_BUT_SET_VARIABLE + ZFS_AC_CONFIG_ALWAYS_NO_BOOL_COMPARE +-- +2.14.2 + diff --git a/zfs-patches/0006-Add-configure-option-to-enable-gcov-analysis.patch b/zfs-patches/0006-Add-configure-option-to-enable-gcov-analysis.patch new file mode 100644 index 0000000..d5030e0 --- /dev/null +++ b/zfs-patches/0006-Add-configure-option-to-enable-gcov-analysis.patch @@ -0,0 +1,121 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Fri, 15 Sep 2017 10:24:13 -0700 +Subject: [PATCH] Add configure option to enable gcov analysis +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* Add configure option to enable gcov analysis. +* Includes a few minor ctime fixes. +* Add codecov.yml configuration. + +Reviewed-by: Prakash Surya +Signed-off-by: Brian Behlendorf +Closes #6642 +(cherry picked from commit 184087f822ef178d6f5c155681ee7c3d90f23321) +Signed-off-by: Fabian Grünbichler +--- + configure.ac | 1 + + Makefile.am | 8 +++--- + .github/codecov.yml | 9 +++++++ + config/zfs-build.m4 | 31 ++++++++++++++++++++++ + .../tests/functional/ctime/ctime_001_pos.ksh | 0 + 5 files changed, 45 insertions(+), 4 deletions(-) + create mode 100644 .github/codecov.yml + mode change 100644 => 100755 tests/zfs-tests/tests/functional/ctime/ctime_001_pos.ksh + +diff --git a/configure.ac b/configure.ac +index e145aa370..ee754fd38 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -56,6 +56,7 @@ ZFS_AC_PACKAGE + ZFS_AC_CONFIG + ZFS_AC_DEBUG + ZFS_AC_DEBUGINFO ++ZFS_AC_GCOV + + AC_CONFIG_FILES([ + Makefile +diff --git a/Makefile.am b/Makefile.am +index 508d3f40e..732a373bd 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -29,10 +29,10 @@ distclean-local:: + -o -name .pc -o -name .hg -o -name .git \) -prune -o \ + \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ + -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ +- -o -name '.*.rej' -o -name '.script-config' -o -size 0 \ +- -o -name '*%' -o -name '.*.cmd' -o -name 'core' \ +- -o -name 'Makefile' -o -name 'Module.symvers' \ +- -o -name '*.order' -o -name '*.markers' \) \ ++ -o -name '.*.rej' -o -size 0 -o -name '*%' -o -name '.*.cmd' \ ++ -o -name 'core' -o -name 'Makefile' -o -name 'Module.symvers' \ ++ -o -name '*.order' -o -name '*.markers' -o -name '*.gcda' \ ++ -o -name '*.gcno' \) \ + -type f -print | xargs $(RM) + + dist-hook: +diff --git a/.github/codecov.yml b/.github/codecov.yml +new file mode 100644 +index 000000000..f36be39cb +--- /dev/null ++++ b/.github/codecov.yml +@@ -0,0 +1,9 @@ ++codecov: ++ strict_yaml_branch: master # only use the latest copy on master branch ++ ++comment: off ++ ++coverage: ++ status: ++ project: off ++ patch: off +diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 +index a8609b829..b84658a64 100644 +--- a/config/zfs-build.m4 ++++ b/config/zfs-build.m4 +@@ -75,6 +75,37 @@ AC_DEFUN([ZFS_AC_DEBUGINFO], [ + AC_MSG_RESULT([$enable_debuginfo]) + ]) + ++AC_DEFUN([ZFS_AC_GCOV_KERNEL], [ ++]) ++ ++AC_DEFUN([ZFS_AC_GCOV_USER], [ ++ DEBUG_CFLAGS="$DEBUG_CFLAGS -fprofile-arcs -ftest-coverage" ++]) ++ ++AC_DEFUN([ZFS_AC_GCOV], [ ++ AC_MSG_CHECKING([whether gcov profiling will be enabled]) ++ AC_ARG_ENABLE([gcov], ++ [AS_HELP_STRING([--enable-gcov], ++ [Enable gcov profiling @<:@default=no@:>@])], ++ [], ++ [enable_gcov=no]) ++ ++ AS_CASE(["x$enable_gcov"], ++ ["xyes"], ++ [ZFS_AC_GCOV_KERNEL ++ ZFS_AC_GCOV_USER], ++ ["xkernel"], ++ [ZFS_AC_GCOV_KERNEL], ++ ["xuser"], ++ [ZFS_AC_GCOV_USER], ++ ["xno"], ++ [], ++ [AC_MSG_ERROR([Unknown option $enable_gcov])]) ++ ++ AC_SUBST(DEBUG_CFLAGS) ++ AC_MSG_RESULT([$enable_gcov]) ++]) ++ + AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [ + ZFS_AC_CONFIG_ALWAYS_NO_UNUSED_BUT_SET_VARIABLE + ZFS_AC_CONFIG_ALWAYS_NO_BOOL_COMPARE +diff --git a/tests/zfs-tests/tests/functional/ctime/ctime_001_pos.ksh b/tests/zfs-tests/tests/functional/ctime/ctime_001_pos.ksh +old mode 100644 +new mode 100755 +-- +2.14.2 + diff --git a/zfs-patches/0007-Make-fno-inline-compile-option-more-accessible.patch b/zfs-patches/0007-Make-fno-inline-compile-option-more-accessible.patch new file mode 100644 index 0000000..ef6324c --- /dev/null +++ b/zfs-patches/0007-Make-fno-inline-compile-option-more-accessible.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Prakash Surya +Date: Fri, 15 Sep 2017 11:47:11 -0700 +Subject: [PATCH] Make "-fno-inline" compile option more accessible +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When functions are inlined, it can make the system much more difficult +to instrument using tools such as ftrace, BPF, crash, etc. Thus, to aid +development and increase the system's observability, when the +"--enable-debuginfo" flag is specified, the "-fno-inline" compilation +option will be used for both userspace and kernel modules. + +Reviewed-by: Brian Behlendorf +Signed-off-by: Prakash Surya +Closes #6605 +(cherry picked from commit f1236ebf35d1531db75ac8a57b23e8fe48d6b780) +Signed-off-by: Fabian Grünbichler +--- + config/zfs-build.m4 | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 +index b84658a64..c695a882e 100644 +--- a/config/zfs-build.m4 ++++ b/config/zfs-build.m4 +@@ -45,10 +45,11 @@ AC_DEFUN([ZFS_AC_DEBUG], [ + + AC_DEFUN([ZFS_AC_DEBUGINFO_KERNEL], [ + KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS CONFIG_DEBUG_INFO=y" ++ KERNELCPPFLAGS="${KERNELCPPFLAGS} -fno-inline" + ]) + + AC_DEFUN([ZFS_AC_DEBUGINFO_USER], [ +- DEBUG_CFLAGS="$DEBUG_CFLAGS -g" ++ DEBUG_CFLAGS="${DEBUG_CFLAGS} -g -fno-inline" + ]) + + AC_DEFUN([ZFS_AC_DEBUGINFO], [ +-- +2.14.2 + diff --git a/zfs-patches/0008-Add-support-for-enable-code-coverage-option.patch b/zfs-patches/0008-Add-support-for-enable-code-coverage-option.patch new file mode 100644 index 0000000..ca322b0 --- /dev/null +++ b/zfs-patches/0008-Add-support-for-enable-code-coverage-option.patch @@ -0,0 +1,399 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Prakash Surya +Date: Fri, 22 Sep 2017 18:49:57 -0700 +Subject: [PATCH] Add support for "--enable-code-coverage" option +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This change adds support for a new option that can be passed to the +configure script: "--enable-code-coverage". Further, the "--enable-gcov" +option has been removed, as this new option provides the same +functionality (plus more). + +When using this new option the following make targets are available: + + * check-code-coverage + * code-coverage-capture + * code-coverage-clean + +Note: these make targets can only be run from the root of the project. + +Reviewed-by: Brian Behlendorf +Signed-off-by: Prakash Surya +Closes #6670 +(cherry picked from commit 6b278f3223c0322527836da2e11e33978e54a234) +Signed-off-by: Fabian Grünbichler +--- + configure.ac | 2 +- + Makefile.am | 2 + + config/Rules.am | 2 + + config/ax_code_coverage.m4 | 264 +++++++++++++++++++++++++++++++++++++++++++++ + config/zfs-build.m4 | 31 ------ + 5 files changed, 269 insertions(+), 32 deletions(-) + create mode 100644 config/ax_code_coverage.m4 + +diff --git a/configure.ac b/configure.ac +index ee754fd38..d71712e4c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -50,13 +50,13 @@ AC_PROG_CC + AC_PROG_LIBTOOL + AM_PROG_AS + AM_PROG_CC_C_O ++AX_CODE_COVERAGE + + ZFS_AC_LICENSE + ZFS_AC_PACKAGE + ZFS_AC_CONFIG + ZFS_AC_DEBUG + ZFS_AC_DEBUGINFO +-ZFS_AC_GCOV + + AC_CONFIG_FILES([ + Makefile +diff --git a/Makefile.am b/Makefile.am +index 732a373bd..b539ff30f 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -23,6 +23,8 @@ EXTRA_DIST = autogen.sh copy-builtin + EXTRA_DIST += config/config.awk config/rpm.am config/deb.am config/tgz.am + EXTRA_DIST += META DISCLAIMER COPYRIGHT README.markdown OPENSOLARIS.LICENSE + ++@CODE_COVERAGE_RULES@ ++ + distclean-local:: + -$(RM) -R autom4te*.cache + -find . \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \ +diff --git a/config/Rules.am b/config/Rules.am +index 1d39e7779..215f09c34 100644 +--- a/config/Rules.am ++++ b/config/Rules.am +@@ -6,6 +6,7 @@ AM_CFLAGS += ${NO_UNUSED_BUT_SET_VARIABLE} + AM_CFLAGS += ${NO_BOOL_COMPARE} + AM_CFLAGS += -fno-strict-aliasing + AM_CFLAGS += -std=gnu99 ++AM_CFLAGS += $(CODE_COVERAGE_CFLAGS) + AM_CPPFLAGS = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT + AM_CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64 + AM_CPPFLAGS += -D_LARGEFILE64_SOURCE -DHAVE_LARGE_STACKS=1 +@@ -14,3 +15,4 @@ AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\" + AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\" + AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\" + AM_CPPFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\" ++AM_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS) +diff --git a/config/ax_code_coverage.m4 b/config/ax_code_coverage.m4 +new file mode 100644 +index 000000000..6484f0332 +--- /dev/null ++++ b/config/ax_code_coverage.m4 +@@ -0,0 +1,264 @@ ++# =========================================================================== ++# https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html ++# =========================================================================== ++# ++# SYNOPSIS ++# ++# AX_CODE_COVERAGE() ++# ++# DESCRIPTION ++# ++# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS, ++# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LIBS which should be included ++# in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every ++# build target (program or library) which should be built with code ++# coverage support. Also defines CODE_COVERAGE_RULES which should be ++# substituted in your Makefile; and $enable_code_coverage which can be ++# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined ++# and substituted, and corresponds to the value of the ++# --enable-code-coverage option, which defaults to being disabled. ++# ++# Test also for gcov program and create GCOV variable that could be ++# substituted. ++# ++# Note that all optimization flags in CFLAGS must be disabled when code ++# coverage is enabled. ++# ++# Usage example: ++# ++# configure.ac: ++# ++# AX_CODE_COVERAGE ++# ++# Makefile.am: ++# ++# @CODE_COVERAGE_RULES@ ++# my_program_LIBS = ... $(CODE_COVERAGE_LIBS) ... ++# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ... ++# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ... ++# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ... ++# ++# This results in a "check-code-coverage" rule being added to any ++# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module ++# has been configured with --enable-code-coverage). Running `make ++# check-code-coverage` in that directory will run the module's test suite ++# (`make check`) and build a code coverage report detailing the code which ++# was touched, then print the URI for the report. ++# ++# In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined ++# instead of CODE_COVERAGE_LIBS. They are both still defined, but use of ++# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is ++# deprecated. They have the same value. ++# ++# This code was derived from Makefile.decl in GLib, originally licenced ++# under LGPLv2.1+. ++# ++# LICENSE ++# ++# Copyright (c) 2012, 2016 Philip Withnall ++# Copyright (c) 2012 Xan Lopez ++# Copyright (c) 2012 Christian Persch ++# Copyright (c) 2012 Paolo Borelli ++# Copyright (c) 2012 Dan Winship ++# Copyright (c) 2015 Bastien ROUCARIES ++# ++# This library is free software; you can redistribute it and/or modify it ++# under the terms of the GNU Lesser General Public License as published by ++# the Free Software Foundation; either version 2.1 of the License, or (at ++# your option) any later version. ++# ++# This library 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 Lesser ++# General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public License ++# along with this program. If not, see . ++ ++#serial 25 ++ ++AC_DEFUN([AX_CODE_COVERAGE],[ ++ dnl Check for --enable-code-coverage ++ AC_REQUIRE([AC_PROG_SED]) ++ ++ # allow to override gcov location ++ AC_ARG_WITH([gcov], ++ [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], ++ [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov], ++ [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov]) ++ ++ AC_MSG_CHECKING([whether to build with code coverage support]) ++ AC_ARG_ENABLE([code-coverage], ++ AS_HELP_STRING([--enable-code-coverage], ++ [Whether to enable code coverage support]),, ++ enable_code_coverage=no) ++ ++ AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) ++ AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) ++ AC_MSG_RESULT($enable_code_coverage) ++ ++ AS_IF([ test "$enable_code_coverage" = "yes" ], [ ++ # check for gcov ++ AC_CHECK_TOOL([GCOV], ++ [$_AX_CODE_COVERAGE_GCOV_PROG_WITH], ++ [:]) ++ AS_IF([test "X$GCOV" = "X:"], ++ [AC_MSG_ERROR([gcov is needed to do coverage])]) ++ AC_SUBST([GCOV]) ++ ++ dnl Check if gcc is being used ++ AS_IF([ test "$GCC" = "no" ], [ ++ AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) ++ ]) ++ ++ AC_CHECK_PROG([LCOV], [lcov], [lcov]) ++ AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) ++ ++ AS_IF([ test -z "$LCOV" ], [ ++ AC_MSG_ERROR([To enable code coverage reporting you must have lcov installed]) ++ ]) ++ ++ AS_IF([ test -z "$GENHTML" ], [ ++ AC_MSG_ERROR([Could not find genhtml from the lcov package]) ++ ]) ++ ++ dnl Build the code coverage flags ++ dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility ++ CODE_COVERAGE_CPPFLAGS="-DNDEBUG" ++ CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" ++ CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" ++ CODE_COVERAGE_LIBS="-lgcov" ++ CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" ++ ++ AC_SUBST([CODE_COVERAGE_CPPFLAGS]) ++ AC_SUBST([CODE_COVERAGE_CFLAGS]) ++ AC_SUBST([CODE_COVERAGE_CXXFLAGS]) ++ AC_SUBST([CODE_COVERAGE_LIBS]) ++ AC_SUBST([CODE_COVERAGE_LDFLAGS]) ++ ++ [CODE_COVERAGE_RULES_CHECK=' ++ -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check ++ $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture ++'] ++ [CODE_COVERAGE_RULES_CAPTURE=' ++ $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) ++ $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) ++ -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp ++ $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) ++ @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" ++'] ++ [CODE_COVERAGE_RULES_CLEAN=' ++clean: code-coverage-clean ++distclean: code-coverage-clean ++code-coverage-clean: ++ -$(LCOV) --directory $(top_builddir) -z ++ -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) ++ -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete ++'] ++ ], [ ++ [CODE_COVERAGE_RULES_CHECK=' ++ @echo "Need to reconfigure with --enable-code-coverage" ++'] ++ CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" ++ CODE_COVERAGE_RULES_CLEAN='' ++ ]) ++ ++[CODE_COVERAGE_RULES=' ++# Code coverage ++# ++# Optional: ++# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. ++# Multiple directories may be specified, separated by whitespace. ++# (Default: $(top_builddir)) ++# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated ++# by lcov for code coverage. (Default: ++# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) ++# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage ++# reports to be created. (Default: ++# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) ++# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, ++# set to 0 to disable it and leave empty to stay with the default. ++# (Default: empty) ++# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov ++# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) ++# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov ++# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) ++# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov ++# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the ++# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) ++# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov ++# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) ++# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering ++# lcov instance. (Default: empty) ++# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov ++# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) ++# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the ++# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) ++# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml ++# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) ++# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore ++# ++# The generated report will be titled using the $(PACKAGE_NAME) and ++# $(PACKAGE_VERSION). In order to add the current git hash to the title, ++# use the git-version-gen script, available online. ++ ++# Optional variables ++CODE_COVERAGE_DIRECTORY ?= $(top_builddir) ++CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info ++CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage ++CODE_COVERAGE_BRANCH_COVERAGE ?= ++CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ++--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) ++CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) ++CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" ++CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) ++CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) ++CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= ++CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) ++CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ ++$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ++--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) ++CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) ++CODE_COVERAGE_IGNORE_PATTERN ?= ++ ++GITIGNOREFILES ?= ++GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) ++ ++code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) ++code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) ++code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ ++ $(CODE_COVERAGE_OUTPUT_FILE); ++code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) ++code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) ++code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ ++ $(CODE_COVERAGE_IGNORE_PATTERN); ++code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) ++code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) ++code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); ++code_coverage_quiet = $(code_coverage_quiet_$(V)) ++code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) ++code_coverage_quiet_0 = --quiet ++ ++# sanitizes the test-name: replaces with underscores: dashes and dots ++code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) ++ ++# Use recursive makes in order to ignore errors during check ++check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' ++ ++# Capture code coverage data ++code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' ++ ++# Hook rule executed before code-coverage-capture, overridable by the user ++code-coverage-capture-hook: ++ ++'"$CODE_COVERAGE_RULES_CLEAN"' ++ ++A''M_DISTCHECK_CONFIGURE_FLAGS ?= ++A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage ++ ++.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean ++'] ++ ++ AC_SUBST([CODE_COVERAGE_RULES]) ++ m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) ++]) +diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 +index c695a882e..17cc80462 100644 +--- a/config/zfs-build.m4 ++++ b/config/zfs-build.m4 +@@ -76,37 +76,6 @@ AC_DEFUN([ZFS_AC_DEBUGINFO], [ + AC_MSG_RESULT([$enable_debuginfo]) + ]) + +-AC_DEFUN([ZFS_AC_GCOV_KERNEL], [ +-]) +- +-AC_DEFUN([ZFS_AC_GCOV_USER], [ +- DEBUG_CFLAGS="$DEBUG_CFLAGS -fprofile-arcs -ftest-coverage" +-]) +- +-AC_DEFUN([ZFS_AC_GCOV], [ +- AC_MSG_CHECKING([whether gcov profiling will be enabled]) +- AC_ARG_ENABLE([gcov], +- [AS_HELP_STRING([--enable-gcov], +- [Enable gcov profiling @<:@default=no@:>@])], +- [], +- [enable_gcov=no]) +- +- AS_CASE(["x$enable_gcov"], +- ["xyes"], +- [ZFS_AC_GCOV_KERNEL +- ZFS_AC_GCOV_USER], +- ["xkernel"], +- [ZFS_AC_GCOV_KERNEL], +- ["xuser"], +- [ZFS_AC_GCOV_USER], +- ["xno"], +- [], +- [AC_MSG_ERROR([Unknown option $enable_gcov])]) +- +- AC_SUBST(DEBUG_CFLAGS) +- AC_MSG_RESULT([$enable_gcov]) +-]) +- + AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [ + ZFS_AC_CONFIG_ALWAYS_NO_UNUSED_BUT_SET_VARIABLE + ZFS_AC_CONFIG_ALWAYS_NO_BOOL_COMPARE +-- +2.14.2 + diff --git a/zfs-patches/0009-Update-codecov.yml.patch b/zfs-patches/0009-Update-codecov.yml.patch new file mode 100644 index 0000000..c5c67d9 --- /dev/null +++ b/zfs-patches/0009-Update-codecov.yml.patch @@ -0,0 +1,97 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Fri, 22 Sep 2017 18:54:34 -0700 +Subject: [PATCH] Update codecov.yml +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Update the codecov.yml to make the following functional changes. + +* Do not require the CI testing to pass before posting results. +* Set red-yellow-green coverage percent from 50%-100% +* Allow a 1% drop in coverage to still be considered a pass. +* Reduce the size of the comment posted to the issue. + +Additionally, the top level README.markdown has been updated +to include the codecov.io badge and the project summary reworded. + +Reviewed-by: Prakash Surya +Signed-off-by: Brian Behlendorf +Closes #6669 +(cherry picked from commit 3790bfa80f9b26fd750b4a554c5707b9d380aac4) +Signed-off-by: Fabian Grünbichler +--- + README.markdown | 12 ++++++------ + .github/codecov.yml | 31 ++++++++++++++++++++++++++----- + 2 files changed, 32 insertions(+), 11 deletions(-) + +diff --git a/README.markdown b/README.markdown +index fd2ca8c86..1c305b35d 100644 +--- a/README.markdown ++++ b/README.markdown +@@ -1,9 +1,9 @@ +-

+-ZFS is an advanced file system and volume manager which was originally +-developed for Solaris and is now maintained by the Illumos community. ++![img](http://zfsonlinux.org/images/zfs-linux.png) + +-ZFS on Linux, which is also known as ZoL, is currently feature complete. It +-includes fully functional and stable SPA, DMU, ZVOL, and ZPL layers. And it's native! ++ZFS on Linux is an advanced file system and volume manager which was originally ++developed for Solaris and is now maintained by the OpenZFS community. ++ ++[![codecov](https://codecov.io/gh/zfsonlinux/zfs/branch/master/graph/badge.svg)](https://codecov.io/gh/zfsonlinux/zfs) + + # Official Resources + * [Site](http://zfsonlinux.org) +@@ -16,4 +16,4 @@ Full documentation for installing ZoL on your favorite Linux distribution can + be found at [our site](http://zfsonlinux.org/). + + # Contribute & Develop +-We have a separate document with [contribution guidelines](./.github/CONTRIBUTING.md). +\ No newline at end of file ++We have a separate document with [contribution guidelines](./.github/CONTRIBUTING.md). +diff --git a/.github/codecov.yml b/.github/codecov.yml +index f36be39cb..e74c59a0f 100644 +--- a/.github/codecov.yml ++++ b/.github/codecov.yml +@@ -1,9 +1,30 @@ + codecov: +- strict_yaml_branch: master # only use the latest copy on master branch +- +-comment: off ++ notify: ++ require_ci_to_pass: no + + coverage: ++ precision: 2 ++ round: down ++ range: "50...100" ++ + status: +- project: off +- patch: off ++ project: ++ default: ++ threshold: 1% ++ ++ patch: ++ default: ++ threshold: 1% ++ ++parsers: ++ gcov: ++ branch_detection: ++ conditional: yes ++ loop: yes ++ method: no ++ macro: no ++ ++comment: ++ layout: "header, sunburst, diff" ++ behavior: default ++ require_changes: no +-- +2.14.2 + diff --git a/zfs-patches/0010-Fix-enable-code-coverage-debug-build.patch b/zfs-patches/0010-Fix-enable-code-coverage-debug-build.patch new file mode 100644 index 0000000..dd815d1 --- /dev/null +++ b/zfs-patches/0010-Fix-enable-code-coverage-debug-build.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Fri, 22 Sep 2017 22:16:18 -0700 +Subject: [PATCH] Fix "--enable-code-coverage" debug build +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When --enable-code-coverage is provided it should not result +in NDEBUG being defined. This is controlled by --enable-debug. + +Signed-off-by: Brian Behlendorf +Closes #6674 +(cherry picked from commit 6897ea475fd0c82a74edacf374d4e339f9a9b86b) +Signed-off-by: Fabian Grünbichler +--- + config/ax_code_coverage.m4 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/config/ax_code_coverage.m4 b/config/ax_code_coverage.m4 +index 6484f0332..4417d4444 100644 +--- a/config/ax_code_coverage.m4 ++++ b/config/ax_code_coverage.m4 +@@ -124,7 +124,7 @@ AC_DEFUN([AX_CODE_COVERAGE],[ + + dnl Build the code coverage flags + dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility +- CODE_COVERAGE_CPPFLAGS="-DNDEBUG" ++ CODE_COVERAGE_CPPFLAGS="" + CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_LIBS="-lgcov" +-- +2.14.2 + diff --git a/zfs-patches/0011-Remove-vn_rename-and-vn_remove-dependency.patch b/zfs-patches/0011-Remove-vn_rename-and-vn_remove-dependency.patch new file mode 100644 index 0000000..855cbb6 --- /dev/null +++ b/zfs-patches/0011-Remove-vn_rename-and-vn_remove-dependency.patch @@ -0,0 +1,153 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Thu, 19 Oct 2017 10:06:55 -0700 +Subject: [PATCH] Remove vn_rename and vn_remove dependency +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The only place vn_rename and vn_remove are used is when writing +out an updated pool configuration file. By truncating the file +instead of renaming and removing it we can avoid having to implement +these interfaces entirely. Functionally an empty cache file is +treated the same as a missing cache file. This is particularly +advantageous because the Linux kernel has never provided a way +to reliably implement vn_rename and vn_remove. + +The cachefile_004_pos.ksh test case was updated to understand +that an empty cache file is the same as a missing one. + +The zfs-import-* systemd service files were not updated to use +ConditionFileNotEmpty in place of ConditionPathExists. This +means that after exporting all pools and rebooting new pools +will not the scanned for on the next boot. This small change +should not impact normal usage since pools are not exported +as part of a normal shutdown. + +Documentation was updated accordingly. + +Reviewed-by: George Melikov +Reviewed-by: Arkadiusz Bubała +Signed-off-by: Brian Behlendorf +Closes zfsonlinux/spl#648 +Closes #6753 +(cherry picked from commit 5d62588032aa1d13d7f789cf564a0d20c77a5762) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/spa_config.c | 34 ++++++++++++++++++---- + man/man8/zpool.8 | 2 +- + .../functional/cachefile/cachefile_004_pos.ksh | 6 ++-- + 3 files changed, 32 insertions(+), 10 deletions(-) + +diff --git a/module/zfs/spa_config.c b/module/zfs/spa_config.c +index 5b792b868..fea239014 100644 +--- a/module/zfs/spa_config.c ++++ b/module/zfs/spa_config.c +@@ -147,6 +147,26 @@ out: + kobj_close_file(file); + } + ++static int ++spa_config_remove(spa_config_dirent_t *dp) ++{ ++#if defined(__linux__) && defined(_KERNEL) ++ int error, flags = FWRITE | FTRUNC; ++ uio_seg_t seg = UIO_SYSSPACE; ++ vnode_t *vp; ++ ++ error = vn_open(dp->scd_path, seg, flags, 0644, &vp, 0, 0); ++ if (error == 0) { ++ (void) VOP_FSYNC(vp, FSYNC, kcred, NULL); ++ (void) VOP_CLOSE(vp, 0, 1, 0, kcred, NULL); ++ } ++ ++ return (error); ++#else ++ return (vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE)); ++#endif ++} ++ + static int + spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) + { +@@ -161,7 +181,10 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) + * If the nvlist is empty (NULL), then remove the old cachefile. + */ + if (nvl == NULL) { +- err = vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE); ++ err = spa_config_remove(dp); ++ if (err == ENOENT) ++ err = 0; ++ + return (err); + } + +@@ -174,9 +197,9 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) + #if defined(__linux__) && defined(_KERNEL) + /* + * Write the configuration to disk. Due to the complexity involved +- * in performing a rename from within the kernel the file is truncated +- * and overwritten in place. In the event of an error the file is +- * unlinked to make sure we always have a consistent view of the data. ++ * in performing a rename and remove from within the kernel the file ++ * is instead truncated and overwritten in place. This way we always ++ * have a consistent view of the data or a zero length file. + */ + err = vn_open(dp->scd_path, UIO_SYSSPACE, oflags, 0644, &vp, 0, 0); + if (err == 0) { +@@ -186,9 +209,8 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) + err = VOP_FSYNC(vp, FSYNC, kcred, NULL); + + (void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL); +- + if (err) +- (void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE); ++ (void) spa_config_remove(dp); + } + #else + /* +diff --git a/man/man8/zpool.8 b/man/man8/zpool.8 +index 328ba3dce..22579101a 100644 +--- a/man/man8/zpool.8 ++++ b/man/man8/zpool.8 +@@ -655,7 +655,7 @@ Because the kernel destroys and recreates this file when pools are added and + removed, care should be taken when attempting to access this file. + When the last pool using a + .Sy cachefile +-is exported or destroyed, the file is removed. ++is exported or destroyed, the file will be empty. + .It Sy comment Ns = Ns Ar text + A text string consisting of printable ASCII characters that will be stored + such that it is available even if the pool becomes faulted. +diff --git a/tests/zfs-tests/tests/functional/cachefile/cachefile_004_pos.ksh b/tests/zfs-tests/tests/functional/cachefile/cachefile_004_pos.ksh +index ae54a9365..e0b81e166 100755 +--- a/tests/zfs-tests/tests/functional/cachefile/cachefile_004_pos.ksh ++++ b/tests/zfs-tests/tests/functional/cachefile/cachefile_004_pos.ksh +@@ -98,13 +98,13 @@ log_must zpool set cachefile=$CPATH2 $TESTPOOL1 + log_must pool_in_cache $TESTPOOL1 $CPATH2 + log_must zpool set cachefile=$CPATH2 $TESTPOOL2 + log_must pool_in_cache $TESTPOOL2 $CPATH2 +-if [[ -f $CPATH1 ]]; then ++if [[ -s $CPATH1 ]]; then + log_fail "Verify set when cachefile is set on pool." + fi + + log_must zpool export $TESTPOOL1 + log_must zpool export $TESTPOOL2 +-if [[ -f $CPATH2 ]]; then ++if [[ -s $CPATH2 ]]; then + log_fail "Verify export when cachefile is set on pool." + fi + +@@ -117,7 +117,7 @@ log_must pool_in_cache $TESTPOOL2 $CPATH2 + + log_must zpool destroy $TESTPOOL1 + log_must zpool destroy $TESTPOOL2 +-if [[ -f $CPATH2 ]]; then ++if [[ -s $CPATH2 ]]; then + log_fail "Verify destroy when cachefile is set on pool." + fi + +-- +2.14.2 + diff --git a/zfs-patches/0012-Fix-with-systemd-on-Debian-based-distributions-6963.patch b/zfs-patches/0012-Fix-with-systemd-on-Debian-based-distributions-6963.patch new file mode 100644 index 0000000..77f4db1 --- /dev/null +++ b/zfs-patches/0012-Fix-with-systemd-on-Debian-based-distributions-6963.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: LOLi +Date: Sun, 17 Dec 2017 23:08:48 +0100 +Subject: [PATCH] Fix --with-systemd on Debian-based distributions (#6963) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These changes propagate the "--with-systemd" configure option to the +RPM spec file, allowing Debian-based distributions to package +systemd-related files. + +Signed-off-by: Brian Behlendorf +Signed-off-by: loli10K +Closes #6591 +Closes #6963 +(cherry picked from commit 03658d5081c64e14898cc9be45da3305b27fac9e) +Signed-off-by: Fabian Grünbichler +--- + rpm/generic/zfs.spec.in | 2 +- + config/user-systemd.m4 | 20 ++++++++++++++++---- + config/zfs-build.m4 | 2 +- + 3 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/rpm/generic/zfs.spec.in b/rpm/generic/zfs.spec.in +index 8df57fa46..4a911b4c2 100644 +--- a/rpm/generic/zfs.spec.in ++++ b/rpm/generic/zfs.spec.in +@@ -87,11 +87,11 @@ BuildRequires: libblkid-devel + BuildRequires: libudev-devel + BuildRequires: libattr-devel + %endif ++ + %if 0%{?_systemd} + Requires(post): systemd + Requires(preun): systemd + Requires(postun): systemd +-BuildRequires: systemd + %endif + + # The zpool iostat/status -c scripts call some utilities like lsblk and iostat +diff --git a/config/user-systemd.m4 b/config/user-systemd.m4 +index c2105abce..de2a44f10 100644 +--- a/config/user-systemd.m4 ++++ b/config/user-systemd.m4 +@@ -2,7 +2,8 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_SYSTEMD], [ + AC_ARG_ENABLE(systemd, + AC_HELP_STRING([--enable-systemd], + [install systemd unit/preset files [[default: yes]]]), +- [],enable_systemd=yes) ++ [enable_systemd=$enableval], ++ [enable_systemd=check]) + + AC_ARG_WITH(systemdunitdir, + AC_HELP_STRING([--with-systemdunitdir=DIR], +@@ -19,16 +20,27 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_SYSTEMD], [ + [install systemd module load files into dir [[/usr/lib/modules-load.d]]]), + systemdmoduleloaddir=$withval,systemdmodulesloaddir=/usr/lib/modules-load.d) + ++ AS_IF([test "x$enable_systemd" = xcheck], [ ++ AS_IF([systemctl --version >/dev/null 2>&1], ++ [enable_systemd=yes], ++ [enable_systemd=no]) ++ ]) + +- AS_IF([test "x$enable_systemd" = xyes], +- [ ++ AC_MSG_CHECKING(for systemd support) ++ AC_MSG_RESULT([$enable_systemd]) ++ ++ AS_IF([test "x$enable_systemd" = xyes], [ + ZFS_INIT_SYSTEMD=systemd + ZFS_MODULE_LOAD=modules-load.d ++ DEFINE_SYSTEMD='--with systemd --define "_unitdir $(systemdunitdir)" --define "_presetdir $(systemdpresetdir)"' + modulesloaddir=$systemdmodulesloaddir +- ]) ++ ],[ ++ DEFINE_SYSTEMD='--without systemd' ++ ]) + + AC_SUBST(ZFS_INIT_SYSTEMD) + AC_SUBST(ZFS_MODULE_LOAD) ++ AC_SUBST(DEFINE_SYSTEMD) + AC_SUBST(systemdunitdir) + AC_SUBST(systemdpresetdir) + AC_SUBST(modulesloaddir) +diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 +index 17cc80462..5eaa49c87 100644 +--- a/config/zfs-build.m4 ++++ b/config/zfs-build.m4 +@@ -160,7 +160,7 @@ AC_DEFUN([ZFS_AC_RPM], [ + ]) + + RPM_DEFINE_COMMON='--define "$(DEBUG_ZFS) 1"' +- RPM_DEFINE_UTIL='--define "_dracutdir $(dracutdir)" --define "_udevdir $(udevdir)" --define "_udevruledir $(udevruledir)" --define "_initconfdir $(DEFAULT_INITCONF_DIR)" $(DEFINE_INITRAMFS)' ++ RPM_DEFINE_UTIL='--define "_dracutdir $(dracutdir)" --define "_udevdir $(udevdir)" --define "_udevruledir $(udevruledir)" --define "_initconfdir $(DEFAULT_INITCONF_DIR)" $(DEFINE_INITRAMFS) $(DEFINE_SYSTEMD)' + RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)" --define "require_spldir $(SPL)" --define "require_splobj $(SPL_OBJ)" --define "ksrc $(LINUX)" --define "kobj $(LINUX_OBJ)"' + RPM_DEFINE_DKMS= + +-- +2.14.2 + diff --git a/zfs-patches/0013-ZTS-Fix-create-o_ashift-test-case.patch b/zfs-patches/0013-ZTS-Fix-create-o_ashift-test-case.patch new file mode 100644 index 0000000..df72029 --- /dev/null +++ b/zfs-patches/0013-ZTS-Fix-create-o_ashift-test-case.patch @@ -0,0 +1,137 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: LOLi +Date: Tue, 19 Dec 2017 19:49:33 +0100 +Subject: [PATCH] ZTS: Fix create-o_ashift test case +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function that fills the uberblock ring buffer on every device label +has been reworked to avoid occasional failures caused by a race +condition that prevents 'zpool sync' from writing some uberblock +sequentially: this happens when the pool sync ioctl dispatch code calls +txg_wait_synced() while we're already waiting for a TXG to sync. + +Reviewed-by: Brian Behlendorf +Signed-off-by: loli10K +Closes #6924 +Closes #6977 +(cherry picked from commit 6c891ade8bee9c54484d5cf9b939582b7a9b7eeb) +Signed-off-by: Fabian Grünbichler +--- + cmd/zdb/zdb.c | 8 ++-- + .../cli_root/zpool_create/create-o_ashift.ksh | 47 ++++++++++------------ + 2 files changed, 26 insertions(+), 29 deletions(-) + +diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c +index 1097501e8..442685486 100644 +--- a/cmd/zdb/zdb.c ++++ b/cmd/zdb/zdb.c +@@ -2716,10 +2716,6 @@ dump_label(const char *dev) + exit(1); + } + +- if (ioctl(fd, BLKFLSBUF) != 0) +- (void) printf("failed to invalidate cache '%s' : %s\n", path, +- strerror(errno)); +- + if (fstat64_blk(fd, &statbuf) != 0) { + (void) printf("failed to stat '%s': %s\n", path, + strerror(errno)); +@@ -2727,6 +2723,10 @@ dump_label(const char *dev) + exit(1); + } + ++ if (S_ISBLK(statbuf.st_mode) && ioctl(fd, BLKFLSBUF) != 0) ++ (void) printf("failed to invalidate cache '%s' : %s\n", path, ++ strerror(errno)); ++ + avl_create(&config_tree, cksum_record_compare, + sizeof (cksum_record_t), offsetof(cksum_record_t, link)); + avl_create(&uberblock_tree, cksum_record_compare, +diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_create/create-o_ashift.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_create/create-o_ashift.ksh +index 6449c8a91..6a9c3e28c 100755 +--- a/tests/zfs-tests/tests/functional/cli_root/zpool_create/create-o_ashift.ksh ++++ b/tests/zfs-tests/tests/functional/cli_root/zpool_create/create-o_ashift.ksh +@@ -44,47 +44,45 @@ verify_runnable "global" + + function cleanup + { +- poolexists $TESTPOOL && destroy_pool $TESTPOOL ++ destroy_pool $TESTPOOL + log_must rm -f $disk + } + + # +-# Commit the specified number of TXGs to the provided pool +-# We use 'zpool sync' here because we can't force it via sync(1) like on illumos +-# $1 pool name +-# $2 number of txg syncs ++# Fill the uberblock ring in every label: we do this by committing ++# TXGs to the provided until every slot contains a valid uberblock. ++# NOTE: We use 'zpool sync' here because we can't force it via sync(1) like on ++# illumos + # +-function txg_sync ++function write_device_uberblocks # + { +- typeset pool=$1 +- typeset -i count=$2 +- typeset -i i=0; ++ typeset device=$1 ++ typeset pool=$2 + +- while [ $i -lt $count ] ++ while [ "$(zdb -quuul $device | grep -c 'invalid')" -ne 0 ] + do +- log_must sync_pool $pool true +- ((i = i + 1)) ++ sync_pool $pool true + done + } + + # +-# Verify device $1 labels contains $2 valid uberblocks in every label +-# $1 device +-# $2 uberblocks count ++# Verify every label on contains (valid) uberblocks + # +-function verify_device_uberblocks ++function verify_device_uberblocks # + { + typeset device=$1 + typeset ubcount=$2 + + zdb -quuul $device | egrep '^(\s+)?Uberblock' | +- egrep -v 'invalid$' | awk \ +- -v ubcount=$ubcount '{ uberblocks[$0]++; } +- END { for (i in uberblocks) { +- count++; +- if (uberblocks[i] != 4) { exit 1; } +- } +- if (count != ubcount) { exit 1; } }' ++ awk -v ubcount=$ubcount 'BEGIN { count=0 } { uberblocks[$0]++; } ++ END { ++ for (i in uberblocks) { ++ if (i ~ /invalid/) { continue; } ++ if (uberblocks[i] != 4) { exit 1; } ++ count++; ++ } ++ if (count != ubcount) { exit 1; } ++ }' + + return $? + } +@@ -110,8 +108,7 @@ do + log_fail "Pool was created without setting ashift value to "\ + "$ashift (current = $pprop)" + fi +- # force 128 txg sync to fill the uberblock ring +- txg_sync $TESTPOOL 128 ++ write_device_uberblocks $disk $TESTPOOL + verify_device_uberblocks $disk ${ubcount[$i]} + if [[ $? -ne 0 ]] + then +-- +2.14.2 + diff --git a/zfs-patches/0014-Emit-an-error-message-before-MMP-suspends-pool.patch b/zfs-patches/0014-Emit-an-error-message-before-MMP-suspends-pool.patch new file mode 100644 index 0000000..da521ef --- /dev/null +++ b/zfs-patches/0014-Emit-an-error-message-before-MMP-suspends-pool.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "John L. Hammond" <35266395+jhammond-intel@users.noreply.github.com> +Date: Wed, 17 Jan 2018 14:24:42 -0600 +Subject: [PATCH] Emit an error message before MMP suspends pool +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In mmp_thread(), emit an MMP specific error message before calling +zio_suspend() so that the administrator will understand why the pool +is being suspended. + +Reviewed-by: Olaf Faaland +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Signed-off-by: John L. Hammond +Closes #7048 +(cherry picked from commit ecc972c7f009e1fa75900e276a4c1306c55b5722) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/mmp.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c +index 6f2aa3f59..e91ae628a 100644 +--- a/module/zfs/mmp.c ++++ b/module/zfs/mmp.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -428,6 +429,10 @@ mmp_thread(spa_t *spa) + */ + if (!suspended && mmp_fail_intervals && multihost && + (start - mmp->mmp_last_write) > max_fail_ns) { ++ cmn_err(CE_WARN, "MMP writes to pool '%s' have not " ++ "succeeded in over %llus; suspending pool", ++ spa_name(spa), ++ NSEC2SEC(start - mmp->mmp_last_write)); + zio_suspend(spa, NULL); + } + +-- +2.14.2 + diff --git a/zfs-patches/0015-Fix-systemd_-RPM-macros-usage-on-Debian-based-distri.patch b/zfs-patches/0015-Fix-systemd_-RPM-macros-usage-on-Debian-based-distri.patch new file mode 100644 index 0000000..f41e862 --- /dev/null +++ b/zfs-patches/0015-Fix-systemd_-RPM-macros-usage-on-Debian-based-distri.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: LOLi +Date: Fri, 2 Feb 2018 22:50:42 +0100 +Subject: [PATCH] Fix systemd_ RPM macros usage on Debian-based distributions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Debian-based distributions do not seem to provide RPM macros for +dealing with systemd pre- and post- (un)install actions: this results +in errors when installing or upgrading .deb packages because the +resulting control scripts contain the following unresolved macros: + + * %systemd_post + * %systemd_preun + * %systemd_postun + +Fix this by providing default values for postinstall, preuninstall and +postuninstall scripts when these macros are not defined. + +Reviewed-by: Brian Behlendorf +Reviewed-by: Giuseppe Di Natale +Signed-off-by: loli10K +Closes #7074 +Closes #7100 +(cherry picked from commit 29b79dcfe90a67a919c2f42fbaa2e557ea484bd5) +Signed-off-by: Fabian Grünbichler +--- + rpm/generic/zfs.spec.in | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/rpm/generic/zfs.spec.in b/rpm/generic/zfs.spec.in +index 4a911b4c2..ce028794c 100644 +--- a/rpm/generic/zfs.spec.in ++++ b/rpm/generic/zfs.spec.in +@@ -245,8 +245,15 @@ find %{?buildroot}%{_libdir} -name '*.la' -exec rm -f {} \; + + %post + %if 0%{?_systemd} ++%if 0%{?systemd_post:1} + %systemd_post %{systemd_svcs} + %else ++if [ "$1" = "1" -o "$1" = "install" ] ; then ++ # Initial installation ++ systemctl preset %{systemd_svcs} >/dev/null || true ++fi ++%endif ++%else + if [ -x /sbin/chkconfig ]; then + /sbin/chkconfig --add zfs-import + /sbin/chkconfig --add zfs-mount +@@ -258,9 +265,17 @@ exit 0 + + %preun + %if 0%{?_systemd} ++%if 0%{?systemd_preun:1} + %systemd_preun %{systemd_svcs} + %else +-if [ "$1" = "0" ] && [ -x /sbin/chkconfig ]; then ++if [ "$1" = "0" -o "$1" = "remove" ] ; then ++ # Package removal, not upgrade ++ systemctl --no-reload disable %{systemd_svcs} >/dev/null || true ++ systemctl stop %{systemd_svcs} >/dev/null || true ++fi ++%endif ++%else ++if [ "$1" = "0" -o "$1" = "remove" ] && [ -x /sbin/chkconfig ]; then + /sbin/chkconfig --del zfs-import + /sbin/chkconfig --del zfs-mount + /sbin/chkconfig --del zfs-share +@@ -271,7 +286,11 @@ exit 0 + + %postun + %if 0%{?_systemd} ++%if 0%{?systemd_postun:1} + %systemd_postun %{systemd_svcs} ++%else ++systemctl --system daemon-reload >/dev/null || true ++%endif + %endif + + %files +-- +2.14.2 + diff --git a/zfs-patches/0016-Bug-fix-in-qat_compress.c-for-vmalloc-addr-check.patch b/zfs-patches/0016-Bug-fix-in-qat_compress.c-for-vmalloc-addr-check.patch new file mode 100644 index 0000000..34feeb1 --- /dev/null +++ b/zfs-patches/0016-Bug-fix-in-qat_compress.c-for-vmalloc-addr-check.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: wli5 +Date: Tue, 6 Feb 2018 02:26:27 +0800 +Subject: [PATCH] Bug fix in qat_compress.c for vmalloc addr check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Remove the unused vmalloc address check, and function mem_to_page +will handle the non-vmalloc address when map it to a physical +address. + +Reviewed-by: Brian Behlendorf +Signed-off-by: Weigang Li +Closes #7125 +(cherry picked from commit 5f38142e7b3a8994afef60faa2e65d72e7993807) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/qat_compress.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/module/zfs/qat_compress.c b/module/zfs/qat_compress.c +index 4d17d7ac9..62655f56d 100644 +--- a/module/zfs/qat_compress.c ++++ b/module/zfs/qat_compress.c +@@ -364,10 +364,6 @@ qat_compress(qat_compress_dir_t dir, char *src, int src_len, + Cpa32U dst_buffer_list_mem_size = sizeof (CpaBufferList) + + (num_dst_buf * sizeof (CpaFlatBuffer)); + +- if (!is_vmalloc_addr(src) || !is_vmalloc_addr(src + src_len - 1) || +- !is_vmalloc_addr(dst) || !is_vmalloc_addr(dst + dst_len - 1)) +- return (-1); +- + if (PHYS_CONTIG_ALLOC(&in_pages, + num_src_buf * sizeof (struct page *)) != CPA_STATUS_SUCCESS) + goto fail; +-- +2.14.2 + diff --git a/zfs-patches/0017-Fix-default-libdir-for-Debian-Ubuntu.patch b/zfs-patches/0017-Fix-default-libdir-for-Debian-Ubuntu.patch new file mode 100644 index 0000000..a6dbfd8 --- /dev/null +++ b/zfs-patches/0017-Fix-default-libdir-for-Debian-Ubuntu.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Mon, 5 Feb 2018 20:42:52 -0800 +Subject: [PATCH] Fix default libdir for Debian/Ubuntu +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The distribution provided architecture specific RPM macro files +for x86_64 and other architectures on Debian/Ubuntu specify the +wrong default libdir install location. When building deb packages +override _lib with the correct location. + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: loli10K +Reviewed by: George Melikov +Signed-off-by: Brian Behlendorf +Closes #7083 +Closes #7101 +(cherry picked from commit f1dde3fb20eb27c05b57ad82e0905a587ced8ee8) +Signed-off-by: Fabian Grünbichler +--- + config/zfs-build.m4 | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 +index 5eaa49c87..7c19cecd6 100644 +--- a/config/zfs-build.m4 ++++ b/config/zfs-build.m4 +@@ -164,6 +164,19 @@ AC_DEFUN([ZFS_AC_RPM], [ + RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)" --define "require_spldir $(SPL)" --define "require_splobj $(SPL_OBJ)" --define "ksrc $(LINUX)" --define "kobj $(LINUX_OBJ)"' + RPM_DEFINE_DKMS= + ++ dnl # Override default lib directory on Debian/Ubuntu systems. The provided ++ dnl # /usr/lib/rpm/platform//macros files do not specify the correct ++ dnl # path for multiarch systems as described by the packaging guidelines. ++ dnl # ++ dnl # https://wiki.ubuntu.com/MultiarchSpec ++ dnl # https://wiki.debian.org/Multiarch/Implementation ++ dnl # ++ AS_IF([test "$DEFAULT_PACKAGE" = "deb"], [ ++ MULTIARCH_LIBDIR="lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)" ++ RPM_DEFINE_UTIL+=' --define "_lib $(MULTIARCH_LIBDIR)"' ++ AC_SUBST(MULTIARCH_LIBDIR) ++ ]) ++ + SRPM_DEFINE_COMMON='--define "build_src_rpm 1"' + SRPM_DEFINE_UTIL= + SRPM_DEFINE_KMOD= +-- +2.14.2 + diff --git a/zfs-patches/0018-Remove-deprecated-zfs_arc_p_aggressive_disable.patch b/zfs-patches/0018-Remove-deprecated-zfs_arc_p_aggressive_disable.patch new file mode 100644 index 0000000..d83d4ab --- /dev/null +++ b/zfs-patches/0018-Remove-deprecated-zfs_arc_p_aggressive_disable.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Richard Elling +Date: Wed, 7 Feb 2018 11:54:20 -0800 +Subject: [PATCH] Remove deprecated zfs_arc_p_aggressive_disable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +zfs_arc_p_aggressive_disable is no more. This PR removes docs +and module parameters for zfs_arc_p_aggressive_disable. + +Reviewed-by: Giuseppe Di Natale +Reviewed by: George Melikov +Reviewed-by: Brian Behlendorf +Richard Elling +Closes #7135 + +(cherry picked from commit a58e1284d8998b0d7e409a6ec009d9d372aad41b) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/arc.c | 4 ---- + man/man5/zfs-module-parameters.5 | 11 ----------- + 2 files changed, 15 deletions(-) + +diff --git a/module/zfs/arc.c b/module/zfs/arc.c +index 264e67735..9d1d0db1d 100644 +--- a/module/zfs/arc.c ++++ b/module/zfs/arc.c +@@ -391,7 +391,6 @@ unsigned long zfs_arc_dnode_limit_percent = 10; + */ + unsigned long zfs_arc_sys_free = 0; + int zfs_arc_min_prefetch_lifespan = 0; +-int zfs_arc_p_aggressive_disable = 1; + int zfs_arc_p_dampener_disable = 1; + int zfs_arc_meta_prune = 10000; + int zfs_arc_meta_strategy = ARC_STRATEGY_META_BALANCED; +@@ -7928,9 +7927,6 @@ MODULE_PARM_DESC(zfs_arc_meta_strategy, "Meta reclaim strategy"); + module_param(zfs_arc_grow_retry, int, 0644); + MODULE_PARM_DESC(zfs_arc_grow_retry, "Seconds before growing arc size"); + +-module_param(zfs_arc_p_aggressive_disable, int, 0644); +-MODULE_PARM_DESC(zfs_arc_p_aggressive_disable, "disable aggressive arc_p grow"); +- + module_param(zfs_arc_p_dampener_disable, int, 0644); + MODULE_PARM_DESC(zfs_arc_p_dampener_disable, "disable arc_p adapt dampener"); + +diff --git a/man/man5/zfs-module-parameters.5 b/man/man5/zfs-module-parameters.5 +index 19e6becfd..d4daffde6 100644 +--- a/man/man5/zfs-module-parameters.5 ++++ b/man/man5/zfs-module-parameters.5 +@@ -674,17 +674,6 @@ max arc_p + Default value: \fB0\fR. + .RE + +-.sp +-.ne 2 +-.na +-\fBzfs_arc_p_aggressive_disable\fR (int) +-.ad +-.RS 12n +-Disable aggressive arc_p growth +-.sp +-Use \fB1\fR for yes (default) and \fB0\fR to disable. +-.RE +- + .sp + .ne 2 + .na +-- +2.14.2 + diff --git a/zfs-patches/0019-OpenZFS-8966-Source-file-zfs_acl.c-function-zfs_acls.patch b/zfs-patches/0019-OpenZFS-8966-Source-file-zfs_acl.c-function-zfs_acls.patch new file mode 100644 index 0000000..fc28cd8 --- /dev/null +++ b/zfs-patches/0019-OpenZFS-8966-Source-file-zfs_acl.c-function-zfs_acls.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: WHR +Date: Sun, 14 Jan 2018 23:57:54 +0300 +Subject: [PATCH] OpenZFS 8966 - Source file zfs_acl.c, function + zfs_aclset_common contains a use after end of the lifetime of a local + variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Authored by: WHR +Reviewed by: Matt Ahrens +Reviewed by: Andriy Gapon +Reviewed by: George Melikov +Reviewed by: Brian Behlendorf +Approved by: Richard Lowe +Ported-by: Giuseppe Di Natale + +OpenZFS-issue: https://www.illumos.org/issues/8966 +OpenZFS-commit: https://github.com/openzfs/openzfs/commit/c95549fcdc +Closes #7141 + +(cherry picked from commit a196b3bc3dcc14bda32b2fbed40d5e436319aca6) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/zfs_acl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/module/zfs/zfs_acl.c b/module/zfs/zfs_acl.c +index 7ddedeaaf..1fcfca0c7 100644 +--- a/module/zfs/zfs_acl.c ++++ b/module/zfs/zfs_acl.c +@@ -1323,6 +1323,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) + sa_bulk_attr_t bulk[5]; + uint64_t ctime[2]; + int count = 0; ++ zfs_acl_phys_t acl_phys; + + mode = zp->z_mode; + +@@ -1369,7 +1370,6 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) + } else { /* Painful legacy way */ + zfs_acl_node_t *aclnode; + uint64_t off = 0; +- zfs_acl_phys_t acl_phys; + uint64_t aoid; + + if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zfsvfs), +-- +2.14.2 + diff --git a/zfs-patches/0020-Linux-4.16-compat-inode_set_iversion.patch b/zfs-patches/0020-Linux-4.16-compat-inode_set_iversion.patch new file mode 100644 index 0000000..b73965d --- /dev/null +++ b/zfs-patches/0020-Linux-4.16-compat-inode_set_iversion.patch @@ -0,0 +1,145 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Thu, 8 Feb 2018 14:27:59 -0800 +Subject: [PATCH] Linux 4.16 compat: inode_set_iversion() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A new interface was added to manipulate the version field of an +inode. Add a inode_set_iversion() wrapper for older kernels and +use the new interface when available. + +The i_version field was dropped from the trace point due to the +switch to an atomic64_t i_version type. + +Reviewed-by: Olaf Faaland +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Chunwei Chen +Signed-off-by: Brian Behlendorf +Closes #7148 +(cherry picked from commit 310e63dfd18f59ad583631dfa2f55d40cedf1415) +Signed-off-by: Fabian Grünbichler +--- + include/linux/vfs_compat.h | 14 ++++++++++++++ + include/sys/trace_acl.h | 6 ++---- + module/zfs/zpl_super.c | 2 +- + config/kernel-inode-set-iversion.m4 | 19 +++++++++++++++++++ + config/kernel.m4 | 1 + + 5 files changed, 37 insertions(+), 5 deletions(-) + create mode 100644 config/kernel-inode-set-iversion.m4 + +diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h +index 6111f0afc..f51ff887d 100644 +--- a/include/linux/vfs_compat.h ++++ b/include/linux/vfs_compat.h +@@ -578,4 +578,18 @@ current_time(struct inode *ip) + } + #endif + ++/* ++ * 4.16 API change ++ * Added iversion interface for managing inode version field. ++ */ ++#ifdef HAVE_INODE_SET_IVERSION ++#include ++#else ++static inline void ++inode_set_iversion(struct inode *ip, u64 val) ++{ ++ ip->i_version = val; ++} ++#endif ++ + #endif /* _ZFS_VFS_H */ +diff --git a/include/sys/trace_acl.h b/include/sys/trace_acl.h +index 1057e560b..610bbe29c 100644 +--- a/include/sys/trace_acl.h ++++ b/include/sys/trace_acl.h +@@ -68,7 +68,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class, + __field(uint32_t, i_gid) + __field(unsigned long, i_ino) + __field(unsigned int, i_nlink) +- __field(u64, i_version) + __field(loff_t, i_size) + __field(unsigned int, i_blkbits) + __field(unsigned short, i_bytes) +@@ -103,7 +102,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class, + __entry->i_gid = KGID_TO_SGID(ZTOI(zn)->i_gid); + __entry->i_ino = zn->z_inode.i_ino; + __entry->i_nlink = zn->z_inode.i_nlink; +- __entry->i_version = zn->z_inode.i_version; + __entry->i_size = zn->z_inode.i_size; + __entry->i_blkbits = zn->z_inode.i_blkbits; + __entry->i_bytes = zn->z_inode.i_bytes; +@@ -121,7 +119,7 @@ DECLARE_EVENT_CLASS(zfs_ace_class, + "mapcnt %llu size %llu pflags %llu " + "sync_cnt %u mode 0x%x is_sa %d " + "is_mapped %d is_ctldir %d is_stale %d inode { " +- "uid %u gid %u ino %lu nlink %u version %llu size %lli " ++ "uid %u gid %u ino %lu nlink %u size %lli " + "blkbits %u bytes %u mode 0x%x generation %x } } " + "ace { type %u flags %u access_mask %u } mask_matched %u", + __entry->z_id, __entry->z_unlinked, __entry->z_atime_dirty, +@@ -131,7 +129,7 @@ DECLARE_EVENT_CLASS(zfs_ace_class, + __entry->z_is_sa, __entry->z_is_mapped, + __entry->z_is_ctldir, __entry->z_is_stale, __entry->i_uid, + __entry->i_gid, __entry->i_ino, __entry->i_nlink, +- __entry->i_version, __entry->i_size, __entry->i_blkbits, ++ __entry->i_size, __entry->i_blkbits, + __entry->i_bytes, __entry->i_mode, __entry->i_generation, + __entry->z_type, __entry->z_flags, __entry->z_access_mask, + __entry->mask_matched) +diff --git a/module/zfs/zpl_super.c b/module/zfs/zpl_super.c +index b6ef60277..25e75a897 100644 +--- a/module/zfs/zpl_super.c ++++ b/module/zfs/zpl_super.c +@@ -36,7 +36,7 @@ zpl_inode_alloc(struct super_block *sb) + struct inode *ip; + + VERIFY3S(zfs_inode_alloc(sb, &ip), ==, 0); +- ip->i_version = 1; ++ inode_set_iversion(ip, 1); + + return (ip); + } +diff --git a/config/kernel-inode-set-iversion.m4 b/config/kernel-inode-set-iversion.m4 +new file mode 100644 +index 000000000..9a7d7890e +--- /dev/null ++++ b/config/kernel-inode-set-iversion.m4 +@@ -0,0 +1,19 @@ ++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([ ++ #include ++ ],[ ++ struct inode inode; ++ inode_set_iversion(&inode, 1); ++ ],[ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_INODE_SET_IVERSION, 1, ++ [inode_set_iversion() exists]) ++ ],[ ++ AC_MSG_RESULT(no) ++ ]) ++]) +diff --git a/config/kernel.m4 b/config/kernel.m4 +index b759ccd39..b83f021e8 100644 +--- a/config/kernel.m4 ++++ b/config/kernel.m4 +@@ -65,6 +65,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ + ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL + ZFS_AC_KERNEL_INODE_OPERATIONS_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 +-- +2.14.2 + diff --git a/zfs-patches/0021-Linux-4.11-compat-avoid-refcount_t-name-conflict.patch b/zfs-patches/0021-Linux-4.11-compat-avoid-refcount_t-name-conflict.patch new file mode 100644 index 0000000..a1ee0c1 --- /dev/null +++ b/zfs-patches/0021-Linux-4.11-compat-avoid-refcount_t-name-conflict.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Thu, 8 Feb 2018 14:31:08 -0800 +Subject: [PATCH] Linux 4.11 compat: avoid refcount_t name conflict +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Related to commit 4859fe796, when directly using the kernel's +refcount functions in kernel compatibility code do not map +refcount_t to zfs_refcount_t. This leads to a type mismatch. + +Longer term we should consider renaming refcount_t to +zfs_refcount_t in the zfs code base. + +Reviewed-by: Olaf Faaland +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Chunwei Chen +Signed-off-by: Brian Behlendorf +Closes #7148 +(cherry picked from commit 3713b7333532f221733f7b74189d996359ed4311) +Signed-off-by: Fabian Grünbichler +--- + include/linux/vfs_compat.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h +index f51ff887d..7fcf3c055 100644 +--- a/include/linux/vfs_compat.h ++++ b/include/linux/vfs_compat.h +@@ -272,6 +272,10 @@ lseek_execute( + * This is several orders of magnitude larger than expected grace period. + * At 60 seconds the kernel will also begin issuing RCU stall warnings. + */ ++#ifdef refcount_t ++#undef refcount_t ++#endif ++ + #include + + #if defined(HAVE_POSIX_ACL_RELEASE) && !defined(HAVE_POSIX_ACL_RELEASE_GPL_ONLY) +@@ -397,6 +401,8 @@ typedef mode_t zpl_equivmode_t; + #define zpl_posix_acl_valid(ip, acl) posix_acl_valid(acl) + #endif + ++#define refcount_t zfs_refcount_t ++ + #endif /* CONFIG_FS_POSIX_ACL */ + + /* +-- +2.14.2 + diff --git a/zfs-patches/0022-Fix-zdb-c-traverse-stop-on-damaged-objset-root.patch b/zfs-patches/0022-Fix-zdb-c-traverse-stop-on-damaged-objset-root.patch new file mode 100644 index 0000000..7904043 --- /dev/null +++ b/zfs-patches/0022-Fix-zdb-c-traverse-stop-on-damaged-objset-root.patch @@ -0,0 +1,116 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chunwei Chen +Date: Tue, 30 Jan 2018 13:39:11 -0800 +Subject: [PATCH] Fix zdb -c traverse stop on damaged objset root +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If a corruption happens to be on a root block of an objset, zdb -c will +not correctly report the error, and it will not traverse the datasets +that come after. This is because traverse_visitbp, which does the +callback and reset error for TRAVERSE_HARD, is skipped when traversing +zil is failed in traverse_impl. + +Here's example of what 'zdb -eLcc' command looks like on a pool with +damaged objset root: + +== before patch: + +Traversing all blocks to verify checksums ... + +Error counts: + + errno count +block traversal size 379392 != alloc 33987072 (unreachable 33607680) + + bp count: 172 + ganged count: 0 + bp logical: 1678336 avg: 9757 + bp physical: 130560 avg: 759 compression: 12.85 + bp allocated: 379392 avg: 2205 compression: 4.42 + bp deduped: 0 ref>1: 0 deduplication: 1.00 + SPA allocated: 33987072 used: 0.80% + + additional, non-pointer bps of type 0: 71 + Dittoed blocks on same vdev: 101 + +== after patch: + +Traversing all blocks to verify checksums ... + +zdb_blkptr_cb: Got error 52 reading <54, 0, -1, 0> -- skipping + +Error counts: + + errno count + 52 1 +block traversal size 33963520 != alloc 33987072 (unreachable 23552) + + bp count: 447 + ganged count: 0 + bp logical: 36093440 avg: 80745 + bp physical: 33699840 avg: 75391 compression: 1.07 + bp allocated: 33963520 avg: 75981 compression: 1.06 + bp deduped: 0 ref>1: 0 deduplication: 1.00 + SPA allocated: 33987072 used: 0.80% + + additional, non-pointer bps of type 0: 76 + Dittoed blocks on same vdev: 115 + +== + +Reviewed-by: Brian Behlendorf +Reviewed-by: loli10K +Signed-off-by: Chunwei Chen +Closes #7099 +(cherry picked from commit 23227313a2016449176cbfcbae2d4fc463a2bc09) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/dmu_traverse.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/module/zfs/dmu_traverse.c b/module/zfs/dmu_traverse.c +index c78228d74..b494bef35 100644 +--- a/module/zfs/dmu_traverse.c ++++ b/module/zfs/dmu_traverse.c +@@ -599,19 +599,27 @@ traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp, + + /* See comment on ZIL traversal in dsl_scan_visitds. */ + if (ds != NULL && !ds->ds_is_snapshot && !BP_IS_HOLE(rootbp)) { ++ enum zio_flag zio_flags = ZIO_FLAG_CANFAIL; + uint32_t flags = ARC_FLAG_WAIT; + objset_phys_t *osp; + arc_buf_t *buf; + +- err = arc_read(NULL, td->td_spa, rootbp, +- arc_getbuf_func, &buf, +- ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, czb); +- if (err != 0) +- return (err); +- +- osp = buf->b_data; +- traverse_zil(td, &osp->os_zil_header); +- arc_buf_destroy(buf, &buf); ++ err = arc_read(NULL, td->td_spa, rootbp, arc_getbuf_func, ++ &buf, ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, czb); ++ if (err != 0) { ++ /* ++ * If both TRAVERSE_HARD and TRAVERSE_PRE are set, ++ * continue to visitbp so that td_func can be called ++ * in pre stage, and err will reset to zero. ++ */ ++ if (!(td->td_flags & TRAVERSE_HARD) || ++ !(td->td_flags & TRAVERSE_PRE)) ++ return (err); ++ } else { ++ osp = buf->b_data; ++ traverse_zil(td, &osp->os_zil_header); ++ arc_buf_destroy(buf, &buf); ++ } + } + + if (!(flags & TRAVERSE_PREFETCH_DATA) || +-- +2.14.2 + diff --git a/zfs-patches/0023-Fix-zle_decompress-out-of-bound-access.patch b/zfs-patches/0023-Fix-zle_decompress-out-of-bound-access.patch new file mode 100644 index 0000000..5345806 --- /dev/null +++ b/zfs-patches/0023-Fix-zle_decompress-out-of-bound-access.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chunwei Chen +Date: Thu, 1 Feb 2018 15:41:05 -0800 +Subject: [PATCH] Fix zle_decompress out of bound access +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Brian Behlendorf +Reviewed-by: loli10K +Signed-off-by: Chunwei Chen +Closes #7099 +(cherry picked from commit 5e566c57726226ceeca09b1eb19cb1c373622763) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/zle.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/module/zfs/zle.c b/module/zfs/zle.c +index 13c5673fb..613607faa 100644 +--- a/module/zfs/zle.c ++++ b/module/zfs/zle.c +@@ -74,10 +74,14 @@ zle_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n) + while (src < s_end && dst < d_end) { + int len = 1 + *src++; + if (len <= n) { ++ if (src + len > s_end || dst + len > d_end) ++ return (-1); + while (len-- != 0) + *dst++ = *src++; + } else { + len -= n; ++ if (dst + len > d_end) ++ return (-1); + while (len-- != 0) + *dst++ = 0; + } +-- +2.14.2 + diff --git a/zfs-patches/0024-Fix-racy-assignment-of-zcb.zcb_haderrors.patch b/zfs-patches/0024-Fix-racy-assignment-of-zcb.zcb_haderrors.patch new file mode 100644 index 0000000..ff489a3 --- /dev/null +++ b/zfs-patches/0024-Fix-racy-assignment-of-zcb.zcb_haderrors.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chunwei Chen +Date: Thu, 1 Feb 2018 15:42:41 -0800 +Subject: [PATCH] Fix racy assignment of zcb.zcb_haderrors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +zcb_haderrors will be modified in zdb_blkptr_done, which is +asynchronous. So we must move this assignment after zio_wait. + +Reviewed-by: Brian Behlendorf +Reviewed-by: loli10K +Signed-off-by: Chunwei Chen +Closes #7099 +(cherry picked from commit c797f0898ec11669427e2fc481118bc2e2d8ef3f) +Signed-off-by: Fabian Grünbichler +--- + cmd/zdb/zdb.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c +index 442685486..0cc1656a8 100644 +--- a/cmd/zdb/zdb.c ++++ b/cmd/zdb/zdb.c +@@ -3313,7 +3313,7 @@ dump_block_stats(spa_t *spa) + uint64_t norm_alloc, norm_space, total_alloc, total_found; + int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD; + boolean_t leaks = B_FALSE; +- int e, c; ++ int e, c, err; + bp_embedded_type_t i; + + (void) printf("\nTraversing all blocks %s%s%s%s%s...\n\n", +@@ -3354,7 +3354,7 @@ dump_block_stats(spa_t *spa) + + zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa)); + zcb.zcb_start = zcb.zcb_lastprint = gethrtime(); +- zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb); ++ err = traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb); + + /* + * If we've traversed the data blocks then we need to wait for those +@@ -3370,6 +3370,12 @@ dump_block_stats(spa_t *spa) + } + } + ++ /* ++ * Done after zio_wait() since zcb_haderrors is modified in ++ * zdb_blkptr_done() ++ */ ++ zcb.zcb_haderrors |= err; ++ + if (zcb.zcb_haderrors) { + (void) printf("\nError counts:\n\n"); + (void) printf("\t%5s %s\n", "errno", "count"); +-- +2.14.2 + diff --git a/zfs-patches/0025-Fix-zdb-R-decompression.patch b/zfs-patches/0025-Fix-zdb-R-decompression.patch new file mode 100644 index 0000000..3b1f895 --- /dev/null +++ b/zfs-patches/0025-Fix-zdb-R-decompression.patch @@ -0,0 +1,130 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chunwei Chen +Date: Thu, 1 Feb 2018 16:19:36 -0800 +Subject: [PATCH] Fix zdb -R decompression +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are some issues in the zdb -R decompression implementation. + +The first is that ZLE can easily decompress non-ZLE streams. So we add +ZDB_NO_ZLE env to make zdb skip ZLE. + +The second is the random bytes appended to pabd, pbuf2 stuff. This serve +no purpose at all, those bytes shouldn't be read during decompression +anyway. Instead, we randomize lbuf2, so that we can make sure +decompression fill exactly to lsize by bcmp lbuf and lbuf2. + +The last one is the condition to detect fail is wrong. + +Reviewed-by: Brian Behlendorf +Reviewed-by: loli10K +Signed-off-by: Chunwei Chen +Closes #7099 +Closes #4984 +(cherry picked from commit 18c662b84566cd34e6f6fb982d6a01a415a4e3cd) +Signed-off-by: Fabian Grünbichler +--- + cmd/zdb/zdb.c | 38 ++++++++++++++++++-------------------- + man/man8/zdb.8 | 4 +++- + 2 files changed, 21 insertions(+), 21 deletions(-) + +diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c +index 0cc1656a8..2d80589ca 100644 +--- a/cmd/zdb/zdb.c ++++ b/cmd/zdb/zdb.c +@@ -3895,13 +3895,6 @@ name: + return (NULL); + } + +-/* ARGSUSED */ +-static int +-random_get_pseudo_bytes_cb(void *buf, size_t len, void *unused) +-{ +- return (random_get_pseudo_bytes(buf, len)); +-} +- + /* + * Read a block from a pool and print it out. The syntax of the + * block descriptor is: +@@ -4064,17 +4057,8 @@ zdb_read_block(char *thing, spa_t *spa) + * every decompress function at every inflated blocksize. + */ + enum zio_compress c; +- void *pbuf2 = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL); + void *lbuf2 = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL); + +- abd_copy_to_buf(pbuf2, pabd, psize); +- +- VERIFY0(abd_iterate_func(pabd, psize, SPA_MAXBLOCKSIZE - psize, +- random_get_pseudo_bytes_cb, NULL)); +- +- VERIFY0(random_get_pseudo_bytes((uint8_t *)pbuf2 + psize, +- SPA_MAXBLOCKSIZE - psize)); +- + /* + * XXX - On the one hand, with SPA_MAXBLOCKSIZE at 16MB, + * this could take a while and we should let the user know +@@ -4084,13 +4068,29 @@ zdb_read_block(char *thing, spa_t *spa) + for (lsize = psize + SPA_MINBLOCKSIZE; + lsize <= SPA_MAXBLOCKSIZE; lsize += SPA_MINBLOCKSIZE) { + for (c = 0; c < ZIO_COMPRESS_FUNCTIONS; c++) { ++ /* ++ * ZLE can easily decompress non zle stream. ++ * So have an option to disable it. ++ */ ++ if (c == ZIO_COMPRESS_ZLE && ++ getenv("ZDB_NO_ZLE")) ++ continue; ++ + (void) fprintf(stderr, + "Trying %05llx -> %05llx (%s)\n", + (u_longlong_t)psize, (u_longlong_t)lsize, + zio_compress_table[c].ci_name); ++ ++ /* ++ * We randomize lbuf2, and decompress to both ++ * lbuf and lbuf2. This way, we will know if ++ * decompression fill exactly to lsize. ++ */ ++ VERIFY0(random_get_pseudo_bytes(lbuf2, lsize)); ++ + if (zio_decompress_data(c, pabd, + lbuf, psize, lsize) == 0 && +- zio_decompress_data_buf(c, pbuf2, ++ zio_decompress_data(c, pabd, + lbuf2, psize, lsize) == 0 && + bcmp(lbuf, lbuf2, lsize) == 0) + break; +@@ -4098,11 +4098,9 @@ zdb_read_block(char *thing, spa_t *spa) + if (c != ZIO_COMPRESS_FUNCTIONS) + break; + } +- +- umem_free(pbuf2, SPA_MAXBLOCKSIZE); + umem_free(lbuf2, SPA_MAXBLOCKSIZE); + +- if (lsize <= psize) { ++ if (lsize > SPA_MAXBLOCKSIZE) { + (void) printf("Decompress of %s failed\n", thing); + goto out; + } +diff --git a/man/man8/zdb.8 b/man/man8/zdb.8 +index 4e47de7be..d991aae4c 100644 +--- a/man/man8/zdb.8 ++++ b/man/man8/zdb.8 +@@ -246,7 +246,9 @@ and, optionally, + .It Sy b Ar offset + Print block pointer + .It Sy d +-Decompress the block ++Decompress the block. Set environment variable ++.Nm ZBD_NO_ZLE ++to skip zle when guessing. + .It Sy e + Byte swap the block + .It Sy g +-- +2.14.2 + diff --git a/zfs-patches/0026-Fix-zdb-E-segfault.patch b/zfs-patches/0026-Fix-zdb-E-segfault.patch new file mode 100644 index 0000000..ef0d242 --- /dev/null +++ b/zfs-patches/0026-Fix-zdb-E-segfault.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chunwei Chen +Date: Thu, 1 Feb 2018 16:28:11 -0800 +Subject: [PATCH] Fix zdb -E segfault +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +SPA_MAXBLOCKSIZE is too large for stack. + +Reviewed-by: Brian Behlendorf +Reviewed-by: loli10K +Signed-off-by: Chunwei Chen +Closes #7099 +(cherry picked from commit 31ff122aa2e20c7ed48617868085ddba7b4ad174) +Signed-off-by: Fabian Grünbichler +--- + cmd/zdb/zdb.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c +index 2d80589ca..90847d8d9 100644 +--- a/cmd/zdb/zdb.c ++++ b/cmd/zdb/zdb.c +@@ -4139,11 +4139,12 @@ zdb_embedded_block(char *thing) + { + blkptr_t bp; + unsigned long long *words = (void *)&bp; +- char buf[SPA_MAXBLOCKSIZE]; ++ char *buf; + int err; + +- memset(&bp, 0, sizeof (blkptr_t)); ++ buf = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL); + ++ bzero(&bp, sizeof (bp)); + err = sscanf(thing, "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx:" + "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx", + words + 0, words + 1, words + 2, words + 3, +@@ -4161,6 +4162,7 @@ zdb_embedded_block(char *thing) + exit(1); + } + zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0); ++ umem_free(buf, SPA_MAXBLOCKSIZE); + } + + int +-- +2.14.2 + diff --git a/zfs-patches/0027-Fix-zdb-ed-on-objset-for-exported-pool.patch b/zfs-patches/0027-Fix-zdb-ed-on-objset-for-exported-pool.patch new file mode 100644 index 0000000..e5edcd1 --- /dev/null +++ b/zfs-patches/0027-Fix-zdb-ed-on-objset-for-exported-pool.patch @@ -0,0 +1,217 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chunwei Chen +Date: Thu, 1 Feb 2018 16:36:40 -0800 +Subject: [PATCH] Fix zdb -ed on objset for exported pool +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +zdb -ed on objset for exported pool would failed with: + failed to own dataset 'qq/fs0': No such file or directory + +The reason is that zdb pass objset name to spa_import, it uses that +name to create a spa. Later, when dmu_objset_own tries to lookup the spa +using real pool name, it can't find one. + +We fix this by make sure we pass pool name rather than objset name to +spa_import. + +Reviewed-by: Brian Behlendorf +Reviewed-by: loli10K +Signed-off-by: Chunwei Chen +Closes #7099 +Closes #6464 +(cherry picked from commit 478754a8f5ff0f3b9f6dfe4ce272efc1681d243e) +Signed-off-by: Fabian Grünbichler +--- + .../tests/functional/cli_root/zdb/Makefile.am | 3 +- + cmd/zdb/zdb.c | 32 +++++++---- + tests/runfiles/linux.run | 2 +- + .../tests/functional/clean_mirror/cleanup.ksh | 4 +- + .../tests/functional/cli_root/zdb/zdb_006_pos.ksh | 64 ++++++++++++++++++++++ + 5 files changed, 90 insertions(+), 15 deletions(-) + create mode 100755 tests/zfs-tests/tests/functional/cli_root/zdb/zdb_006_pos.ksh + +diff --git a/tests/zfs-tests/tests/functional/cli_root/zdb/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zdb/Makefile.am +index 51170fbc8..d37bcf607 100644 +--- a/tests/zfs-tests/tests/functional/cli_root/zdb/Makefile.am ++++ b/tests/zfs-tests/tests/functional/cli_root/zdb/Makefile.am +@@ -4,4 +4,5 @@ dist_pkgdata_SCRIPTS = \ + zdb_002_pos.ksh \ + zdb_003_pos.ksh \ + zdb_004_pos.ksh \ +- zdb_005_pos.ksh ++ zdb_005_pos.ksh \ ++ zdb_006_pos.ksh +diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c +index 90847d8d9..17a0ae251 100644 +--- a/cmd/zdb/zdb.c ++++ b/cmd/zdb/zdb.c +@@ -4177,7 +4177,7 @@ main(int argc, char **argv) + int error = 0; + char **searchdirs = NULL; + int nsearch = 0; +- char *target; ++ char *target, *target_pool; + nvlist_t *policy = NULL; + uint64_t max_txg = UINT64_MAX; + int flags = ZFS_IMPORT_MISSING_LOG; +@@ -4380,6 +4380,20 @@ main(int argc, char **argv) + error = 0; + target = argv[0]; + ++ if (strpbrk(target, "/@") != NULL) { ++ size_t targetlen; ++ ++ target_pool = strdup(target); ++ *strpbrk(target_pool, "/@") = '\0'; ++ ++ target_is_spa = B_FALSE; ++ targetlen = strlen(target); ++ if (targetlen && target[targetlen - 1] == '/') ++ target[targetlen - 1] = '\0'; ++ } else { ++ target_pool = target; ++ } ++ + if (dump_opt['e']) { + importargs_t args = { 0 }; + nvlist_t *cfg = NULL; +@@ -4388,8 +4402,10 @@ main(int argc, char **argv) + args.path = searchdirs; + args.can_be_active = B_TRUE; + +- error = zpool_tryimport(g_zfs, target, &cfg, &args); ++ error = zpool_tryimport(g_zfs, target_pool, &cfg, &args); ++ + if (error == 0) { ++ + if (nvlist_add_nvlist(cfg, + ZPOOL_REWIND_POLICY, policy) != 0) { + fatal("can't open '%s': %s", +@@ -4404,19 +4420,13 @@ main(int argc, char **argv) + (void) printf("\nConfiguration for import:\n"); + dump_nvlist(cfg, 8); + } +- error = spa_import(target, cfg, NULL, ++ error = spa_import(target_pool, cfg, NULL, + flags | ZFS_IMPORT_SKIP_MMP); + } + } + +- if (strpbrk(target, "/@") != NULL) { +- size_t targetlen; +- +- target_is_spa = B_FALSE; +- targetlen = strlen(target); +- if (targetlen && target[targetlen - 1] == '/') +- target[targetlen - 1] = '\0'; +- } ++ if (target_pool != target) ++ free(target_pool); + + if (error == 0) { + if (target_is_spa || dump_opt['R']) { +diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run +index 303c27529..ea2dbb282 100644 +--- a/tests/runfiles/linux.run ++++ b/tests/runfiles/linux.run +@@ -73,7 +73,7 @@ tags = ['functional', 'clean_mirror'] + + [tests/functional/cli_root/zdb] + tests = ['zdb_001_neg', 'zdb_002_pos', 'zdb_003_pos', 'zdb_004_pos', +- 'zdb_005_pos'] ++ 'zdb_005_pos', 'zdb_006_pos'] + pre = + post = + tags = ['functional', 'cli_root', 'zdb'] +diff --git a/tests/zfs-tests/tests/functional/clean_mirror/cleanup.ksh b/tests/zfs-tests/tests/functional/clean_mirror/cleanup.ksh +index ac3bfbca8..fb0db312e 100755 +--- a/tests/zfs-tests/tests/functional/clean_mirror/cleanup.ksh ++++ b/tests/zfs-tests/tests/functional/clean_mirror/cleanup.ksh +@@ -38,10 +38,10 @@ df -F zfs -h | grep "$TESTFS " >/dev/null + [[ $? == 0 ]] && log_must zfs umount -f $TESTDIR + destroy_pool $TESTPOOL + +-if is_mpath_device $MIRROR_PRIMARY; then ++if ( is_mpath_device $MIRROR_PRIMARY || is_loop_device $MIRROR_SECONDARY); then + parted $DEV_DSKDIR/$MIRROR_PRIMARY -s rm 1 + fi +-if is_mpath_device $MIRROR_SECONDARY; then ++if ( is_mpath_device $MIRROR_SECONDARY || is_loop_device $MIRROR_SECONDARY); then + parted $DEV_DSKDIR/$MIRROR_SECONDARY -s rm 1 + fi + # recreate and destroy a zpool over the disks to restore the partitions to +diff --git a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_006_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_006_pos.ksh +new file mode 100755 +index 000000000..97b00e9e1 +--- /dev/null ++++ b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_006_pos.ksh +@@ -0,0 +1,64 @@ ++#!/bin/ksh ++ ++# ++# This file and its contents are supplied under the terms of the ++# Common Development and Distribution License ("CDDL"), version 1.0. ++# You may only use this file in accordance with the terms of version ++# 1.0 of the CDDL. ++# ++# A full copy of the text of the CDDL should have accompanied this ++# source. A copy of the CDDL is also available via the Internet at ++# http://www.illumos.org/license/CDDL. ++# ++ ++# ++# Copyright (c) 2018 by Nutanix. All rights reserved. ++# ++ ++. $STF_SUITE/include/libtest.shlib ++ ++# ++# Description: ++# zdb -d will work on imported/exported pool with pool/dataset argument ++# ++# Strategy: ++# 1. Create a pool ++# 2. Run zdb -d with pool and dataset arguments. ++# 3. Export the pool ++# 4. Run zdb -ed with pool and dataset arguments. ++# ++ ++function cleanup ++{ ++ datasetexists $TESTPOOL && destroy_pool $TESTPOOL ++ for DISK in $DISKS; do ++ zpool labelclear -f $DEV_RDSKDIR/$DISK ++ done ++} ++ ++log_assert "Verify zdb -d works on imported/exported pool with pool/dataset argument" ++log_onexit cleanup ++ ++verify_runnable "global" ++verify_disk_count "$DISKS" 2 ++ ++default_mirror_setup_noexit $DISKS ++log_must zfs snap $TESTPOOL/$TESTFS@snap ++ ++log_must zdb -d $TESTPOOL ++log_must zdb -d $TESTPOOL/ ++log_must zdb -d $TESTPOOL/$TESTFS ++log_must zdb -d $TESTPOOL/$TESTFS@snap ++ ++log_must zpool export $TESTPOOL ++ ++log_must zdb -ed $TESTPOOL ++log_must zdb -ed $TESTPOOL/ ++log_must zdb -ed $TESTPOOL/$TESTFS ++log_must zdb -ed $TESTPOOL/$TESTFS@snap ++ ++log_must zpool import $TESTPOOL ++ ++cleanup ++ ++log_pass "zdb -d works on imported/exported pool with pool/dataset argument" +-- +2.14.2 + diff --git a/zfs-patches/0028-Handle-zap_add-failures-in-mixed-case-mode.patch b/zfs-patches/0028-Handle-zap_add-failures-in-mixed-case-mode.patch new file mode 100644 index 0000000..94d0ca1 --- /dev/null +++ b/zfs-patches/0028-Handle-zap_add-failures-in-mixed-case-mode.patch @@ -0,0 +1,553 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: sanjeevbagewadi +Date: Fri, 9 Feb 2018 23:45:53 +0530 +Subject: [PATCH] Handle zap_add() failures in mixed case mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With "casesensitivity=mixed", zap_add() could fail when the number of +files/directories with the same name (varying in case) exceed the +capacity of the leaf node of a Fatzap. This results in a ASSERT() +failure as zfs_link_create() does not expect zap_add() to fail. The fix +is to handle these failures and rollback the transactions. + +Reviewed by: Matt Ahrens +Reviewed-by: Chunwei Chen +Reviewed-by: Brian Behlendorf +Signed-off-by: Sanjeev Bagewadi +Closes #7011 +Closes #7054 +(cherry picked from commit b3da003ebfad673bb4ada35f87a18a1ef175e95d) +Signed-off-by: Fabian Grünbichler +--- + .../tests/functional/casenorm/Makefile.am | 1 + + include/sys/zap_leaf.h | 15 ++- + module/zfs/zap.c | 25 +++- + module/zfs/zap_leaf.c | 2 +- + module/zfs/zap_micro.c | 38 +++++- + module/zfs/zfs_dir.c | 29 ++++- + module/zfs/zfs_vnops.c | 73 ++++++++--- + tests/runfiles/linux.run | 2 +- + .../functional/casenorm/mixed_create_failure.ksh | 136 +++++++++++++++++++++ + 9 files changed, 289 insertions(+), 32 deletions(-) + create mode 100755 tests/zfs-tests/tests/functional/casenorm/mixed_create_failure.ksh + +diff --git a/tests/zfs-tests/tests/functional/casenorm/Makefile.am b/tests/zfs-tests/tests/functional/casenorm/Makefile.am +index 00a19c7ff..00cb59074 100644 +--- a/tests/zfs-tests/tests/functional/casenorm/Makefile.am ++++ b/tests/zfs-tests/tests/functional/casenorm/Makefile.am +@@ -9,6 +9,7 @@ dist_pkgdata_SCRIPTS = \ + insensitive_formd_lookup.ksh \ + insensitive_none_delete.ksh \ + insensitive_none_lookup.ksh \ ++ mixed_create_failure.ksh \ + mixed_formd_delete.ksh \ + mixed_formd_lookup_ci.ksh \ + mixed_formd_lookup.ksh \ +diff --git a/include/sys/zap_leaf.h b/include/sys/zap_leaf.h +index e784c5963..a3da1036a 100644 +--- a/include/sys/zap_leaf.h ++++ b/include/sys/zap_leaf.h +@@ -46,10 +46,15 @@ struct zap_stats; + * block size (1<l_bs) - hash entry size (2) * number of hash + * entries - header space (2*chunksize) + */ +-#define ZAP_LEAF_NUMCHUNKS(l) \ +- (((1<<(l)->l_bs) - 2*ZAP_LEAF_HASH_NUMENTRIES(l)) / \ ++#define ZAP_LEAF_NUMCHUNKS_BS(bs) \ ++ (((1<<(bs)) - 2*ZAP_LEAF_HASH_NUMENTRIES_BS(bs)) / \ + ZAP_LEAF_CHUNKSIZE - 2) + ++#define ZAP_LEAF_NUMCHUNKS(l) (ZAP_LEAF_NUMCHUNKS_BS(((l)->l_bs))) ++ ++#define ZAP_LEAF_NUMCHUNKS_DEF \ ++ (ZAP_LEAF_NUMCHUNKS_BS(fzap_default_block_shift)) ++ + /* + * The amount of space within the chunk available for the array is: + * chunk size - space for type (1) - space for next pointer (2) +@@ -74,8 +79,10 @@ struct zap_stats; + * which is less than block size / CHUNKSIZE (24) / minimum number of + * chunks per entry (3). + */ +-#define ZAP_LEAF_HASH_SHIFT(l) ((l)->l_bs - 5) +-#define ZAP_LEAF_HASH_NUMENTRIES(l) (1 << ZAP_LEAF_HASH_SHIFT(l)) ++#define ZAP_LEAF_HASH_SHIFT_BS(bs) ((bs) - 5) ++#define ZAP_LEAF_HASH_NUMENTRIES_BS(bs) (1 << ZAP_LEAF_HASH_SHIFT_BS(bs)) ++#define ZAP_LEAF_HASH_SHIFT(l) (ZAP_LEAF_HASH_SHIFT_BS(((l)->l_bs))) ++#define ZAP_LEAF_HASH_NUMENTRIES(l) (ZAP_LEAF_HASH_NUMENTRIES_BS(((l)->l_bs))) + + /* + * The chunks start immediately after the hash table. The end of the +diff --git a/module/zfs/zap.c b/module/zfs/zap.c +index ee9962bff..9843d8c50 100644 +--- a/module/zfs/zap.c ++++ b/module/zfs/zap.c +@@ -819,15 +819,19 @@ fzap_lookup(zap_name_t *zn, + return (err); + } + ++#define MAX_EXPAND_RETRIES 2 ++ + int + fzap_add_cd(zap_name_t *zn, + uint64_t integer_size, uint64_t num_integers, + const void *val, uint32_t cd, void *tag, dmu_tx_t *tx) + { + zap_leaf_t *l; ++ zap_leaf_t *prev_l = NULL; + int err; + zap_entry_handle_t zeh; + zap_t *zap = zn->zn_zap; ++ int expand_retries = 0; + + ASSERT(RW_LOCK_HELD(&zap->zap_rwlock)); + ASSERT(!zap->zap_ismicro); +@@ -851,10 +855,29 @@ retry: + if (err == 0) { + zap_increment_num_entries(zap, 1, tx); + } else if (err == EAGAIN) { ++ /* ++ * If the last two expansions did not help, there is no point ++ * trying to expand again ++ */ ++ if (expand_retries > MAX_EXPAND_RETRIES && prev_l == l) { ++ err = SET_ERROR(ENOSPC); ++ goto out; ++ } ++ + err = zap_expand_leaf(zn, l, tag, tx, &l); + zap = zn->zn_zap; /* zap_expand_leaf() may change zap */ +- if (err == 0) ++ if (err == 0) { ++ prev_l = l; ++ expand_retries++; + goto retry; ++ } else if (err == ENOSPC) { ++ /* ++ * If we failed to expand the leaf, then bailout ++ * as there is no point trying ++ * zap_put_leaf_maybe_grow_ptrtbl(). ++ */ ++ return (err); ++ } + } + + out: +diff --git a/module/zfs/zap_leaf.c b/module/zfs/zap_leaf.c +index c342695c7..526e46606 100644 +--- a/module/zfs/zap_leaf.c ++++ b/module/zfs/zap_leaf.c +@@ -53,7 +53,7 @@ static uint16_t *zap_leaf_rehash_entry(zap_leaf_t *l, uint16_t entry); + ((h) >> \ + (64 - ZAP_LEAF_HASH_SHIFT(l) - zap_leaf_phys(l)->l_hdr.lh_prefix_len))) + +-#define LEAF_HASH_ENTPTR(l, h) (&zap_leaf_phys(l)->l_hash[LEAF_HASH(l, h)]) ++#define LEAF_HASH_ENTPTR(l, h) (&zap_leaf_phys(l)->l_hash[LEAF_HASH(l, h)]) + + extern inline zap_leaf_phys_t *zap_leaf_phys(zap_leaf_t *l); + +diff --git a/module/zfs/zap_micro.c b/module/zfs/zap_micro.c +index 3ebf995c6..34bef3e63 100644 +--- a/module/zfs/zap_micro.c ++++ b/module/zfs/zap_micro.c +@@ -363,6 +363,41 @@ mze_find_unused_cd(zap_t *zap, uint64_t hash) + return (cd); + } + ++/* ++ * Each mzap entry requires at max : 4 chunks ++ * 3 chunks for names + 1 chunk for value. ++ */ ++#define MZAP_ENT_CHUNKS (1 + ZAP_LEAF_ARRAY_NCHUNKS(MZAP_NAME_LEN) + \ ++ ZAP_LEAF_ARRAY_NCHUNKS(sizeof (uint64_t))) ++ ++/* ++ * Check if the current entry keeps the colliding entries under the fatzap leaf ++ * size. ++ */ ++static boolean_t ++mze_canfit_fzap_leaf(zap_name_t *zn, uint64_t hash) ++{ ++ zap_t *zap = zn->zn_zap; ++ mzap_ent_t mze_tofind; ++ mzap_ent_t *mze; ++ avl_index_t idx; ++ avl_tree_t *avl = &zap->zap_m.zap_avl; ++ uint32_t mzap_ents = 0; ++ ++ mze_tofind.mze_hash = hash; ++ mze_tofind.mze_cd = 0; ++ ++ for (mze = avl_find(avl, &mze_tofind, &idx); ++ mze && mze->mze_hash == hash; mze = AVL_NEXT(avl, mze)) { ++ mzap_ents++; ++ } ++ ++ /* Include the new entry being added */ ++ mzap_ents++; ++ ++ return (ZAP_LEAF_NUMCHUNKS_DEF > (mzap_ents * MZAP_ENT_CHUNKS)); ++} ++ + static void + mze_remove(zap_t *zap, mzap_ent_t *mze) + { +@@ -1191,7 +1226,8 @@ zap_add_impl(zap_t *zap, const char *key, + err = fzap_add(zn, integer_size, num_integers, val, tag, tx); + zap = zn->zn_zap; /* fzap_add() may change zap */ + } else if (integer_size != 8 || num_integers != 1 || +- strlen(key) >= MZAP_NAME_LEN) { ++ strlen(key) >= MZAP_NAME_LEN || ++ !mze_canfit_fzap_leaf(zn, zn->zn_hash)) { + err = mzap_upgrade(&zn->zn_zap, tag, tx, 0); + if (err == 0) { + err = fzap_add(zn, integer_size, num_integers, val, +diff --git a/module/zfs/zfs_dir.c b/module/zfs/zfs_dir.c +index 9a8bbccd9..6398a1d15 100644 +--- a/module/zfs/zfs_dir.c ++++ b/module/zfs/zfs_dir.c +@@ -742,7 +742,11 @@ zfs_dirent(znode_t *zp, uint64_t mode) + } + + /* +- * Link zp into dl. Can only fail if zp has been unlinked. ++ * Link zp into dl. Can fail in the following cases : ++ * - if zp has been unlinked. ++ * - if the number of entries with the same hash (aka. colliding entries) ++ * exceed the capacity of a leaf-block of fatzap and splitting of the ++ * leaf-block does not help. + */ + int + zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag) +@@ -776,6 +780,24 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag) + NULL, &links, sizeof (links)); + } + } ++ ++ value = zfs_dirent(zp, zp->z_mode); ++ error = zap_add(ZTOZSB(zp)->z_os, dzp->z_id, dl->dl_name, 8, 1, ++ &value, tx); ++ ++ /* ++ * zap_add could fail to add the entry if it exceeds the capacity of the ++ * leaf-block and zap_leaf_split() failed to help. ++ * The caller of this routine is responsible for failing the transaction ++ * which will rollback the SA updates done above. ++ */ ++ if (error != 0) { ++ if (!(flag & ZRENAMING) && !(flag & ZNEW)) ++ drop_nlink(ZTOI(zp)); ++ mutex_exit(&zp->z_lock); ++ return (error); ++ } ++ + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, + &dzp->z_id, sizeof (dzp->z_id)); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, +@@ -813,11 +835,6 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag) + ASSERT(error == 0); + mutex_exit(&dzp->z_lock); + +- value = zfs_dirent(zp, zp->z_mode); +- error = zap_add(ZTOZSB(zp)->z_os, dzp->z_id, dl->dl_name, +- 8, 1, &value, tx); +- ASSERT(error == 0); +- + return (0); + } + +diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c +index 6f6ce79db..8a7ad702c 100644 +--- a/module/zfs/zfs_vnops.c ++++ b/module/zfs/zfs_vnops.c +@@ -1443,10 +1443,22 @@ top: + } + zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids); + ++ error = zfs_link_create(dl, zp, tx, ZNEW); ++ if (error != 0) { ++ /* ++ * Since, we failed to add the directory entry for it, ++ * delete the newly created dnode. ++ */ ++ zfs_znode_delete(zp, tx); ++ remove_inode_hash(ZTOI(zp)); ++ zfs_acl_ids_free(&acl_ids); ++ dmu_tx_commit(tx); ++ goto out; ++ } ++ + if (fuid_dirtied) + zfs_fuid_sync(zfsvfs, tx); + +- (void) zfs_link_create(dl, zp, tx, ZNEW); + txtype = zfs_log_create_txtype(Z_FILE, vsecp, vap); + if (flag & FIGNORECASE) + txtype |= TX_CI; +@@ -2037,13 +2049,18 @@ top: + */ + zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids); + +- if (fuid_dirtied) +- zfs_fuid_sync(zfsvfs, tx); +- + /* + * Now put new name in parent dir. + */ +- (void) zfs_link_create(dl, zp, tx, ZNEW); ++ error = zfs_link_create(dl, zp, tx, ZNEW); ++ if (error != 0) { ++ zfs_znode_delete(zp, tx); ++ remove_inode_hash(ZTOI(zp)); ++ goto out; ++ } ++ ++ if (fuid_dirtied) ++ zfs_fuid_sync(zfsvfs, tx); + + *ipp = ZTOI(zp); + +@@ -2053,6 +2070,7 @@ top: + zfs_log_create(zilog, tx, txtype, dzp, zp, dirname, vsecp, + acl_ids.z_fuidp, vap); + ++out: + zfs_acl_ids_free(&acl_ids); + + dmu_tx_commit(tx); +@@ -2062,10 +2080,14 @@ top: + if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + zil_commit(zilog, 0); + +- zfs_inode_update(dzp); +- zfs_inode_update(zp); ++ if (error != 0) { ++ iput(ZTOI(zp)); ++ } else { ++ zfs_inode_update(dzp); ++ zfs_inode_update(zp); ++ } + ZFS_EXIT(zfsvfs); +- return (0); ++ return (error); + } + + /* +@@ -3683,6 +3705,13 @@ top: + VERIFY3U(zfs_link_destroy(tdl, szp, tx, + ZRENAMING, NULL), ==, 0); + } ++ } else { ++ /* ++ * If we had removed the existing target, subsequent ++ * call to zfs_link_create() to add back the same entry ++ * but, the new dnode (szp) should not fail. ++ */ ++ ASSERT(tzp == NULL); + } + } + +@@ -3853,14 +3882,18 @@ top: + /* + * Insert the new object into the directory. + */ +- (void) zfs_link_create(dl, zp, tx, ZNEW); +- +- if (flags & FIGNORECASE) +- txtype |= TX_CI; +- zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link); ++ error = zfs_link_create(dl, zp, tx, ZNEW); ++ if (error != 0) { ++ zfs_znode_delete(zp, tx); ++ remove_inode_hash(ZTOI(zp)); ++ } else { ++ if (flags & FIGNORECASE) ++ txtype |= TX_CI; ++ zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link); + +- zfs_inode_update(dzp); +- zfs_inode_update(zp); ++ zfs_inode_update(dzp); ++ zfs_inode_update(zp); ++ } + + zfs_acl_ids_free(&acl_ids); + +@@ -3868,10 +3901,14 @@ top: + + zfs_dirent_unlock(dl); + +- *ipp = ZTOI(zp); ++ if (error == 0) { ++ *ipp = ZTOI(zp); + +- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) +- zil_commit(zilog, 0); ++ if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) ++ zil_commit(zilog, 0); ++ } else { ++ iput(ZTOI(zp)); ++ } + + ZFS_EXIT(zfsvfs); + return (error); +diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run +index ea2dbb282..8be3e1c62 100644 +--- a/tests/runfiles/linux.run ++++ b/tests/runfiles/linux.run +@@ -55,7 +55,7 @@ tags = ['functional', 'cachefile'] + # 'mixed_none_lookup', 'mixed_none_lookup_ci', 'mixed_none_delete', + # 'mixed_formd_lookup', 'mixed_formd_lookup_ci', 'mixed_formd_delete'] + [tests/functional/casenorm] +-tests = ['case_all_values', 'norm_all_values'] ++tests = ['case_all_values', 'norm_all_values', 'mixed_create_failure'] + tags = ['functional', 'casenorm'] + + [tests/functional/chattr] +diff --git a/tests/zfs-tests/tests/functional/casenorm/mixed_create_failure.ksh b/tests/zfs-tests/tests/functional/casenorm/mixed_create_failure.ksh +new file mode 100755 +index 000000000..51b5bb3f6 +--- /dev/null ++++ b/tests/zfs-tests/tests/functional/casenorm/mixed_create_failure.ksh +@@ -0,0 +1,136 @@ ++#!/bin/ksh -p ++# ++# ++# This file and its contents are supplied under the terms of the ++# Common Development and Distribution License ("CDDL"), version 1.0. ++# You may only use this file in accordance with the terms of version ++# 1.0 of the CDDL. ++# ++# A full copy of the text of the CDDL should have accompanied this ++# source. A copy of the CDDL is also available via the Internet at ++# http://www.illumos.org/license/CDDL. ++# ++# ++# Copyright 2018 Nutanix Inc. All rights reserved. ++# ++ ++. $STF_SUITE/tests/functional/casenorm/casenorm.kshlib ++ ++# DESCRIPTION: ++# For the filesystem with casesensitivity=mixed, normalization=none, ++# when multiple files with the same name (differing only in case) are created, ++# the number of files is limited to what can fit in a fatzap leaf-block. ++# And beyond that, it fails with ENOSPC. ++# ++# Ensure that the create/rename operations fail gracefully and not trigger an ++# ASSERT. ++# ++# STRATEGY: ++# Repeat the below steps for objects: files, directories, symlinks and hardlinks ++# 1. Create objects with same name but varying in case. ++# E.g. 'abcdefghijklmnop', 'Abcdefghijklmnop', 'ABcdefghijklmnop' etc. ++# The create should fail with ENOSPC. ++# 2. Create an object with name 'tmp_obj' and try to rename it to name that we ++# failed to add in step 1 above. ++# This should fail as well. ++ ++verify_runnable "global" ++ ++function cleanup ++{ ++ destroy_testfs ++} ++ ++log_onexit cleanup ++log_assert "With mixed mode: ensure create fails with ENOSPC beyond a certain limit" ++ ++create_testfs "-o casesensitivity=mixed -o normalization=none" ++ ++# Different object types ++obj_type=('file' 'dir' 'symlink' 'hardlink') ++ ++# Commands to create different object types ++typeset -A ops ++ops['file']='touch' ++ops['dir']='mkdir' ++ops['symlink']='ln -s' ++ops['hardlink']='ln' ++ ++# This function tests the following for a give object type : ++# - Create multiple objects with the same name (varying only in case). ++# Ensure that it eventually fails once the leaf-block limit is exceeded. ++# - Create another object with a different name. And attempt rename it to the ++# name (for which the create had failed in the previous step). ++# This should fail as well. ++# Args : ++# $1 - object type (file/dir/symlink/hardlink) ++# $2 - test directory ++# ++function test_ops ++{ ++ typeset obj_type=$1 ++ typeset testdir=$2 ++ ++ target_obj='target-file' ++ ++ op="${ops[$obj_type]}" ++ ++ log_note "The op : $op" ++ log_note "testdir=$testdir obj_type=$obj_type" ++ ++ test_path="$testdir/$obj_type" ++ mkdir $test_path ++ log_note "Created test dir $test_path" ++ ++ if [[ $obj_type = "symlink" || $obj_type = "hardlink" ]]; then ++ touch $test_path/$target_obj ++ log_note "Created target: $test_path/$target_obj" ++ op="$op $test_path/$target_obj" ++ fi ++ ++ log_note "op : $op" ++ names='{a,A}{b,B}{c,C}{d,D}{e,E}{f,F}{g,G}{h,H}{i,I}{j,J}{k,K}{l,L}' ++ for name in $names; do ++ cmd="$op $test_path/$name" ++ out=$($cmd 2>&1) ++ ret=$? ++ log_note "cmd: $cmd ret: $ret out=$out" ++ if (($ret != 0)); then ++ if [[ $out = *@(No space left on device)* ]]; then ++ save_name="$test_path/$name" ++ break; ++ else ++ log_err "$cmd failed with unexpected error : $out" ++ fi ++ fi ++ done ++ ++ log_note 'Test rename \"sample_name\" rename' ++ TMP_OBJ="$test_path/tmp_obj" ++ cmd="$op $TMP_OBJ" ++ out=$($cmd 2>&1) ++ ret=$? ++ if (($ret != 0)); then ++ log_err "cmd:$cmd failed out:$out" ++ fi ++ ++ # Now, try to rename the tmp_obj to the name which we failed to add earlier. ++ # This should fail as well. ++ out=$(mv $TMP_OBJ $save_name 2>&1) ++ ret=$? ++ if (($ret != 0)); then ++ if [[ $out = *@(No space left on device)* ]]; then ++ log_note "$cmd failed as expected : $out" ++ else ++ log_err "$cmd failed with : $out" ++ fi ++ fi ++} ++ ++for obj_type in ${obj_type[*]}; ++do ++ log_note "Testing create of $obj_type" ++ test_ops $obj_type $TESTDIR ++done ++ ++log_pass "Mixed mode FS: Ops on large number of colliding names fail gracefully" +-- +2.14.2 + diff --git a/zfs-patches/0029-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch b/zfs-patches/0029-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch new file mode 100644 index 0000000..87c2f04 --- /dev/null +++ b/zfs-patches/0029-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: sanjeevbagewadi +Date: Tue, 13 Feb 2018 01:00:38 +0530 +Subject: [PATCH] mmp should use a fixed tag for spa_config locks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +mmp_write_uberblock() and mmp_write_done() should the same tag +for spa_config_locks. + +Reviewed-by: Olaf Faaland +Reviewed-by: Giuseppe Di Natale +Reviewed by: Brian Behlendorf +Signed-off-by: Sanjeev Bagewadi +Closes #6530 +Closes #7155 +(cherry picked from commit d85011ed696b41f4de963f7932dfb53ea871278b) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/mmp.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c +index e91ae628a..1dfb7c05b 100644 +--- a/module/zfs/mmp.c ++++ b/module/zfs/mmp.c +@@ -125,6 +125,7 @@ uint_t zfs_multihost_import_intervals = MMP_DEFAULT_IMPORT_INTERVALS; + uint_t zfs_multihost_fail_intervals = MMP_DEFAULT_FAIL_INTERVALS; + + static void mmp_thread(spa_t *spa); ++char *mmp_tag = "mmp_write_uberblock"; + + void + mmp_init(spa_t *spa) +@@ -278,7 +279,7 @@ mmp_write_done(zio_t *zio) + + unlock: + mutex_exit(&mts->mmp_io_lock); +- spa_config_exit(spa, SCL_STATE, FTAG); ++ spa_config_exit(spa, SCL_STATE, mmp_tag); + + abd_free(zio->io_abd); + } +@@ -314,7 +315,7 @@ mmp_write_uberblock(spa_t *spa) + int label; + uint64_t offset; + +- spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); ++ spa_config_enter(spa, SCL_STATE, mmp_tag, RW_READER); + vd = mmp_random_leaf(spa->spa_root_vdev); + if (vd == NULL) { + spa_config_exit(spa, SCL_STATE, FTAG); +-- +2.14.2 + diff --git a/zfs-patches/0030-contrib-initramfs-add-missing-conf.d-zfs.patch b/zfs-patches/0030-contrib-initramfs-add-missing-conf.d-zfs.patch new file mode 100644 index 0000000..ec7ce71 --- /dev/null +++ b/zfs-patches/0030-contrib-initramfs-add-missing-conf.d-zfs.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: LOLi +Date: Mon, 12 Feb 2018 20:40:00 +0100 +Subject: [PATCH] contrib/initramfs: add missing conf.d/zfs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When upgrading from the distribution-provided zfs-initramfs package on +root-on-zfs Ubuntu and Debian the system may fail to boot: this change +adds the missing initramfs configuration file. + +Reviewed-by: Brian Behlendorf +Reviewed-by: Richard Laager +Signed-off-by: loli10K +Closes #7158 +(cherry picked from commit a9ff89e05cd2f420e44b0e50c92d97c166772d2b) +Signed-off-by: Fabian Grünbichler +--- + contrib/initramfs/Makefile.am | 6 ++++-- + contrib/initramfs/conf.d/zfs | 8 ++++++++ + 2 files changed, 12 insertions(+), 2 deletions(-) + create mode 100644 contrib/initramfs/conf.d/zfs + +diff --git a/contrib/initramfs/Makefile.am b/contrib/initramfs/Makefile.am +index 998e588ab..b22940821 100644 +--- a/contrib/initramfs/Makefile.am ++++ b/contrib/initramfs/Makefile.am +@@ -1,8 +1,10 @@ + initrddir = $(datarootdir)/initramfs-tools + +-initrd_SCRIPTS = conf-hooks.d/zfs hooks/zfs scripts/zfs scripts/local-top/zfs ++initrd_SCRIPTS = \ ++ conf.d/zfs conf-hooks.d/zfs hooks/zfs scripts/zfs scripts/local-top/zfs + + EXTRA_DIST = \ ++ $(top_srcdir)/contrib/initramfs/conf.d/zfs \ + $(top_srcdir)/contrib/initramfs/conf-hooks.d/zfs \ + $(top_srcdir)/contrib/initramfs/hooks/zfs \ + $(top_srcdir)/contrib/initramfs/scripts/zfs \ +@@ -10,7 +12,7 @@ EXTRA_DIST = \ + $(top_srcdir)/contrib/initramfs/README.initramfs.markdown + + install-initrdSCRIPTS: $(EXTRA_DIST) +- for d in conf-hooks.d hooks scripts scripts/local-top; do \ ++ for d in conf.d conf-hooks.d hooks scripts scripts/local-top; do \ + $(MKDIR_P) $(DESTDIR)$(initrddir)/$$d; \ + cp $(top_srcdir)/contrib/initramfs/$$d/zfs \ + $(DESTDIR)$(initrddir)/$$d/; \ +diff --git a/contrib/initramfs/conf.d/zfs b/contrib/initramfs/conf.d/zfs +new file mode 100644 +index 000000000..c67d75ba8 +--- /dev/null ++++ b/contrib/initramfs/conf.d/zfs +@@ -0,0 +1,8 @@ ++for x in $(cat /proc/cmdline) ++do ++ case $x in ++ root=ZFS=*|root=zfs:*) ++ BOOT=zfs ++ ;; ++ esac ++done +-- +2.14.2 + diff --git a/zfs-patches/0031-zfs-receive-fails-with-dataset-is-busy.patch b/zfs-patches/0031-zfs-receive-fails-with-dataset-is-busy.patch new file mode 100644 index 0000000..bae187b --- /dev/null +++ b/zfs-patches/0031-zfs-receive-fails-with-dataset-is-busy.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: LOLi +Date: Mon, 12 Feb 2018 21:28:59 +0100 +Subject: [PATCH] 'zfs receive' fails with "dataset is busy" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Receiving an incremental stream after an interrupted "zfs receive -s" +fails with the message "dataset is busy": this is because we still have +the hidden clone ../%recv from the resumable receive. + +Improve the error message suggesting the existence of a partially +complete resumable stream from "zfs receive -s" which can be either +aborted ("zfs receive -A") or resumed ("zfs send -t"). + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Reviewed-by: George Melikov +Signed-off-by: loli10K +Closes #7129 +Closes #7154 +(cherry picked from commit 1d805a534b5e1768413a0242b8e92b97cb1a796c) +Signed-off-by: Fabian Grünbichler +--- + cmd/zfs/zfs_main.c | 2 +- + lib/libzfs/libzfs_sendrecv.c | 18 +++++++++++++++++- + 2 files changed, 18 insertions(+), 2 deletions(-) + +diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c +index e8fe6a9fa..f57df8581 100644 +--- a/cmd/zfs/zfs_main.c ++++ b/cmd/zfs/zfs_main.c +@@ -6072,7 +6072,7 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol, + + (void) fprintf(stderr, gettext("cannot %s '%s': " + "Contains partially-completed state from " +- "\"zfs receive -r\", which can be resumed with " ++ "\"zfs receive -s\", which can be resumed with " + "\"zfs send -t\"\n"), + cmdname, zfs_get_name(zhp)); + return (1); +diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c +index ec190022f..66d89067b 100644 +--- a/lib/libzfs/libzfs_sendrecv.c ++++ b/lib/libzfs/libzfs_sendrecv.c +@@ -3254,6 +3254,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, + zfs_type_t type; + boolean_t toplevel = B_FALSE; + boolean_t zoned = B_FALSE; ++ boolean_t hastoken = B_FALSE; + + begin_time = time(NULL); + bzero(origin, MAXNAMELEN); +@@ -3535,6 +3536,11 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, + /* we want to know if we're zoned when validating -o|-x props */ + zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED); + ++ /* may need this info later, get it now we have zhp around */ ++ if (zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN, NULL, 0, ++ NULL, NULL, 0, B_TRUE) == 0) ++ hastoken = B_TRUE; ++ + /* gather existing properties on destination */ + origprops = fnvlist_alloc(); + fnvlist_merge(origprops, zhp->zfs_props); +@@ -3741,9 +3747,19 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, + break; + case EDQUOT: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, +- "destination %s space quota exceeded"), name); ++ "destination %s space quota exceeded."), name); + (void) zfs_error(hdl, EZFS_NOSPC, errbuf); + break; ++ case EBUSY: ++ if (hastoken) { ++ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, ++ "destination %s contains " ++ "partially-complete state from " ++ "\"zfs receive -s\"."), name); ++ (void) zfs_error(hdl, EZFS_BUSY, errbuf); ++ break; ++ } ++ /* fallthru */ + default: + (void) zfs_standard_error(hdl, ioctl_errno, errbuf); + } +-- +2.14.2 + diff --git a/zfs-patches/0032-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch b/zfs-patches/0032-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch new file mode 100644 index 0000000..8fc2b50 --- /dev/null +++ b/zfs-patches/0032-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch @@ -0,0 +1,247 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: George Wilson +Date: Thu, 8 Feb 2018 15:04:14 -0500 +Subject: [PATCH] OpenZFS 8857 - zio_remove_child() panic due to already + destroyed parent zio +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PROBLEM +======= +It's possible for a parent zio to complete even though it has children +which have not completed. This can result in the following panic: + > $C + ffffff01809128c0 vpanic() + ffffff01809128e0 mutex_panic+0x58(fffffffffb94c904, ffffff597dde7f80) + ffffff0180912950 mutex_vector_enter+0x347(ffffff597dde7f80) + ffffff01809129b0 zio_remove_child+0x50(ffffff597dde7c58, ffffff32bd901ac0, + ffffff3373370908) + ffffff0180912a40 zio_done+0x390(ffffff32bd901ac0) + ffffff0180912a70 zio_execute+0x78(ffffff32bd901ac0) + ffffff0180912b30 taskq_thread+0x2d0(ffffff33bae44140) + ffffff0180912b40 thread_start+8() + > ::status + debugging crash dump vmcore.2 (64-bit) from batfs0390 + operating system: 5.11 joyent_20170911T171900Z (i86pc) + image uuid: (not set) + panic message: mutex_enter: bad mutex, lp=ffffff597dde7f80 + owner=ffffff3c59b39480 thread=ffffff0180912c40 + dump content: kernel pages only +The problem is that dbuf_prefetch along with l2arc can create a zio tree +which confuses the parent zio and allows it to complete with while children +still exist. Here's the scenario: + zio tree: + pio + |--- lio +The parent zio, pio, has entered the zio_done stage and begins to check its +children to see there are still some that have not completed. In zio_done(), +the children are checked in the following order: + zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE) + zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_DONE) + zio_wait_for_children(zio, ZIO_CHILD_DDT, ZIO_WAIT_DONE) + zio_wait_for_children(zio, ZIO_CHILD_LOGICAL, ZIO_WAIT_DONE) +If pio, finds any child which has not completed then it stops executing and +goes to sleep. Each call to zio_wait_for_children() will grab the io_lock +while checking the particular child. +In this scenario, the pio has completed the first call to +zio_wait_for_children() to check for any ZIO_CHILD_VDEV children. Since +the only zio in the zio tree right now is the logical zio, lio, then it +completes that call and prepares to check the next child type. +In the meantime, the lio completes and in its callback creates a child vdev +zio, cio. The zio tree looks like this: + zio tree: + pio + |--- lio + |--- cio +The lio then grabs the parent's io_lock and removes itself. + zio tree: + pio + |--- cio +The pio continues to run but has already completed its check for ZIO_CHILD_VDEV +and will erroneously complete. When the child zio, cio, completes it will panic +the system trying to reference the parent zio which has been destroyed. +SOLUTION +======== +The fix is to rework the zio_wait_for_children() logic to accept a bitfield +for all the children types that it's interested in checking. The +io_lock will is held the entire time we check all the children types. Since +the function now accepts a bitfield, a simple ZIO_CHILD_BIT() macro is provided +to allow for the conversion between a ZIO_CHILD type and the bitfield used by +the zio_wiat_for_children logic. + +Authored by: George Wilson +Reviewed by: Matthew Ahrens +Reviewed by: Andriy Gapon +Reviewed by: Youzhong Yang +Reviewed by: Brian Behlendorf +Approved by: Dan McDonald +Ported-by: Giuseppe Di Natale + +OpenZFS-issue: https://www.illumos.org/issues/8857 +OpenZFS-commit: https://github.com/openzfs/openzfs/commit/862ff6d99c +Issue #5918 +Closes #7168 + +(cherry picked from commit 07ce5d739024cf9c638716c09f9934b4e629678c) +Signed-off-by: Fabian Grünbichler +--- + include/sys/zio.h | 11 +++++++++++ + module/zfs/zio.c | 49 +++++++++++++++++++++++++++++-------------------- + 2 files changed, 40 insertions(+), 20 deletions(-) + +diff --git a/include/sys/zio.h b/include/sys/zio.h +index 4eaabc38c..0d741f8e2 100644 +--- a/include/sys/zio.h ++++ b/include/sys/zio.h +@@ -215,6 +215,9 @@ enum zio_flag { + (((zio)->io_flags & ZIO_FLAG_VDEV_INHERIT) | \ + ZIO_FLAG_CANFAIL) + ++#define ZIO_CHILD_BIT(x) (1 << (x)) ++#define ZIO_CHILD_BIT_IS_SET(val, x) ((val) & (1 << (x))) ++ + enum zio_child { + ZIO_CHILD_VDEV = 0, + ZIO_CHILD_GANG, +@@ -223,6 +226,14 @@ enum zio_child { + ZIO_CHILD_TYPES + }; + ++#define ZIO_CHILD_VDEV_BIT ZIO_CHILD_BIT(ZIO_CHILD_VDEV) ++#define ZIO_CHILD_GANG_BIT ZIO_CHILD_BIT(ZIO_CHILD_GANG) ++#define ZIO_CHILD_DDT_BIT ZIO_CHILD_BIT(ZIO_CHILD_DDT) ++#define ZIO_CHILD_LOGICAL_BIT ZIO_CHILD_BIT(ZIO_CHILD_LOGICAL) ++#define ZIO_CHILD_ALL_BITS \ ++ (ZIO_CHILD_VDEV_BIT | ZIO_CHILD_GANG_BIT | \ ++ ZIO_CHILD_DDT_BIT | ZIO_CHILD_LOGICAL_BIT) ++ + enum zio_wait_type { + ZIO_WAIT_READY = 0, + ZIO_WAIT_DONE, +diff --git a/module/zfs/zio.c b/module/zfs/zio.c +index 1d69d8d8d..cd0a473e0 100644 +--- a/module/zfs/zio.c ++++ b/module/zfs/zio.c +@@ -491,21 +491,26 @@ zio_remove_child(zio_t *pio, zio_t *cio, zio_link_t *zl) + } + + static boolean_t +-zio_wait_for_children(zio_t *zio, enum zio_child child, enum zio_wait_type wait) ++zio_wait_for_children(zio_t *zio, uint8_t childbits, enum zio_wait_type wait) + { +- uint64_t *countp = &zio->io_children[child][wait]; + boolean_t waiting = B_FALSE; + + mutex_enter(&zio->io_lock); + ASSERT(zio->io_stall == NULL); +- if (*countp != 0) { +- zio->io_stage >>= 1; +- ASSERT3U(zio->io_stage, !=, ZIO_STAGE_OPEN); +- zio->io_stall = countp; +- waiting = B_TRUE; ++ for (int c = 0; c < ZIO_CHILD_TYPES; c++) { ++ if (!(ZIO_CHILD_BIT_IS_SET(childbits, c))) ++ continue; ++ ++ uint64_t *countp = &zio->io_children[c][wait]; ++ if (*countp != 0) { ++ zio->io_stage >>= 1; ++ ASSERT3U(zio->io_stage, !=, ZIO_STAGE_OPEN); ++ zio->io_stall = countp; ++ waiting = B_TRUE; ++ break; ++ } + } + mutex_exit(&zio->io_lock); +- + return (waiting); + } + +@@ -1296,9 +1301,10 @@ zio_write_compress(zio_t *zio) + * If our children haven't all reached the ready stage, + * wait for them and then repeat this pipeline stage. + */ +- if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_READY) || +- zio_wait_for_children(zio, ZIO_CHILD_LOGICAL, ZIO_WAIT_READY)) ++ if (zio_wait_for_children(zio, ZIO_CHILD_LOGICAL_BIT | ++ ZIO_CHILD_GANG_BIT, ZIO_WAIT_READY)) { + return (ZIO_PIPELINE_STOP); ++ } + + if (!IO_IS_ALLOCATING(zio)) + return (ZIO_PIPELINE_CONTINUE); +@@ -2229,8 +2235,9 @@ zio_gang_issue(zio_t *zio) + { + blkptr_t *bp = zio->io_bp; + +- if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_DONE)) ++ if (zio_wait_for_children(zio, ZIO_CHILD_GANG_BIT, ZIO_WAIT_DONE)) { + return (ZIO_PIPELINE_STOP); ++ } + + ASSERT(BP_IS_GANG(bp) && zio->io_gang_leader == zio); + ASSERT(zio->io_child_type > ZIO_CHILD_GANG); +@@ -2561,8 +2568,9 @@ zio_ddt_read_done(zio_t *zio) + { + blkptr_t *bp = zio->io_bp; + +- if (zio_wait_for_children(zio, ZIO_CHILD_DDT, ZIO_WAIT_DONE)) ++ if (zio_wait_for_children(zio, ZIO_CHILD_DDT_BIT, ZIO_WAIT_DONE)) { + return (ZIO_PIPELINE_STOP); ++ } + + ASSERT(BP_GET_DEDUP(bp)); + ASSERT(BP_GET_PSIZE(bp) == zio->io_size); +@@ -3292,8 +3300,9 @@ zio_vdev_io_done(zio_t *zio) + vdev_ops_t *ops = vd ? vd->vdev_ops : &vdev_mirror_ops; + boolean_t unexpected_error = B_FALSE; + +- if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE)) ++ if (zio_wait_for_children(zio, ZIO_CHILD_VDEV_BIT, ZIO_WAIT_DONE)) { + return (ZIO_PIPELINE_STOP); ++ } + + ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE); + +@@ -3362,8 +3371,9 @@ zio_vdev_io_assess(zio_t *zio) + { + vdev_t *vd = zio->io_vd; + +- if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE)) ++ if (zio_wait_for_children(zio, ZIO_CHILD_VDEV_BIT, ZIO_WAIT_DONE)) { + return (ZIO_PIPELINE_STOP); ++ } + + if (vd == NULL && !(zio->io_flags & ZIO_FLAG_CONFIG_WRITER)) + spa_config_exit(zio->io_spa, SCL_ZIO, zio); +@@ -3578,9 +3588,10 @@ zio_ready(zio_t *zio) + zio_t *pio, *pio_next; + zio_link_t *zl = NULL; + +- if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_READY) || +- zio_wait_for_children(zio, ZIO_CHILD_DDT, ZIO_WAIT_READY)) ++ if (zio_wait_for_children(zio, ZIO_CHILD_GANG_BIT | ZIO_CHILD_DDT_BIT, ++ ZIO_WAIT_READY)) { + return (ZIO_PIPELINE_STOP); ++ } + + if (zio->io_ready) { + ASSERT(IO_IS_ALLOCATING(zio)); +@@ -3721,11 +3732,9 @@ zio_done(zio_t *zio) + * If our children haven't all completed, + * wait for them and then repeat this pipeline stage. + */ +- if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE) || +- zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_DONE) || +- zio_wait_for_children(zio, ZIO_CHILD_DDT, ZIO_WAIT_DONE) || +- zio_wait_for_children(zio, ZIO_CHILD_LOGICAL, ZIO_WAIT_DONE)) ++ if (zio_wait_for_children(zio, ZIO_CHILD_ALL_BITS, ZIO_WAIT_DONE)) { + return (ZIO_PIPELINE_STOP); ++ } + + /* + * If the allocation throttle is enabled, then update the accounting. +-- +2.14.2 + diff --git a/zfs-patches/0033-Clarify-zinject-8-explanation-of-e.patch b/zfs-patches/0033-Clarify-zinject-8-explanation-of-e.patch new file mode 100644 index 0000000..561a646 --- /dev/null +++ b/zfs-patches/0033-Clarify-zinject-8-explanation-of-e.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Olaf Faaland +Date: Thu, 15 Feb 2018 09:50:06 -0800 +Subject: [PATCH] Clarify zinject(8) explanation of -e +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Error injection of EIO or ENXIO simply sets the zio's io_error value, +rather than preventing the read or write from occurring. This is +important information as it affects how the probes must be used. + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Reviewed-by: George Melikov +Signed-off-by: Olaf Faaland +Closes #7172 +(cherry picked from commit 26941ce90b8f056949a3bc29da606513af799781) +Signed-off-by: Fabian Grünbichler +--- + man/man8/zinject.8 | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/man/man8/zinject.8 b/man/man8/zinject.8 +index 50fecfb64..7f363974b 100644 +--- a/man/man8/zinject.8 ++++ b/man/man8/zinject.8 +@@ -111,6 +111,9 @@ Specify + .BR "dtl" " for an ECHILD error," + .BR "io" " for an EIO error where reopening the device will succeed, or" + .BR "nxio" " for an ENXIO error where reopening the device will fail." ++For EIO and ENXIO, the "failed" reads or writes still occur. The probe simply ++sets the error value reported by the I/O pipeline so it appears the read or ++write failed. + .TP + .BI "\-f" " frequency" + Only inject errors a fraction of the time. Expressed as a real number +-- +2.14.2 + diff --git a/zfs-patches/0034-Fix-config-issues-frame-size-and-headers.patch b/zfs-patches/0034-Fix-config-issues-frame-size-and-headers.patch new file mode 100644 index 0000000..656e845 --- /dev/null +++ b/zfs-patches/0034-Fix-config-issues-frame-size-and-headers.patch @@ -0,0 +1,199 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: chrisrd +Date: Fri, 16 Feb 2018 07:58:23 +1100 +Subject: [PATCH] Fix config issues: frame size and headers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1. With various (debug and/or tracing?) kernel options enabled it's +possible for 'struct inode' and 'struct super_block' to exceed the +default frame size, leaving errors like this in config.log: + +build/conftest.c:116:1: error: the frame size of 1048 bytes is larger +than 1024 bytes [-Werror=frame-larger-than=] + +Fix this by removing the frame size warning for config checks + +2. Without the correct headers included, it's possible for declarations +to be missed, leaving errors like this in the config.log: + +build/conftest.c:131:14: error: ‘struct nameidata’ declared inside +parameter list [-Werror] + +Fix this by adding appropriate headers. + +Note: Both these issues can result in silent config failures because +the compile failure is taken to mean "this option is not supported by +this kernel" rather than "there's something wrong with the config +test". This can lead to something merely annoying (compile failures) to +something potentially serious (miscompiled or misused kernel primitives +or functions). E.g. the fixes included here resulted in these +additional defines in zfs_config.h with linux v4.14.19: + +Also, drive-by whitespace fixes in config/* files which don't mention +"GNU" (those ones look to be imported from elsewhere so leave them +alone). + +Reviewed by: Brian Behlendorf +Signed-off-by: Chris Dunlop +Closes #7169 +(cherry picked from commit 5a84c60fb95ee7ca1393efe93d9d17c80497c6b6) +Signed-off-by: Fabian Grünbichler +--- + config/deb.am | 8 ++++---- + config/kernel-acl.m4 | 1 + + config/kernel-create-nameidata.m4 | 1 + + config/kernel-dentry-operations.m4 | 1 + + config/kernel-get-link.m4 | 2 +- + config/kernel-lookup-nameidata.m4 | 1 + + config/kernel-vm_node_stat.m4 | 2 +- + config/kernel.m4 | 2 +- + config/tgz.am | 4 ++-- + config/user-libblkid.m4 | 2 +- + 10 files changed, 14 insertions(+), 10 deletions(-) + +diff --git a/config/deb.am b/config/deb.am +index 1b51f9316..58ab96e18 100644 +--- a/config/deb.am ++++ b/config/deb.am +@@ -2,16 +2,16 @@ deb-local: + @(if test "${HAVE_DPKGBUILD}" = "no"; then \ + echo -e "\n" \ + "*** Required util ${DPKGBUILD} missing. Please install the\n" \ +- "*** package for your distribution which provides ${DPKGBUILD},\n" \ ++ "*** package for your distribution which provides ${DPKGBUILD},\n" \ + "*** re-run configure, and try again.\n"; \ +- exit 1; \ ++ exit 1; \ + fi; \ + if test "${HAVE_ALIEN}" = "no"; then \ + echo -e "\n" \ + "*** Required util ${ALIEN} missing. Please install the\n" \ +- "*** package for your distribution which provides ${ALIEN},\n" \ ++ "*** package for your distribution which provides ${ALIEN},\n" \ + "*** re-run configure, and try again.\n"; \ +- exit 1; \ ++ exit 1; \ + fi) + + deb-kmod: deb-local rpm-kmod +diff --git a/config/kernel-acl.m4 b/config/kernel-acl.m4 +index 311484349..02cc020e5 100644 +--- a/config/kernel-acl.m4 ++++ b/config/kernel-acl.m4 +@@ -184,6 +184,7 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA], [ + AC_MSG_CHECKING([whether iops->permission() wants nameidata]) + ZFS_LINUX_TRY_COMPILE([ + #include ++ #include + + int permission_fn(struct inode *inode, int mask, + struct nameidata *nd) { return 0; } +diff --git a/config/kernel-create-nameidata.m4 b/config/kernel-create-nameidata.m4 +index a71490a00..d4c155c57 100644 +--- a/config/kernel-create-nameidata.m4 ++++ b/config/kernel-create-nameidata.m4 +@@ -5,6 +5,7 @@ AC_DEFUN([ZFS_AC_KERNEL_CREATE_NAMEIDATA], [ + AC_MSG_CHECKING([whether iops->create() passes nameidata]) + ZFS_LINUX_TRY_COMPILE([ + #include ++ #include + + #ifdef HAVE_MKDIR_UMODE_T + int inode_create(struct inode *inode ,struct dentry *dentry, +diff --git a/config/kernel-dentry-operations.m4 b/config/kernel-dentry-operations.m4 +index 3182490c9..61f5a27af 100644 +--- a/config/kernel-dentry-operations.m4 ++++ b/config/kernel-dentry-operations.m4 +@@ -5,6 +5,7 @@ AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA], [ + AC_MSG_CHECKING([whether dops->d_revalidate() takes struct nameidata]) + ZFS_LINUX_TRY_COMPILE([ + #include ++ #include + + int revalidate (struct dentry *dentry, + struct nameidata *nidata) { return 0; } +diff --git a/config/kernel-get-link.m4 b/config/kernel-get-link.m4 +index 022c49c54..3cda08c1b 100644 +--- a/config/kernel-get-link.m4 ++++ b/config/kernel-get-link.m4 +@@ -41,7 +41,7 @@ AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_LINK], [ + AC_DEFINE(HAVE_FOLLOW_LINK_NAMEIDATA, 1, + [iops->follow_link() nameidata]) + ],[ +- AC_MSG_ERROR(no; please file a bug report) ++ AC_MSG_ERROR(no; please file a bug report) + ]) + ]) + ]) +diff --git a/config/kernel-lookup-nameidata.m4 b/config/kernel-lookup-nameidata.m4 +index 43f5fb4cb..5453be5e8 100644 +--- a/config/kernel-lookup-nameidata.m4 ++++ b/config/kernel-lookup-nameidata.m4 +@@ -5,6 +5,7 @@ AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_NAMEIDATA], [ + AC_MSG_CHECKING([whether iops->lookup() passes nameidata]) + ZFS_LINUX_TRY_COMPILE([ + #include ++ #include + + struct dentry *inode_lookup(struct inode *inode, + struct dentry *dentry, struct nameidata *nidata) +diff --git a/config/kernel-vm_node_stat.m4 b/config/kernel-vm_node_stat.m4 +index e1c42f884..5dcd9d827 100644 +--- a/config/kernel-vm_node_stat.m4 ++++ b/config/kernel-vm_node_stat.m4 +@@ -7,7 +7,7 @@ AC_DEFUN([ZFS_AC_KERNEL_VM_NODE_STAT], [ + ZFS_LINUX_TRY_COMPILE([ + #include + #include +- ],[ ++ ],[ + int a __attribute__ ((unused)) = NR_VM_NODE_STAT_ITEMS; + long x __attribute__ ((unused)) = + atomic_long_read(&vm_node_stat[0]); +diff --git a/config/kernel.m4 b/config/kernel.m4 +index b83f021e8..d4a84b2b2 100644 +--- a/config/kernel.m4 ++++ b/config/kernel.m4 +@@ -722,7 +722,7 @@ AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [ + 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 $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag) >/dev/null && AC_TRY_COMMAND([$3])], ++ [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])] + ) +diff --git a/config/tgz.am b/config/tgz.am +index 2997b1de2..0657d045d 100644 +--- a/config/tgz.am ++++ b/config/tgz.am +@@ -2,9 +2,9 @@ tgz-local: + @(if test "${HAVE_ALIEN}" = "no"; then \ + echo -e "\n" \ + "*** Required util ${ALIEN} missing. Please install the\n" \ +- "*** package for your distribution which provides ${ALIEN},\n" \ ++ "*** package for your distribution which provides ${ALIEN},\n" \ + "*** re-run configure, and try again.\n"; \ +- exit 1; \ ++ exit 1; \ + fi) + + tgz-kmod: tgz-local rpm-kmod +diff --git a/config/user-libblkid.m4 b/config/user-libblkid.m4 +index 5bc7f466a..88e6f990b 100644 +--- a/config/user-libblkid.m4 ++++ b/config/user-libblkid.m4 +@@ -6,7 +6,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_LIBBLKID], [ + LIBBLKID= + + AC_CHECK_HEADER([blkid/blkid.h], [], [AC_MSG_FAILURE([ +- *** blkid.h missing, libblkid-devel package required])]) ++ *** blkid.h missing, libblkid-devel package required])]) + + AC_SUBST([LIBBLKID], ["-lblkid"]) + AC_DEFINE([HAVE_LIBBLKID], 1, [Define if you have libblkid]) +-- +2.14.2 + diff --git a/zfs-patches/0035-Correct-count_uberblocks-in-mmp.kshlib.patch b/zfs-patches/0035-Correct-count_uberblocks-in-mmp.kshlib.patch new file mode 100644 index 0000000..db1e329 --- /dev/null +++ b/zfs-patches/0035-Correct-count_uberblocks-in-mmp.kshlib.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Giuseppe Di Natale +Date: Tue, 20 Feb 2018 16:28:52 -0800 +Subject: [PATCH] Correct count_uberblocks in mmp.kshlib +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A log_must call was causing count_uberblocks to return more +than just the uberblock count. Remove the log_must since it +was only logging a sleep. + +Reviewed-by: Brian Behlendorf +Reviewed-by: Olaf Faaland +Reviewed-by: loli10K +Signed-off-by: Giuseppe Di Natale +Closes #7191 +(cherry picked from commit d5b10b3ef3b5e82b9e5a9bee122f1a0be007dae2) +Signed-off-by: Fabian Grünbichler +--- + tests/zfs-tests/tests/functional/mmp/mmp.kshlib | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/zfs-tests/tests/functional/mmp/mmp.kshlib b/tests/zfs-tests/tests/functional/mmp/mmp.kshlib +index 4c46ae7a2..1f8d66fd9 100644 +--- a/tests/zfs-tests/tests/functional/mmp/mmp.kshlib ++++ b/tests/zfs-tests/tests/functional/mmp/mmp.kshlib +@@ -198,6 +198,6 @@ function count_uberblocks # pool duration + typeset -i duration=$2 + typeset hist_path="/proc/spl/kstat/zfs/$pool/multihost" + +- log_must sleep $duration ++ sleep $duration + echo $(cat "$hist_path" | sed '1,2d' | wc -l) + } +-- +2.14.2 + diff --git a/zfs-patches/0036-Add-SMART-attributes-for-SSD-and-NVMe.patch b/zfs-patches/0036-Add-SMART-attributes-for-SSD-and-NVMe.patch new file mode 100644 index 0000000..a18d02d --- /dev/null +++ b/zfs-patches/0036-Add-SMART-attributes-for-SSD-and-NVMe.patch @@ -0,0 +1,131 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: bunder2015 +Date: Wed, 21 Feb 2018 16:52:47 -0500 +Subject: [PATCH] Add SMART attributes for SSD and NVMe +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This adds the SMART attributes required to probe Samsung SSD and NVMe +(and possibly others) disks when using the "zpool status -c" command. + +Reviewed-by: loli10K +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Tony Hutter +Reviewed-by: Brian Behlendorf +Signed-off-by: bunder2015 +Closes #7183 +Closes #7193 +(cherry picked from commit c705d8386b21b08aefdc62b6b1a556aab6717316) +Signed-off-by: Fabian Grünbichler +--- + cmd/zpool/Makefile.am | 2 ++ + cmd/zpool/zpool.d/nvme_err | 1 + + cmd/zpool/zpool.d/smart | 23 +++++++++++++++++++++-- + 3 files changed, 24 insertions(+), 2 deletions(-) + create mode 120000 cmd/zpool/zpool.d/nvme_err + +diff --git a/cmd/zpool/Makefile.am b/cmd/zpool/Makefile.am +index 6eff1d143..c7b8b76e3 100644 +--- a/cmd/zpool/Makefile.am ++++ b/cmd/zpool/Makefile.am +@@ -60,6 +60,7 @@ dist_zpoolexec_SCRIPTS = \ + zpool.d/pend_sec \ + zpool.d/off_ucor \ + zpool.d/ata_err \ ++ zpool.d/nvme_err \ + zpool.d/pwr_cyc \ + zpool.d/upath \ + zpool.d/vendor +@@ -98,6 +99,7 @@ zpoolconfdefaults = \ + pend_sec \ + off_ucor \ + ata_err \ ++ nvme_err \ + pwr_cyc \ + upath \ + vendor +diff --git a/cmd/zpool/zpool.d/nvme_err b/cmd/zpool/zpool.d/nvme_err +new file mode 120000 +index 000000000..94f22861f +--- /dev/null ++++ b/cmd/zpool/zpool.d/nvme_err +@@ -0,0 +1 @@ ++smart +\ No newline at end of file +diff --git a/cmd/zpool/zpool.d/smart b/cmd/zpool/zpool.d/smart +index 3721f30ed..4bc3af39d 100755 +--- a/cmd/zpool/zpool.d/smart ++++ b/cmd/zpool/zpool.d/smart +@@ -23,6 +23,7 @@ off_ucor: Show SMART offline uncorrectable errors (ATA). + ata_err: Show SMART ATA errors (ATA). + pwr_cyc: Show SMART power cycle count (ATA). + serial: Show disk serial number. ++nvme_err: Show SMART NVMe errors (NVMe). + " + + script=$(basename "$0") +@@ -37,7 +38,7 @@ smartctl_path=$(which smartctl) + if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ]; then + raw_out=$(eval "sudo $smartctl_path -a $VDEV_UPATH") + +- # Are we a SAS or ATA drive? Look for the right line in smartctl: ++ # What kind of drive are we? Look for the right line in smartctl: + # + # SAS: + # Transport protocol: SAS +@@ -45,7 +46,10 @@ if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ]; then + # SATA: + # ATA Version is: 8 + # +- type=$(echo "$raw_out" | grep -m 1 -Eo '^ATA|SAS$') ++ # NVMe: ++ # SMART/Health Information (NVMe Log 0xnn, NSID 0xnn) ++ # ++ type=$(echo "$raw_out" | grep -m 1 -Eo '^ATA|NVMe|SAS$') + out=$(echo "$raw_out" | awk ' + # SAS specific + /read:/{print "rrd="$4"\nr_cor="$5"\nr_proc="$7"\nr_ucor="$8} +@@ -71,10 +75,21 @@ if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ]; then + + # SATA common + /Temperature_Celsius/{print "temp="$10} ++/Airflow_Temperature_Cel/{print "temp="$10} + /SMART overall-health self-assessment test result:/{print "health="$6} + /Power_On_Hours/{print "hours_on="$10} + /Serial Number:/{print "serial="$3} + ++# NVMe common ++/Temperature:/{print "temp="$2} ++/SMART overall-health self-assessment test result:/{print "health="$6} ++/Power On Hours:/{gsub("[^0-9]","",$4); print "hours_on="$4} ++/Serial Number:/{print "serial="$3} ++/Power Cycles:/{print "pwr_cyc="$3} ++ ++# NVMe specific ++/Media and Data Integrity Errors:/{print "nvme_err="$6} ++ + END {ORS="\n"; print ""} + '); + fi +@@ -94,6 +109,8 @@ smart) + scripts="temp|health|r_ucor|w_ucor" + elif [ "$type" = "ATA" ] ; then + scripts="temp|health|ata_err|realloc|rep_ucor|cmd_to|pend_sec|off_ucor" ++ elif [ "$type" = "NVMe" ] ; then ++ scripts="temp|health|nvme_err" + fi + ;; + smartx) +@@ -102,6 +119,8 @@ smartx) + scripts="hours_on|defect|nonmed|r_proc|w_proc" + elif [ "$type" = "ATA" ] ; then + scripts="hours_on|pwr_cyc" ++ elif [ "$type" = "NVMe" ] ; then ++ scripts="hours_on|pwr_cyc" + fi + ;; + *) +-- +2.14.2 + diff --git a/zfs-patches/0037-Allow-modprobe-to-fail-when-called-within-systemd.patch b/zfs-patches/0037-Allow-modprobe-to-fail-when-called-within-systemd.patch new file mode 100644 index 0000000..a918450 --- /dev/null +++ b/zfs-patches/0037-Allow-modprobe-to-fail-when-called-within-systemd.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Matthew Thode +Date: Wed, 21 Feb 2018 22:45:35 +0000 +Subject: [PATCH] Allow modprobe to fail when called within systemd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allows for systems with zfs built into the kernel manually to run +these services. Otherwise the service will fail to start. + +Reviewed-by: loli10K +Reviewed-by: Kash Pande +Reviewed-by: Brian Behlendorf +Signed-off-by: Matthew Thode +Closes #7174 +(cherry picked from commit 30ac8de48a2bb680e15dfe8879faaa7b461b771c) +Signed-off-by: Fabian Grünbichler +--- + etc/systemd/system/zfs-import-cache.service.in | 2 +- + etc/systemd/system/zfs-import-scan.service.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/etc/systemd/system/zfs-import-cache.service.in b/etc/systemd/system/zfs-import-cache.service.in +index 9d677f8dd..726c468ca 100644 +--- a/etc/systemd/system/zfs-import-cache.service.in ++++ b/etc/systemd/system/zfs-import-cache.service.in +@@ -12,7 +12,7 @@ ConditionPathExists=@sysconfdir@/zfs/zpool.cache + [Service] + Type=oneshot + RemainAfterExit=yes +-ExecStartPre=/sbin/modprobe zfs ++ExecStartPre=-/sbin/modprobe zfs + ExecStart=@sbindir@/zpool import -c @sysconfdir@/zfs/zpool.cache -aN + + [Install] +diff --git a/etc/systemd/system/zfs-import-scan.service.in b/etc/systemd/system/zfs-import-scan.service.in +index cc428b0d0..8fe2c1072 100644 +--- a/etc/systemd/system/zfs-import-scan.service.in ++++ b/etc/systemd/system/zfs-import-scan.service.in +@@ -11,7 +11,7 @@ ConditionPathExists=!@sysconfdir@/zfs/zpool.cache + [Service] + Type=oneshot + RemainAfterExit=yes +-ExecStartPre=/sbin/modprobe zfs ++ExecStartPre=-/sbin/modprobe zfs + ExecStart=@sbindir@/zpool import -aN -d /dev/disk/by-id -o cachefile=none + + [Install] +-- +2.14.2 + diff --git a/zfs-patches/0038-Linux-4.16-compat-use-correct-_dec_and_test.patch b/zfs-patches/0038-Linux-4.16-compat-use-correct-_dec_and_test.patch new file mode 100644 index 0000000..00d4b4f --- /dev/null +++ b/zfs-patches/0038-Linux-4.16-compat-use-correct-_dec_and_test.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tony Hutter +Date: Thu, 22 Feb 2018 09:02:06 -0800 +Subject: [PATCH] Linux 4.16 compat: use correct *_dec_and_test() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use refcount_dec_and_test() on 4.16+ kernels, atomic_dec_and_test() +on older kernels. https://lwn.net/Articles/714974/ + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Signed-off-by: Tony Hutter +Closes: #7179 +Closes: #7211 +(cherry picked from commit e5ba614d05bde1e98ba46d5b75cf6b8a0701c2ca) +Signed-off-by: Fabian Grünbichler +--- + include/linux/vfs_compat.h | 6 +++++- + config/kernel-acl-refcount.m4 | 20 ++++++++++++++++++++ + config/kernel.m4 | 1 + + 3 files changed, 26 insertions(+), 1 deletion(-) + create mode 100644 config/kernel-acl-refcount.m4 + +diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h +index 7fcf3c055..6347268af 100644 +--- a/include/linux/vfs_compat.h ++++ b/include/linux/vfs_compat.h +@@ -288,9 +288,13 @@ zpl_posix_acl_release(struct posix_acl *acl) + { + if ((acl == NULL) || (acl == ACL_NOT_CACHED)) + return; +- ++#ifdef HAVE_ACL_REFCOUNT ++ if (refcount_dec_and_test(&acl->a_refcount)) ++ zpl_posix_acl_release_impl(acl); ++#else + if (atomic_dec_and_test(&acl->a_refcount)) + zpl_posix_acl_release_impl(acl); ++#endif + } + #endif /* HAVE_POSIX_ACL_RELEASE */ + +diff --git a/config/kernel-acl-refcount.m4 b/config/kernel-acl-refcount.m4 +new file mode 100644 +index 000000000..43e3c442d +--- /dev/null ++++ b/config/kernel-acl-refcount.m4 +@@ -0,0 +1,20 @@ ++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_ACL_HAS_REFCOUNT], [ ++ AC_MSG_CHECKING([whether posix_acl has refcount_t]) ++ ZFS_LINUX_TRY_COMPILE([ ++ #include ++ #include ++ #include ++ ],[ ++ struct posix_acl acl; ++ refcount_t *r __attribute__ ((unused)) = &acl.a_refcount; ++ ],[ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_ACL_REFCOUNT, 1, [posix_acl has refcount_t]) ++ ],[ ++ AC_MSG_RESULT(no) ++ ]) ++]) +diff --git a/config/kernel.m4 b/config/kernel.m4 +index d4a84b2b2..7bb86a96e 100644 +--- a/config/kernel.m4 ++++ b/config/kernel.m4 +@@ -124,6 +124,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ + ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR + ZFS_AC_KERNEL_CURRENT_TIME + ZFS_AC_KERNEL_VM_NODE_STAT ++ ZFS_AC_KERNEL_ACL_HAS_REFCOUNT + + AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ + KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" +-- +2.14.2 + diff --git a/zfs-patches/0039-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch b/zfs-patches/0039-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch new file mode 100644 index 0000000..ad004d2 --- /dev/null +++ b/zfs-patches/0039-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Olaf Faaland +Date: Thu, 22 Feb 2018 09:14:46 -0800 +Subject: [PATCH] Do not initiate MMP writes while pool is suspended +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +While the pool is suspended on host A, it may be imported on host B. +If host A continued to write MMP blocks, it would be blindly +overwriting MMP blocks written by host B, and the blocks written by +host A would have outdated txg information. + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Signed-off-by: Olaf Faaland +Closes #7182 +(cherry picked from commit b1f61f05b4b2edc77ec5f3d28d041d7b3c873f01) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/mmp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c +index 1dfb7c05b..d003d79de 100644 +--- a/module/zfs/mmp.c ++++ b/module/zfs/mmp.c +@@ -437,7 +437,7 @@ mmp_thread(spa_t *spa) + zio_suspend(spa, NULL); + } + +- if (multihost) ++ if (multihost && !suspended) + mmp_write_uberblock(spa); + + CALLB_CPR_SAFE_BEGIN(&cpr); +-- +2.14.2 + diff --git a/zfs-patches/0040-Report-duration-and-error-in-mmp_history-entries.patch b/zfs-patches/0040-Report-duration-and-error-in-mmp_history-entries.patch new file mode 100644 index 0000000..f05ac98 --- /dev/null +++ b/zfs-patches/0040-Report-duration-and-error-in-mmp_history-entries.patch @@ -0,0 +1,237 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Olaf Faaland +Date: Thu, 22 Feb 2018 15:34:34 -0800 +Subject: [PATCH] Report duration and error in mmp_history entries +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +After an MMP write completes, update the relevant mmp_history entry +with the time between submission and completion, and the error +status of the write. + +[faaland1@toss3a zfs]$ cat /proc/spl/kstat/zfs/pool/multihost +39 0 0x01 100 8800 69147946270893 72723903122926 +id txg timestamp error duration mmp_delay vdev_guid +10607 1166 1518985089 0 138301 637785455 4882... +10608 1166 1518985089 0 136154 635407747 1151... +10609 1166 1518985089 0 803618560 633048078 9740... +10610 1166 1518985090 0 144826 633048078 4882... +10611 1166 1518985090 0 164527 666187671 1151... + +Where duration = gethrtime_in_done_fn - gethrtime_at_submission, and +error = zio->io_error. + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Signed-off-by: Olaf Faaland +Closes #7190 +(cherry picked from commit 2644784f49a6b6be063d54ca0e1662ee6bef7ebd) +Signed-off-by: Fabian Grünbichler +--- + include/sys/mmp.h | 1 + + include/sys/spa.h | 4 +++- + include/sys/vdev_impl.h | 1 + + module/zfs/mmp.c | 13 ++++++++++-- + module/zfs/spa_stats.c | 54 ++++++++++++++++++++++++++++++++++++++++--------- + 5 files changed, 60 insertions(+), 13 deletions(-) + +diff --git a/include/sys/mmp.h b/include/sys/mmp.h +index 5b2fea1a6..1ce685f9c 100644 +--- a/include/sys/mmp.h ++++ b/include/sys/mmp.h +@@ -42,6 +42,7 @@ typedef struct mmp_thread { + uint64_t mmp_delay; /* decaying avg ns between MMP writes */ + uberblock_t mmp_ub; /* last ub written by sync */ + zio_t *mmp_zio_root; /* root of mmp write zios */ ++ uint64_t mmp_kstat_id; /* unique id for next MMP write kstat */ + } mmp_thread_t; + + +diff --git a/include/sys/spa.h b/include/sys/spa.h +index 67235871f..53fa5514a 100644 +--- a/include/sys/spa.h ++++ b/include/sys/spa.h +@@ -759,8 +759,10 @@ extern txg_stat_t *spa_txg_history_init_io(spa_t *, uint64_t, + struct dsl_pool *); + extern void spa_txg_history_fini_io(spa_t *, txg_stat_t *); + extern void spa_tx_assign_add_nsecs(spa_t *spa, uint64_t nsecs); ++extern int spa_mmp_history_set(spa_t *spa, uint64_t mmp_kstat_id, int io_error, ++ hrtime_t duration); + extern void spa_mmp_history_add(uint64_t txg, uint64_t timestamp, +- uint64_t mmp_delay, vdev_t *vd, int label); ++ uint64_t mmp_delay, vdev_t *vd, int label, uint64_t mmp_kstat_id); + + /* Pool configuration locks */ + extern int spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw); +diff --git a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h +index 4c2e3cd2e..13c495822 100644 +--- a/include/sys/vdev_impl.h ++++ b/include/sys/vdev_impl.h +@@ -238,6 +238,7 @@ struct vdev { + vdev_aux_t vdev_label_aux; /* on-disk aux state */ + uint64_t vdev_leaf_zap; + hrtime_t vdev_mmp_pending; /* 0 if write finished */ ++ uint64_t vdev_mmp_kstat_id; /* to find kstat entry */ + + /* + * For DTrace to work in userland (libzpool) context, these fields must +diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c +index d003d79de..ee8e9201b 100644 +--- a/module/zfs/mmp.c ++++ b/module/zfs/mmp.c +@@ -135,6 +135,7 @@ mmp_init(spa_t *spa) + mutex_init(&mmp->mmp_thread_lock, NULL, MUTEX_DEFAULT, NULL); + cv_init(&mmp->mmp_thread_cv, NULL, CV_DEFAULT, NULL); + mutex_init(&mmp->mmp_io_lock, NULL, MUTEX_DEFAULT, NULL); ++ mmp->mmp_kstat_id = 1; + } + + void +@@ -244,7 +245,8 @@ mmp_write_done(zio_t *zio) + mmp_thread_t *mts = zio->io_private; + + mutex_enter(&mts->mmp_io_lock); +- vd->vdev_mmp_pending = 0; ++ uint64_t mmp_kstat_id = vd->vdev_mmp_kstat_id; ++ hrtime_t mmp_write_duration = gethrtime() - vd->vdev_mmp_pending; + + if (zio->io_error) + goto unlock; +@@ -278,9 +280,15 @@ mmp_write_done(zio_t *zio) + mts->mmp_last_write = gethrtime(); + + unlock: ++ vd->vdev_mmp_pending = 0; ++ vd->vdev_mmp_kstat_id = 0; ++ + mutex_exit(&mts->mmp_io_lock); + spa_config_exit(spa, SCL_STATE, mmp_tag); + ++ spa_mmp_history_set(spa, mmp_kstat_id, zio->io_error, ++ mmp_write_duration); ++ + abd_free(zio->io_abd); + } + +@@ -333,6 +341,7 @@ mmp_write_uberblock(spa_t *spa) + ub->ub_mmp_magic = MMP_MAGIC; + ub->ub_mmp_delay = mmp->mmp_delay; + vd->vdev_mmp_pending = gethrtime(); ++ vd->vdev_mmp_kstat_id = mmp->mmp_kstat_id++; + + zio_t *zio = zio_null(mmp->mmp_zio_root, spa, NULL, NULL, NULL, flags); + abd_t *ub_abd = abd_alloc_for_io(VDEV_UBERBLOCK_SIZE(vd), B_TRUE); +@@ -350,7 +359,7 @@ mmp_write_uberblock(spa_t *spa) + flags | ZIO_FLAG_DONT_PROPAGATE); + + spa_mmp_history_add(ub->ub_txg, ub->ub_timestamp, ub->ub_mmp_delay, vd, +- label); ++ label, vd->vdev_mmp_kstat_id); + + zio_nowait(zio); + } +diff --git a/module/zfs/spa_stats.c b/module/zfs/spa_stats.c +index 7ca359806..58967e9fc 100644 +--- a/module/zfs/spa_stats.c ++++ b/module/zfs/spa_stats.c +@@ -718,21 +718,24 @@ spa_io_history_destroy(spa_t *spa) + */ + + typedef struct spa_mmp_history { ++ uint64_t mmp_kstat_id; /* unique # for updates */ + uint64_t txg; /* txg of last sync */ + uint64_t timestamp; /* UTC time of of last sync */ + uint64_t mmp_delay; /* nanosec since last MMP write */ + uint64_t vdev_guid; /* unique ID of leaf vdev */ + char *vdev_path; + uint64_t vdev_label; /* vdev label */ ++ int io_error; /* error status of MMP write */ ++ hrtime_t duration; /* time from submission to completion */ + list_node_t smh_link; + } spa_mmp_history_t; + + static int + spa_mmp_history_headers(char *buf, size_t size) + { +- (void) snprintf(buf, size, "%-10s %-10s %-12s %-24s %-10s %s\n", +- "txg", "timestamp", "mmp_delay", "vdev_guid", "vdev_label", +- "vdev_path"); ++ (void) snprintf(buf, size, "%-10s %-10s %-10s %-6s %-10s %-12s %-24s " ++ "%-10s %s\n", "id", "txg", "timestamp", "error", "duration", ++ "mmp_delay", "vdev_guid", "vdev_label", "vdev_path"); + return (0); + } + +@@ -741,11 +744,12 @@ spa_mmp_history_data(char *buf, size_t size, void *data) + { + spa_mmp_history_t *smh = (spa_mmp_history_t *)data; + +- (void) snprintf(buf, size, "%-10llu %-10llu %-12llu %-24llu %-10llu " +- "%s\n", +- (u_longlong_t)smh->txg, (u_longlong_t)smh->timestamp, +- (u_longlong_t)smh->mmp_delay, (u_longlong_t)smh->vdev_guid, +- (u_longlong_t)smh->vdev_label, ++ (void) snprintf(buf, size, "%-10llu %-10llu %-10llu %-6lld %-10lld " ++ "%-12llu %-24llu %-10llu %s\n", ++ (u_longlong_t)smh->mmp_kstat_id, (u_longlong_t)smh->txg, ++ (u_longlong_t)smh->timestamp, (longlong_t)smh->io_error, ++ (longlong_t)smh->duration, (u_longlong_t)smh->mmp_delay, ++ (u_longlong_t)smh->vdev_guid, (u_longlong_t)smh->vdev_label, + (smh->vdev_path ? smh->vdev_path : "-")); + + return (0); +@@ -861,11 +865,40 @@ spa_mmp_history_destroy(spa_t *spa) + } + + /* +- * Add a new MMP update to historical record. ++ * Set MMP write duration and error status in existing record. ++ */ ++int ++spa_mmp_history_set(spa_t *spa, uint64_t mmp_kstat_id, int io_error, ++ hrtime_t duration) ++{ ++ spa_stats_history_t *ssh = &spa->spa_stats.mmp_history; ++ spa_mmp_history_t *smh; ++ int error = ENOENT; ++ ++ if (zfs_multihost_history == 0 && ssh->size == 0) ++ return (0); ++ ++ mutex_enter(&ssh->lock); ++ for (smh = list_head(&ssh->list); smh != NULL; ++ smh = list_next(&ssh->list, smh)) { ++ if (smh->mmp_kstat_id == mmp_kstat_id) { ++ smh->io_error = io_error; ++ smh->duration = duration; ++ error = 0; ++ break; ++ } ++ } ++ mutex_exit(&ssh->lock); ++ ++ return (error); ++} ++ ++/* ++ * Add a new MMP write to historical record. + */ + void + spa_mmp_history_add(uint64_t txg, uint64_t timestamp, uint64_t mmp_delay, +- vdev_t *vd, int label) ++ vdev_t *vd, int label, uint64_t mmp_kstat_id) + { + spa_t *spa = vd->vdev_spa; + spa_stats_history_t *ssh = &spa->spa_stats.mmp_history; +@@ -882,6 +915,7 @@ spa_mmp_history_add(uint64_t txg, uint64_t timestamp, uint64_t mmp_delay, + if (vd->vdev_path) + smh->vdev_path = strdup(vd->vdev_path); + smh->vdev_label = label; ++ smh->mmp_kstat_id = mmp_kstat_id; + + mutex_enter(&ssh->lock); + +-- +2.14.2 + diff --git a/zfs-patches/0041-Fix-free-memory-calculation-on-v3.14.patch b/zfs-patches/0041-Fix-free-memory-calculation-on-v3.14.patch new file mode 100644 index 0000000..5c55057 --- /dev/null +++ b/zfs-patches/0041-Fix-free-memory-calculation-on-v3.14.patch @@ -0,0 +1,451 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: chrisrd +Date: Sat, 24 Feb 2018 03:50:06 +1100 +Subject: [PATCH] Fix free memory calculation on v3.14+ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Provide infrastructure to auto-configure to enum and API changes in the +global page stats used for our free memory calculations. + +arc_free_memory has been broken since an API change in Linux v3.14: + +2016-07-28 v4.8 599d0c95 mm, vmscan: move LRU lists to node +2016-07-28 v4.8 75ef7184 mm, vmstat: add infrastructure for per-node + vmstats + +These commits moved some of global_page_state() into +global_node_page_state(). The API change was particularly egregious as, +instead of breaking the old code, it silently did the wrong thing and we +continued using global_page_state() where we should have been using +global_node_page_state(), thus indexing into the wrong array via +NR_SLAB_RECLAIMABLE et al. + +There have been further API changes along the way: + +2017-07-06 v4.13 385386cf mm: vmstat: move slab statistics from zone to + node counters +2017-09-06 v4.14 c41f012a mm: rename global_page_state to + global_zone_page_state + +...and various (incomplete, as it turns out) attempts to accomodate +these changes in ZoL: + +2017-08-24 2209e409 Linux 4.8+ compatibility fix for vm stats +2017-09-16 787acae0 Linux 3.14 compat: IO acct, global_page_state, etc +2017-09-19 661907e6 Linux 4.14 compat: IO acct, global_page_state, etc + +The config infrastructure provided here resolves these issues going back +to the original API change in v3.14 and is robust against further Linux +changes in this area. + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Reviewed-by: George Melikov +Signed-off-by: Chris Dunlop +Closes #7170 +(cherry picked from commit 338523dd6ec641cc4d552c3f67e1becfb9e22b0a) +Signed-off-by: Fabian Grünbichler +--- + include/linux/Makefile.am | 3 +- + scripts/Makefile.am | 2 + + include/linux/page_compat.h | 78 ++++++++++++++++++++++++++ + module/zfs/arc.c | 23 ++------ + config/kernel-global_page_state.m4 | 109 +++++++++++++++++++++++++++++++++++++ + config/kernel-vm_node_stat.m4 | 22 -------- + config/kernel.m4 | 2 +- + scripts/enum-extract.pl | 58 ++++++++++++++++++++ + 8 files changed, 256 insertions(+), 41 deletions(-) + create mode 100644 include/linux/page_compat.h + create mode 100644 config/kernel-global_page_state.m4 + delete mode 100644 config/kernel-vm_node_stat.m4 + create mode 100755 scripts/enum-extract.pl + +diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am +index 9bb0b3493..89c2689f6 100644 +--- a/include/linux/Makefile.am ++++ b/include/linux/Makefile.am +@@ -9,7 +9,8 @@ KERNEL_H = \ + $(top_srcdir)/include/linux/kmap_compat.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/mod_compat.h \ ++ $(top_srcdir)/include/linux/page_compat.h + + USER_H = + +diff --git a/scripts/Makefile.am b/scripts/Makefile.am +index 74b8b31a5..5a8abd135 100644 +--- a/scripts/Makefile.am ++++ b/scripts/Makefile.am +@@ -5,6 +5,7 @@ EXTRA_DIST = dkms.mkconf dkms.postbuild kmodtool zfs2zol-patch.sed cstyle.pl + pkgdatadir = $(datadir)/@PACKAGE@ + dist_pkgdata_SCRIPTS = \ + $(top_builddir)/scripts/common.sh \ ++ $(top_srcdir)/scripts/enum-extract.pl \ + $(top_srcdir)/scripts/zimport.sh \ + $(top_srcdir)/scripts/zfs.sh \ + $(top_srcdir)/scripts/zfs-tests.sh \ +@@ -15,3 +16,4 @@ dist_pkgdata_SCRIPTS = \ + $(top_srcdir)/scripts/zpios-survey.sh \ + $(top_srcdir)/scripts/smb.sh \ + $(top_srcdir)/scripts/zfs-helpers.sh ++ +diff --git a/include/linux/page_compat.h b/include/linux/page_compat.h +new file mode 100644 +index 000000000..95acb7d53 +--- /dev/null ++++ b/include/linux/page_compat.h +@@ -0,0 +1,78 @@ ++#ifndef _ZFS_PAGE_COMPAT_H ++#define _ZFS_PAGE_COMPAT_H ++ ++/* ++ * We have various enum members moving between two separate enum types, ++ * and accessed by different functions at various times. Centralise the ++ * insanity. ++ * ++ * < v4.8: all enums in zone_stat_item, via global_page_state() ++ * v4.8: some enums moved to node_stat_item, global_node_page_state() introduced ++ * v4.13: some enums moved from zone_stat_item to node_state_item ++ * v4.14: global_page_state() rename to global_zone_page_state() ++ * ++ * The defines used here are created by config/kernel-global_page_state.m4 ++ */ ++ ++/* ++ * Create our own accessor functions to follow the Linux API changes ++ */ ++#if defined(ZFS_GLOBAL_ZONE_PAGE_STATE) ++ ++/* global_zone_page_state() introduced */ ++#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_FILE_PAGES) ++#define nr_file_pages() global_node_page_state(NR_FILE_PAGES) ++#else ++#define nr_file_pages() global_zone_page_state(NR_FILE_PAGES) ++#endif ++#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_INACTIVE_ANON) ++#define nr_inactive_anon_pages() global_node_page_state(NR_INACTIVE_ANON) ++#else ++#define nr_inactive_anon_pages() global_zone_page_state(NR_INACTIVE_ANON) ++#endif ++#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_INACTIVE_FILE) ++#define nr_inactive_file_pages() global_node_page_state(NR_INACTIVE_FILE) ++#else ++#define nr_inactive_file_pages() global_zone_page_state(NR_INACTIVE_FILE) ++#endif ++#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE) ++#define nr_slab_reclaimable_pages() global_node_page_state(NR_SLAB_RECLAIMABLE) ++#else ++#define nr_slab_reclaimable_pages() global_zone_page_state(NR_SLAB_RECLAIMABLE) ++#endif ++ ++#elif defined(ZFS_GLOBAL_NODE_PAGE_STATE) ++ ++/* global_node_page_state() introduced */ ++#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_FILE_PAGES) ++#define nr_file_pages() global_node_page_state(NR_FILE_PAGES) ++#else ++#define nr_file_pages() global_page_state(NR_FILE_PAGES) ++#endif ++#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_INACTIVE_ANON) ++#define nr_inactive_anon_pages() global_node_page_state(NR_INACTIVE_ANON) ++#else ++#define nr_inactive_anon_pages() global_page_state(NR_INACTIVE_ANON) ++#endif ++#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_INACTIVE_FILE) ++#define nr_inactive_file_pages() global_node_page_state(NR_INACTIVE_FILE) ++#else ++#define nr_inactive_file_pages() global_page_state(NR_INACTIVE_FILE) ++#endif ++#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE) ++#define nr_slab_reclaimable_pages() global_node_page_state(NR_SLAB_RECLAIMABLE) ++#else ++#define nr_slab_reclaimable_pages() global_page_state(NR_SLAB_RECLAIMABLE) ++#endif ++ ++#else ++ ++/* global_page_state() only */ ++#define nr_file_pages() global_page_state(NR_FILE_PAGES) ++#define nr_inactive_anon_pages() global_page_state(NR_INACTIVE_ANON) ++#define nr_inactive_file_pages() global_page_state(NR_INACTIVE_FILE) ++#define nr_slab_reclaimable_pages() global_page_state(NR_SLAB_RECLAIMABLE) ++ ++#endif /* ZFS_GLOBAL_ZONE_PAGE_STATE */ ++ ++#endif /* _ZFS_PAGE_COMPAT_H */ +diff --git a/module/zfs/arc.c b/module/zfs/arc.c +index 9d1d0db1d..236794672 100644 +--- a/module/zfs/arc.c ++++ b/module/zfs/arc.c +@@ -280,6 +280,7 @@ + #include + #include + #include ++#include + #endif + #include + #include +@@ -4016,17 +4017,11 @@ arc_free_memory(void) + si_meminfo(&si); + return (ptob(si.freeram - si.freehigh)); + #else +-#ifdef ZFS_GLOBAL_NODE_PAGE_STATE + return (ptob(nr_free_pages() + +- global_node_page_state(NR_INACTIVE_FILE) + +- global_node_page_state(NR_INACTIVE_ANON) + +- global_node_page_state(NR_SLAB_RECLAIMABLE))); +-#else +- return (ptob(nr_free_pages() + +- global_page_state(NR_INACTIVE_FILE) + +- global_page_state(NR_INACTIVE_ANON) + +- global_page_state(NR_SLAB_RECLAIMABLE))); +-#endif /* ZFS_GLOBAL_NODE_PAGE_STATE */ ++ nr_inactive_file_pages() + ++ nr_inactive_anon_pages() + ++ nr_slab_reclaimable_pages())); ++ + #endif /* CONFIG_HIGHMEM */ + #else + return (spa_get_random(arc_all_memory() * 20 / 100)); +@@ -4437,13 +4432,7 @@ arc_evictable_memory(void) + * Scale reported evictable memory in proportion to page cache, cap + * at specified min/max. + */ +-#ifdef ZFS_GLOBAL_NODE_PAGE_STATE +- uint64_t min = (ptob(global_node_page_state(NR_FILE_PAGES)) / 100) * +- zfs_arc_pc_percent; +-#else +- uint64_t min = (ptob(global_page_state(NR_FILE_PAGES)) / 100) * +- zfs_arc_pc_percent; +-#endif ++ uint64_t min = (ptob(nr_file_pages()) / 100) * zfs_arc_pc_percent; + min = MAX(arc_c_min, MIN(arc_c_max, min)); + + if (arc_dirty >= min) +diff --git a/config/kernel-global_page_state.m4 b/config/kernel-global_page_state.m4 +new file mode 100644 +index 000000000..f4a40011f +--- /dev/null ++++ b/config/kernel-global_page_state.m4 +@@ -0,0 +1,109 @@ ++dnl # ++dnl # 4.8 API change ++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([ ++ #include ++ #include ++ ],[ ++ (void) global_node_page_state(0); ++ ],[ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(ZFS_GLOBAL_NODE_PAGE_STATE, 1, [global_node_page_state() exists]) ++ ],[ ++ AC_MSG_RESULT(no) ++ ]) ++]) ++ ++dnl # ++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([ ++ #include ++ #include ++ ],[ ++ (void) global_zone_page_state(0); ++ ],[ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(ZFS_GLOBAL_ZONE_PAGE_STATE, 1, [global_zone_page_state() exists]) ++ ],[ ++ AC_MSG_RESULT(no) ++ ]) ++]) ++ ++dnl # ++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)],[ ++ AC_MSG_RESULT([yes]) ++ 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]) ++ ]) ++]) ++ ++dnl # ++dnl # Sanity check helpers ++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!]) ++]) ++ ++AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK], [ ++ enum_check_a="m4_join([_], [$ZFS_ENUM_NODE_STAT_ITEM], $1)" ++ enum_check_b="m4_join([_], [$ZFS_ENUM_ZONE_STAT_ITEM], $1)" ++ AS_IF([test -n "$enum_check_a" -a -n "$enum_check_b"],[ ++ ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR([$1], [DUPLICATE]) ++ ]) ++ AS_IF([test -z "$enum_check_a" -a -z "$enum_check_b"],[ ++ ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR([$1], [NOT FOUND]) ++ ]) ++]) ++ ++dnl # ++dnl # Ensure the config tests are finding one and only one of each enum of interest ++dnl # ++AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY], [ ++ AC_MSG_CHECKING([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]) ++ ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_FILE]) ++ ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_SLAB_RECLAIMABLE]) ++ ++ AC_MSG_RESULT(yes) ++]) ++ ++dnl # ++dnl # enum members in which we're interested ++dnl # ++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], [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-vm_node_stat.m4 b/config/kernel-vm_node_stat.m4 +deleted file mode 100644 +index 5dcd9d827..000000000 +--- a/config/kernel-vm_node_stat.m4 ++++ /dev/null +@@ -1,22 +0,0 @@ +-dnl # +-dnl # 4.8 API change +-dnl # kernel vm counters change +-dnl # +-AC_DEFUN([ZFS_AC_KERNEL_VM_NODE_STAT], [ +- AC_MSG_CHECKING([whether to use vm_node_stat based fn's]) +- ZFS_LINUX_TRY_COMPILE([ +- #include +- #include +- ],[ +- int a __attribute__ ((unused)) = NR_VM_NODE_STAT_ITEMS; +- long x __attribute__ ((unused)) = +- atomic_long_read(&vm_node_stat[0]); +- (void) global_node_page_state(0); +- ],[ +- AC_MSG_RESULT(yes) +- AC_DEFINE(ZFS_GLOBAL_NODE_PAGE_STATE, 1, +- [using global_node_page_state()]) +- ],[ +- AC_MSG_RESULT(no) +- ]) +-]) +diff --git a/config/kernel.m4 b/config/kernel.m4 +index 7bb86a96e..3e499e447 100644 +--- a/config/kernel.m4 ++++ b/config/kernel.m4 +@@ -123,7 +123,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ + ZFS_AC_KERNEL_RENAME_WANTS_FLAGS + ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR + ZFS_AC_KERNEL_CURRENT_TIME +- ZFS_AC_KERNEL_VM_NODE_STAT ++ ZFS_AC_KERNEL_GLOBAL_PAGE_STATE + ZFS_AC_KERNEL_ACL_HAS_REFCOUNT + + AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ +diff --git a/scripts/enum-extract.pl b/scripts/enum-extract.pl +new file mode 100755 +index 000000000..5112cc807 +--- /dev/null ++++ b/scripts/enum-extract.pl +@@ -0,0 +1,58 @@ ++#!/usr/bin/perl -w ++ ++my $usage = <) { ++ # comments ++ s/\/\*.*\*\///; ++ if (m/\/\*/) { ++ while ($_ .= <>) { ++ last if s/\/\*.*\*\///s; ++ } ++ } ++ ++ # preprocessor stuff ++ next if /^#/; ++ ++ # find our enum ++ $in_enum = 1 if s/^\s*enum\s+${enum}(?:\s|$)//; ++ next unless $in_enum; ++ ++ # remove explicit values ++ s/\s*=[^,]+,/,/g; ++ ++ # extract each identifier ++ while (m/\b([a-z_][a-z0-9_]*)\b/ig) { ++ print $1, "\n"; ++ } ++ ++ # ++ # don't exit: there may be multiple versions of the same enum, e.g. ++ # inside different #ifdef blocks. Let's explicitly return all of ++ # them and let external tooling deal with it. ++ # ++ $in_enum = 0 if m/}\s*;/; ++} ++ ++exit 0; +-- +2.14.2 + diff --git a/zfs-patches/0042-Add-scrub-after-resilver-zed-script.patch b/zfs-patches/0042-Add-scrub-after-resilver-zed-script.patch new file mode 100644 index 0000000..ee8b608 --- /dev/null +++ b/zfs-patches/0042-Add-scrub-after-resilver-zed-script.patch @@ -0,0 +1,516 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tony Hutter +Date: Fri, 23 Feb 2018 11:38:05 -0800 +Subject: [PATCH] Add scrub after resilver zed script +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* Add a zed script to kick off a scrub after a resilver. The script is +disabled by default. + +* Add a optional $PATH (-P) option to zed to allow it to use a custom +$PATH for its zedlets. This is needed when you're running zed under +the ZTS in a local workspace. + +* Update test scripts to not copy in all-debug.sh and all-syslog.sh by +default. They can be optionally copied in as part of zed_setup(). +These scripts slow down zed considerably under heavy events loads and +can cause events to be dropped or their delivery delayed. This was +causing some sporadic failures in the 'fault' tests. + +Reviewed-by: Brian Behlendorf +Reviewed-by: Richard Laager +Signed-off-by: Tony Hutter +Closes #4662 +Closes #7086 +(cherry picked from commit 99920d823e8e1510a0ad133c985bd2aa11a02834) +Signed-off-by: Fabian Grünbichler +--- + cmd/zed/Makefile.am | 6 +- + tests/zfs-tests/tests/functional/fault/Makefile.am | 3 +- + cmd/zed/zed_conf.h | 1 + + man/man8/zed.8.in | 10 +++- + cmd/zed/zed_conf.c | 7 ++- + cmd/zed/zed_event.c | 34 +++++++++-- + cmd/zed/zed.d/resilver_finish-start-scrub.sh | 17 ++++++ + cmd/zed/zed.d/zed.rc | 3 + + tests/runfiles/linux.run | 2 +- + tests/zfs-tests/include/commands.cfg | 1 + + tests/zfs-tests/include/libtest.shlib | 50 ++++++++++++++--- + .../zfs-tests/tests/functional/events/cleanup.ksh | 2 +- + tests/zfs-tests/tests/functional/events/setup.ksh | 2 +- + tests/zfs-tests/tests/functional/fault/cleanup.ksh | 2 +- + .../functional/fault/scrub_after_resilver.ksh | 65 ++++++++++++++++++++++ + tests/zfs-tests/tests/functional/fault/setup.ksh | 2 +- + 16 files changed, 186 insertions(+), 21 deletions(-) + create mode 100755 cmd/zed/zed.d/resilver_finish-start-scrub.sh + create mode 100755 tests/zfs-tests/tests/functional/fault/scrub_after_resilver.ksh + +diff --git a/cmd/zed/Makefile.am b/cmd/zed/Makefile.am +index 97733a512..ee44898cd 100644 +--- a/cmd/zed/Makefile.am ++++ b/cmd/zed/Makefile.am +@@ -69,7 +69,8 @@ dist_zedexec_SCRIPTS = \ + zed.d/statechange-notify.sh \ + zed.d/vdev_clear-led.sh \ + zed.d/vdev_attach-led.sh \ +- zed.d/pool_import-led.sh ++ zed.d/pool_import-led.sh \ ++ zed.d/resilver_finish-start-scrub.sh + + zedconfdefaults = \ + all-syslog.sh \ +@@ -80,7 +81,8 @@ zedconfdefaults = \ + statechange-notify.sh \ + vdev_clear-led.sh \ + vdev_attach-led.sh \ +- pool_import-led.sh ++ pool_import-led.sh \ ++ resilver_finish-start-scrub.sh + + install-data-hook: + $(MKDIR_P) "$(DESTDIR)$(zedconfdir)" +diff --git a/tests/zfs-tests/tests/functional/fault/Makefile.am b/tests/zfs-tests/tests/functional/fault/Makefile.am +index eeff31261..abe28501d 100644 +--- a/tests/zfs-tests/tests/functional/fault/Makefile.am ++++ b/tests/zfs-tests/tests/functional/fault/Makefile.am +@@ -4,4 +4,5 @@ dist_pkgdata_SCRIPTS = \ + setup.ksh \ + cleanup.ksh \ + auto_online_001_pos.ksh \ +- auto_replace_001_pos.ksh ++ auto_replace_001_pos.ksh \ ++ scrub_after_resilver.ksh +diff --git a/cmd/zed/zed_conf.h b/cmd/zed/zed_conf.h +index 2bc634134..7d6b63b1d 100644 +--- a/cmd/zed/zed_conf.h ++++ b/cmd/zed/zed_conf.h +@@ -37,6 +37,7 @@ struct zed_conf { + int state_fd; /* fd to state file */ + libzfs_handle_t *zfs_hdl; /* handle to libzfs */ + int zevent_fd; /* fd for access to zevents */ ++ char *path; /* custom $PATH for zedlets to use */ + }; + + struct zed_conf *zed_conf_create(void); +diff --git a/man/man8/zed.8.in b/man/man8/zed.8.in +index 2ab088d98..645e91795 100644 +--- a/man/man8/zed.8.in ++++ b/man/man8/zed.8.in +@@ -27,6 +27,7 @@ ZED \- ZFS Event Daemon + [\fB\-L\fR] + [\fB\-M\fR] + [\fB\-p\fR \fIpidfile\fR] ++[\fB\-P\fR \fIpath\fR] + [\fB\-s\fR \fIstatefile\fR] + [\fB\-v\fR] + [\fB\-V\fR] +@@ -78,9 +79,16 @@ Read the enabled ZEDLETs from the specified directory. + .BI \-p\ pidfile + Write the daemon's process ID to the specified file. + .TP ++.BI \-P\ path ++Custom $PATH for zedlets to use. Normally zedlets run in a locked-down ++environment, with hardcoded paths to the ZFS commands ($ZFS, $ZPOOL, $ZED, ...), ++and a hardcoded $PATH. This is done for security reasons. However, the ++ZFS test suite uses a custom PATH for its ZFS commands, and passes it to zed ++with -P. In short, -P is only to be used by the ZFS test suite; never use ++it in production! ++.TP + .BI \-s\ statefile + Write the daemon's state to the specified file. +- + .SH ZEVENTS + .PP + A zevent is comprised of a list of nvpairs (name/value pairs). Each zevent +diff --git a/cmd/zed/zed_conf.c b/cmd/zed/zed_conf.c +index 5b27f1e4f..86671369c 100644 +--- a/cmd/zed/zed_conf.c ++++ b/cmd/zed/zed_conf.c +@@ -155,6 +155,8 @@ _zed_conf_display_help(const char *prog, int got_err) + "Run daemon in the foreground."); + fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-M", + "Lock all pages in memory."); ++ fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-P", ++ "$PATH for ZED to use (only used by ZTS)."); + fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-Z", + "Zero state file."); + fprintf(fp, "\n"); +@@ -247,7 +249,7 @@ _zed_conf_parse_path(char **resultp, const char *path) + void + zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv) + { +- const char * const opts = ":hLVc:d:p:s:vfFMZ"; ++ const char * const opts = ":hLVc:d:p:P:s:vfFMZ"; + int opt; + + if (!zcp || !argv || !argv[0]) +@@ -275,6 +277,9 @@ zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv) + case 'p': + _zed_conf_parse_path(&zcp->pid_file, optarg); + break; ++ case 'P': ++ _zed_conf_parse_path(&zcp->path, optarg); ++ break; + case 's': + _zed_conf_parse_path(&zcp->state_file, optarg); + break; +diff --git a/cmd/zed/zed_event.c b/cmd/zed/zed_event.c +index 390235019..2a7ff16fd 100644 +--- a/cmd/zed/zed_event.c ++++ b/cmd/zed/zed_event.c +@@ -733,12 +733,14 @@ _zed_event_add_nvpair(uint64_t eid, zed_strings_t *zsp, nvpair_t *nvp) + + /* + * Restrict various environment variables to safe and sane values +- * when constructing the environment for the child process. ++ * when constructing the environment for the child process, unless ++ * we're running with a custom $PATH (like under the ZFS test suite). + * + * Reference: Secure Programming Cookbook by Viega & Messier, Section 1.1. + */ + static void +-_zed_event_add_env_restrict(uint64_t eid, zed_strings_t *zsp) ++_zed_event_add_env_restrict(uint64_t eid, zed_strings_t *zsp, ++ const char *path) + { + const char *env_restrict[][2] = { + { "IFS", " \t\n" }, +@@ -753,11 +755,35 @@ _zed_event_add_env_restrict(uint64_t eid, zed_strings_t *zsp) + { "ZFS_RELEASE", ZFS_META_RELEASE }, + { NULL, NULL } + }; ++ ++ /* ++ * If we have a custom $PATH, use the default ZFS binary locations ++ * instead of the hard-coded ones. ++ */ ++ const char *env_path[][2] = { ++ { "IFS", " \t\n" }, ++ { "PATH", NULL }, /* $PATH copied in later on */ ++ { "ZDB", "zdb" }, ++ { "ZED", "zed" }, ++ { "ZFS", "zfs" }, ++ { "ZINJECT", "zinject" }, ++ { "ZPOOL", "zpool" }, ++ { "ZFS_ALIAS", ZFS_META_ALIAS }, ++ { "ZFS_VERSION", ZFS_META_VERSION }, ++ { "ZFS_RELEASE", ZFS_META_RELEASE }, ++ { NULL, NULL } ++ }; + const char *(*pa)[2]; + + assert(zsp != NULL); + +- for (pa = env_restrict; *(*pa); pa++) { ++ pa = path != NULL ? env_path : env_restrict; ++ ++ for (; *(*pa); pa++) { ++ /* Use our custom $PATH if we have one */ ++ if (path != NULL && strcmp((*pa)[0], "PATH") == 0) ++ (*pa)[1] = path; ++ + _zed_event_add_var(eid, zsp, NULL, (*pa)[0], "%s", (*pa)[1]); + } + } +@@ -902,7 +928,7 @@ zed_event_service(struct zed_conf *zcp) + while ((nvp = nvlist_next_nvpair(nvl, nvp))) + _zed_event_add_nvpair(eid, zsp, nvp); + +- _zed_event_add_env_restrict(eid, zsp); ++ _zed_event_add_env_restrict(eid, zsp, zcp->path); + _zed_event_add_env_preserve(eid, zsp); + + _zed_event_add_var(eid, zsp, ZED_VAR_PREFIX, "PID", +diff --git a/cmd/zed/zed.d/resilver_finish-start-scrub.sh b/cmd/zed/zed.d/resilver_finish-start-scrub.sh +new file mode 100755 +index 000000000..6f9c0b309 +--- /dev/null ++++ b/cmd/zed/zed.d/resilver_finish-start-scrub.sh +@@ -0,0 +1,17 @@ ++#!/bin/sh ++# resilver_finish-start-scrub.sh ++# Run a scrub after a resilver ++# ++# Exit codes: ++# 1: Internal error ++# 2: Script wasn't enabled in zed.rc ++[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc" ++. "${ZED_ZEDLET_DIR}/zed-functions.sh" ++ ++[ "${ZED_SCRUB_AFTER_RESILVER}" = "1" ] || exit 2 ++[ -n "${ZEVENT_POOL}" ] || exit 1 ++[ -n "${ZEVENT_SUBCLASS}" ] || exit 1 ++zed_check_cmd "${ZPOOL}" || exit 1 ++ ++zed_log_msg "Starting scrub after resilver on ${ZEVENT_POOL}" ++"${ZPOOL}" scrub "${ZEVENT_POOL}" +diff --git a/cmd/zed/zed.d/zed.rc b/cmd/zed/zed.d/zed.rc +index a1dd33704..8b0e476d5 100644 +--- a/cmd/zed/zed.d/zed.rc ++++ b/cmd/zed/zed.d/zed.rc +@@ -86,6 +86,9 @@ + # + ZED_USE_ENCLOSURE_LEDS=1 + ++## ++# Run a scrub after every resilver ++#ZED_SCRUB_AFTER_RESILVER=1 + + ## + # The syslog priority (e.g., specified as a "facility.level" pair). +diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run +index 8be3e1c62..89c923db1 100644 +--- a/tests/runfiles/linux.run ++++ b/tests/runfiles/linux.run +@@ -421,7 +421,7 @@ tests = ['exec_001_pos', 'exec_002_neg'] + tags = ['functional', 'exec'] + + [tests/functional/fault] +-tests = ['auto_online_001_pos', 'auto_replace_001_pos'] ++tests = ['auto_online_001_pos', 'auto_replace_001_pos', 'scrub_after_resilver'] + tags = ['functional', 'fault'] + + [tests/functional/features/async_destroy] +diff --git a/tests/zfs-tests/include/commands.cfg b/tests/zfs-tests/include/commands.cfg +index f6fd239de..936e54c1a 100644 +--- a/tests/zfs-tests/include/commands.cfg ++++ b/tests/zfs-tests/include/commands.cfg +@@ -83,6 +83,7 @@ export SYSTEM_FILES='arp + pgrep + ping + pkill ++ printenv + printf + ps + pwd +diff --git a/tests/zfs-tests/include/libtest.shlib b/tests/zfs-tests/include/libtest.shlib +index 86f172a6d..48fb5e7c5 100644 +--- a/tests/zfs-tests/include/libtest.shlib ++++ b/tests/zfs-tests/include/libtest.shlib +@@ -3339,9 +3339,32 @@ function wait_replacing #pool + done + } + ++# ++# Wait for a pool to be scrubbed ++# ++# $1 pool name ++# $2 number of seconds to wait (optional) ++# ++# Returns true when pool has been scrubbed, or false if there's a timeout or if ++# no scrub was done. ++# ++function wait_scrubbed ++{ ++ typeset pool=${1:-$TESTPOOL} ++ typeset iter=${2:-10} ++ for i in {1..$iter} ; do ++ if is_pool_scrubbed $pool ; then ++ return 0 ++ fi ++ sleep 1 ++ done ++ return 1 ++} ++ + # + # Setup custom environment for the ZED. + # ++# $@ Optional list of zedlets to run under zed. + function zed_setup + { + if ! is_linux; then +@@ -3359,6 +3382,7 @@ function zed_setup + if [[ -e $VDEVID_CONF_ETC ]]; then + log_fail "Must not have $VDEVID_CONF_ETC file present on system" + fi ++ EXTRA_ZEDLETS=$@ + + # Create a symlink for /etc/zfs/vdev_id.conf file. + log_must ln -s $VDEVID_CONF $VDEVID_CONF_ETC +@@ -3368,32 +3392,44 @@ function zed_setup + log_must cp ${ZEDLET_ETC_DIR}/zed.rc $ZEDLET_DIR + log_must cp ${ZEDLET_ETC_DIR}/zed-functions.sh $ZEDLET_DIR + ++ # Scripts must only be user writable. ++ if [[ -n "$EXTRA_ZEDLETS" ]] ; then ++ saved_umask=$(umask) ++ log_must umask 0022 ++ for i in $EXTRA_ZEDLETS ; do ++ log_must cp ${ZEDLET_LIBEXEC_DIR}/$i $ZEDLET_DIR ++ done ++ log_must umask $saved_umask ++ fi ++ + # Customize the zed.rc file to enable the full debug log. + log_must sed -i '/\#ZED_DEBUG_LOG=.*/d' $ZEDLET_DIR/zed.rc + echo "ZED_DEBUG_LOG=$ZED_DEBUG_LOG" >>$ZEDLET_DIR/zed.rc + +- # Scripts must only be user writable. +- saved_umask=$(umask) +- log_must umask 0022 +- log_must cp ${ZEDLET_LIBEXEC_DIR}/all-syslog.sh $ZEDLET_DIR +- log_must cp ${ZEDLET_LIBEXEC_DIR}/all-debug.sh $ZEDLET_DIR +- log_must umask $saved_umask + } + + # + # Cleanup custom ZED environment. + # ++# $@ Optional list of zedlets to remove from our test zed.d directory. + function zed_cleanup + { + if ! is_linux; then + return + fi ++ EXTRA_ZEDLETS=$@ + + log_must rm -f ${ZEDLET_DIR}/zed.rc + log_must rm -f ${ZEDLET_DIR}/zed-functions.sh + log_must rm -f ${ZEDLET_DIR}/all-syslog.sh + log_must rm -f ${ZEDLET_DIR}/all-debug.sh + log_must rm -f ${ZEDLET_DIR}/state ++ ++ if [[ -n "$EXTRA_ZEDLETS" ]] ; then ++ for i in $EXTRA_ZEDLETS ; do ++ log_must rm -f ${ZEDLET_DIR}/$i ++ done ++ fi + log_must rm -f $ZED_LOG + log_must rm -f $ZED_DEBUG_LOG + log_must rm -f $VDEVID_CONF_ETC +@@ -3425,7 +3461,7 @@ function zed_start + # run ZED in the background and redirect foreground logging + # output to $ZED_LOG. + log_must truncate -s 0 $ZED_DEBUG_LOG +- log_must eval "zed -vF -d $ZEDLET_DIR -p $ZEDLET_DIR/zed.pid" \ ++ log_must eval "zed -vF -d $ZEDLET_DIR -p $ZEDLET_DIR/zed.pid -P $PATH" \ + "-s $ZEDLET_DIR/state 2>$ZED_LOG &" + + return 0 +diff --git a/tests/zfs-tests/tests/functional/events/cleanup.ksh b/tests/zfs-tests/tests/functional/events/cleanup.ksh +index bc536e260..4905342b7 100755 +--- a/tests/zfs-tests/tests/functional/events/cleanup.ksh ++++ b/tests/zfs-tests/tests/functional/events/cleanup.ksh +@@ -26,6 +26,6 @@ + + . $STF_SUITE/include/libtest.shlib + +-zed_cleanup ++zed_cleanup all-debug.sh all-syslog.sh + + default_cleanup +diff --git a/tests/zfs-tests/tests/functional/events/setup.ksh b/tests/zfs-tests/tests/functional/events/setup.ksh +index 7113c1f39..2f81d16b1 100755 +--- a/tests/zfs-tests/tests/functional/events/setup.ksh ++++ b/tests/zfs-tests/tests/functional/events/setup.ksh +@@ -28,6 +28,6 @@ + + DISK=${DISKS%% *} + +-zed_setup ++zed_setup all-debug.sh all-syslog.sh + + default_setup $DISK +diff --git a/tests/zfs-tests/tests/functional/fault/cleanup.ksh b/tests/zfs-tests/tests/functional/fault/cleanup.ksh +index f39f05d6f..d3de742b3 100755 +--- a/tests/zfs-tests/tests/functional/fault/cleanup.ksh ++++ b/tests/zfs-tests/tests/functional/fault/cleanup.ksh +@@ -31,7 +31,7 @@ verify_runnable "global" + cleanup_devices $DISKS + + zed_stop +-zed_cleanup ++zed_cleanup resilver_finish-start-scrub.sh + + SD=$(lsscsi | nawk '/scsi_debug/ {print $6; exit}') + SDDEVICE=$(echo $SD | nawk -F / '{print $3}') +diff --git a/tests/zfs-tests/tests/functional/fault/scrub_after_resilver.ksh b/tests/zfs-tests/tests/functional/fault/scrub_after_resilver.ksh +new file mode 100755 +index 000000000..558cb065f +--- /dev/null ++++ b/tests/zfs-tests/tests/functional/fault/scrub_after_resilver.ksh +@@ -0,0 +1,65 @@ ++#!/bin/ksh -p ++# ++# This file and its contents are supplied under the terms of the ++# Common Development and Distribution License ("CDDL"), version 1.0. ++# You may only use this file in accordance with the terms of version ++# 1.0 of the CDDL. ++# ++# A full copy of the text of the CDDL should have accompanied this ++# source. A copy of the CDDL is also available via the Internet at ++# http://www.illumos.org/license/CDDL. ++# ++ ++# ++# Copyright (c) 2018 by Lawrence Livermore National Security, LLC. ++# All rights reserved. ++# ++ ++. $STF_SUITE/include/libtest.shlib ++. $STF_SUITE/tests/functional/fault/fault.cfg ++ ++# ++# DESCRIPTION: ++# Test the scrub after resilver zedlet ++# ++# STRATEGY: ++# 1. Create a mirrored pool ++# 2. Fault a disk ++# 3. Replace the disk, starting a resilver ++# 4. Verify that a scrub happens after the resilver finishes ++# ++ ++log_assert "Testing the scrub after resilver zedlet" ++ ++# Backup our zed.rc ++zedrc_backup="$(mktemp)" ++log_must cp $ZEDLET_DIR/zed.rc $zedrc_backup ++ ++# Enable ZED_SCRUB_AFTER_RESILVER ++eval "sed -i 's/\#ZED_SCRUB_AFTER_RESILVER/ZED_SCRUB_AFTER_RESILVER/g' $ZEDLET_DIR/zed.rc" ++ ++function cleanup ++{ ++ # Restore our zed.rc ++ log_must mv $zedrc_backup $ZEDLET_DIR/zed.rc ++ default_cleanup_noexit ++} ++ ++log_onexit cleanup ++ ++verify_disk_count "$DISKS" 3 ++default_mirror_setup_noexit $DISK1 $DISK2 ++ ++log_must zpool offline -f $TESTPOOL $DISK1 ++ ++# Write to our degraded pool so we have some data to resilver ++log_must mkfile 16M $TESTDIR/file1 ++ ++# Replace the failed disks, forcing a resilver ++log_must zpool replace $TESTPOOL $DISK1 $DISK3 ++ ++# Wait for the resilver to finish, and then the subsequent scrub to finish. ++# Waiting for the scrub has the effect of waiting for both. Timeout after 10 ++# seconds if nothing is happening. ++log_must wait_scrubbed $TESTPOOL 10 ++log_pass "Successfully ran the scrub after resilver zedlet" +diff --git a/tests/zfs-tests/tests/functional/fault/setup.ksh b/tests/zfs-tests/tests/functional/fault/setup.ksh +index 3d54d4f21..484bc4587 100755 +--- a/tests/zfs-tests/tests/functional/fault/setup.ksh ++++ b/tests/zfs-tests/tests/functional/fault/setup.ksh +@@ -28,7 +28,7 @@ + + verify_runnable "global" + +-zed_setup ++zed_setup resilver_finish-start-scrub.sh + zed_start + + # Create a scsi_debug device to be used with auto-online (if using loop devices) +-- +2.14.2 + diff --git a/zfs-patches/0043-Add-SMART-self-test-results-to-zpool-status-c.patch b/zfs-patches/0043-Add-SMART-self-test-results-to-zpool-status-c.patch new file mode 100644 index 0000000..a562ecd --- /dev/null +++ b/zfs-patches/0043-Add-SMART-self-test-results-to-zpool-status-c.patch @@ -0,0 +1,322 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tony Hutter +Date: Tue, 27 Feb 2018 09:31:27 -0800 +Subject: [PATCH] Add SMART self-test results to zpool status -c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add in SMART self-test results to zpool status|iostat -c. This +works for both SAS and SATA drives. + +Also, add plumbing to allow the 'smart' script to take smartctl +output from a directory of output text files instead of running +it against the vdevs. + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Signed-off-by: Tony Hutter +Closes #7178 +(cherry picked from commit 5e3085e360161456fe2af697494c479de0ee2085) +Signed-off-by: Fabian Grünbichler +--- + cmd/zpool/Makefile.am | 14 ++++- + cmd/zpool/zpool.d/smart | 132 +++++++++++++++++++++++++++++++++++----- + cmd/zpool/zpool.d/smart_test | 1 + + cmd/zpool/zpool.d/test_ended | 1 + + cmd/zpool/zpool.d/test_progress | 1 + + cmd/zpool/zpool.d/test_status | 1 + + cmd/zpool/zpool.d/test_type | 1 + + 7 files changed, 133 insertions(+), 18 deletions(-) + create mode 120000 cmd/zpool/zpool.d/smart_test + create mode 120000 cmd/zpool/zpool.d/test_ended + create mode 120000 cmd/zpool/zpool.d/test_progress + create mode 120000 cmd/zpool/zpool.d/test_status + create mode 120000 cmd/zpool/zpool.d/test_type + +diff --git a/cmd/zpool/Makefile.am b/cmd/zpool/Makefile.am +index c7b8b76e3..d07f8d616 100644 +--- a/cmd/zpool/Makefile.am ++++ b/cmd/zpool/Makefile.am +@@ -63,7 +63,12 @@ dist_zpoolexec_SCRIPTS = \ + zpool.d/nvme_err \ + zpool.d/pwr_cyc \ + zpool.d/upath \ +- zpool.d/vendor ++ zpool.d/vendor \ ++ zpool.d/smart_test \ ++ zpool.d/test_type \ ++ zpool.d/test_status \ ++ zpool.d/test_progress \ ++ zpool.d/test_ended + + zpoolconfdefaults = \ + enc \ +@@ -102,7 +107,12 @@ zpoolconfdefaults = \ + nvme_err \ + pwr_cyc \ + upath \ +- vendor ++ vendor \ ++ smart_test \ ++ test_type \ ++ test_status \ ++ test_progress \ ++ test_ended + + install-data-hook: + $(MKDIR_P) "$(DESTDIR)$(zpoolconfdir)" +diff --git a/cmd/zpool/zpool.d/smart b/cmd/zpool/zpool.d/smart +index 4bc3af39d..64b5f6e4e 100755 +--- a/cmd/zpool/zpool.d/smart ++++ b/cmd/zpool/zpool.d/smart +@@ -24,8 +24,44 @@ ata_err: Show SMART ATA errors (ATA). + pwr_cyc: Show SMART power cycle count (ATA). + serial: Show disk serial number. + nvme_err: Show SMART NVMe errors (NVMe). ++smart_test: Show SMART self-test results summary. ++test_type: Show SMART self-test type (short, long... ). ++test_status: Show SMART self-test status. ++test_progress: Show SMART self-test percentage done. ++test_ended: Show when the last SMART self-test ended (if supported). + " + ++# Hack for developer testing ++# ++# If you set $samples to a directory containing smartctl output text files, ++# we will use them instead of running smartctl on the vdevs. This can be ++# useful if you want to test a bunch of different smartctl outputs. Also, if ++# $samples is set, and additional 'file' column is added to the zpool output ++# showing the filename. ++samples= ++ ++# get_filename_from_dir DIR ++# ++# Look in directory DIR and return a filename from it. The filename returned ++# is chosen quasi-sequentially (based off our PID). This allows us to return ++# a different filename every time this script is invoked (which we do for each ++# vdev), without having to maintain state. ++get_filename_from_dir() ++{ ++ dir=$1 ++ pid="$$" ++ num_files=$(find "$dir" -maxdepth 1 -type f | wc -l) ++ mod=$((pid % num_files)) ++ i=0 ++ find "$dir" -type f -printf "%f\n" | while read -r file ; do ++ if [ "$mod" = "$i" ] ; then ++ echo "$file" ++ break ++ fi ++ i=$((i+1)) ++ done ++} ++ + script=$(basename "$0") + + if [ "$1" = "-h" ] ; then +@@ -35,8 +71,16 @@ fi + + smartctl_path=$(which smartctl) + +-if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ]; then +- raw_out=$(eval "sudo $smartctl_path -a $VDEV_UPATH") ++if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ] || [ -n "$samples" ] ; then ++ if [ -n "$samples" ] ; then ++ # cat a smartctl output text file instead of running smartctl ++ # on a vdev (only used for developer testing). ++ file=$(get_filename_from_dir $samples) ++ echo "file=$file" ++ raw_out=$(cat "$samples/$file") ++ else ++ raw_out=$(eval "sudo $smartctl_path -a $VDEV_UPATH") ++ fi + + # What kind of drive are we? Look for the right line in smartctl: + # +@@ -49,7 +93,6 @@ if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ]; then + # NVMe: + # SMART/Health Information (NVMe Log 0xnn, NSID 0xnn) + # +- type=$(echo "$raw_out" | grep -m 1 -Eo '^ATA|NVMe|SAS$') + out=$(echo "$raw_out" | awk ' + # SAS specific + /read:/{print "rrd="$4"\nr_cor="$5"\nr_proc="$7"\nr_ucor="$8} +@@ -58,10 +101,11 @@ if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ]; then + /Elements in grown defect list/{print "defect="$6} + + # SAS common ++/SAS/{type="sas"} + /Drive Temperature:/{print "temp="$4} + # Status can be a long string, substitute spaces for '_' + /SMART Health Status:/{printf "health="; for(i=4;i<=NF-1;i++){printf "%s_", $i}; printf "%s\n", $i} +-/number of hours powered up/{print "hours_on="$7} ++/number of hours powered up/{print "hours_on="$7; hours_on=int($7)} + /Serial number:/{print "serial="$3} + + # SATA specific +@@ -74,13 +118,16 @@ if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ]; then + /Power_Cycle_Count/{print "pwr_cyc="$10} + + # SATA common ++/SATA/{type="sata"} + /Temperature_Celsius/{print "temp="$10} + /Airflow_Temperature_Cel/{print "temp="$10} ++/Current Temperature:/{print "temp="$3} + /SMART overall-health self-assessment test result:/{print "health="$6} +-/Power_On_Hours/{print "hours_on="$10} ++/Power_On_Hours/{print "hours_on="$10; hours_on=int($10)} + /Serial Number:/{print "serial="$3} + + # NVMe common ++/NVMe/{type="nvme"} + /Temperature:/{print "temp="$2} + /SMART overall-health self-assessment test result:/{print "health="$6} + /Power On Hours:/{gsub("[^0-9]","",$4); print "hours_on="$4} +@@ -90,39 +137,92 @@ if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ]; then + # NVMe specific + /Media and Data Integrity Errors:/{print "nvme_err="$6} + +-END {ORS="\n"; print ""} ++# SMART self-test info ++/Self-test execution status:/{progress=tolower($4)} # SAS ++/SMART Self-test log/{test_seen=1} # SAS ++/SMART Extended Self-test Log/{test_seen=1} # SATA ++/# 1/{ ++ test_type=tolower($3"_"$4); ++ # Status could be one word ("Completed") or multiple ("Completed: read ++ # failure"). Look for the ":" to see if we need to grab more words. ++ ++ if ($5 ~ ":") ++ status=tolower($5""$6"_"$7) ++ else ++ status=tolower($5) ++ if (status=="self") ++ status="running"; ++ ++ if (type == "sas") { ++ hours=int($(NF-4)) ++ } else { ++ hours=int($(NF-1)) ++ # SATA reports percent remaining, rather than percent done ++ # Convert it to percent done. ++ progress=(100-int($(NF-2)))"%" ++ } ++ # When we int()-ify "hours", it converts stuff like "NOW" and "-" into ++ # 0. In those cases, set it to hours_on, so they will cancel out in ++ # the "hours_ago" calculation later on. ++ if (hours == 0) ++ hours=hours_on ++ ++ if (test_seen) { ++ print "test="hours_on ++ print "test_type="test_type ++ print "test_status="status ++ print "test_progress="progress ++ } ++ # Not all drives report hours_on ++ if (hours_on && hours) { ++ total_hours_ago=(hours_on-hours) ++ days_ago=int(total_hours_ago/24) ++ hours_ago=(total_hours_ago % 24) ++ if (days_ago != 0) ++ ago_str=days_ago"d" ++ if (hours_ago !=0) ++ ago_str=ago_str""hours_ago"h" ++ print "test_ended="ago_str ++ } ++} ++ ++END {print "type="type; ORS="\n"; print ""} + '); + fi ++type=$(echo "$out" | grep '^type=' | cut -d '=' -f 2) + +-# if type is not set by now, either we don't have a block device +-# or smartctl failed. Either way, default to ATA and set out to +-# nothing ++# If type is not set by now, either we don't have a block device ++# or smartctl failed. Either way, default to ATA and set $out to ++# nothing. + if [ -z "$type" ]; then +- type="ATA" ++ type="sata" + out= + fi + + case $script in + smart) + # Print temperature plus common predictors of drive failure +- if [ "$type" = "SAS" ] ; then ++ if [ "$type" = "sas" ] ; then + scripts="temp|health|r_ucor|w_ucor" +- elif [ "$type" = "ATA" ] ; then ++ elif [ "$type" = "sata" ] ; then + scripts="temp|health|ata_err|realloc|rep_ucor|cmd_to|pend_sec|off_ucor" +- elif [ "$type" = "NVMe" ] ; then ++ elif [ "$type" = "nvme" ] ; then + scripts="temp|health|nvme_err" + fi + ;; + smartx) + # Print some other interesting stats +- if [ "$type" = "SAS" ] ; then ++ if [ "$type" = "sas" ] ; then + scripts="hours_on|defect|nonmed|r_proc|w_proc" +- elif [ "$type" = "ATA" ] ; then ++ elif [ "$type" = "sata" ] ; then + scripts="hours_on|pwr_cyc" +- elif [ "$type" = "NVMe" ] ; then ++ elif [ "$type" = "nvme" ] ; then + scripts="hours_on|pwr_cyc" + fi + ;; ++smart_test) ++ scripts="test_type|test_status|test_progress|test_ended" ++ ;; + *) + scripts="$script" + esac +diff --git a/cmd/zpool/zpool.d/smart_test b/cmd/zpool/zpool.d/smart_test +new file mode 120000 +index 000000000..94f22861f +--- /dev/null ++++ b/cmd/zpool/zpool.d/smart_test +@@ -0,0 +1 @@ ++smart +\ No newline at end of file +diff --git a/cmd/zpool/zpool.d/test_ended b/cmd/zpool/zpool.d/test_ended +new file mode 120000 +index 000000000..94f22861f +--- /dev/null ++++ b/cmd/zpool/zpool.d/test_ended +@@ -0,0 +1 @@ ++smart +\ No newline at end of file +diff --git a/cmd/zpool/zpool.d/test_progress b/cmd/zpool/zpool.d/test_progress +new file mode 120000 +index 000000000..94f22861f +--- /dev/null ++++ b/cmd/zpool/zpool.d/test_progress +@@ -0,0 +1 @@ ++smart +\ No newline at end of file +diff --git a/cmd/zpool/zpool.d/test_status b/cmd/zpool/zpool.d/test_status +new file mode 120000 +index 000000000..94f22861f +--- /dev/null ++++ b/cmd/zpool/zpool.d/test_status +@@ -0,0 +1 @@ ++smart +\ No newline at end of file +diff --git a/cmd/zpool/zpool.d/test_type b/cmd/zpool/zpool.d/test_type +new file mode 120000 +index 000000000..94f22861f +--- /dev/null ++++ b/cmd/zpool/zpool.d/test_type +@@ -0,0 +1 @@ ++smart +\ No newline at end of file +-- +2.14.2 + diff --git a/zfs-patches/0044-Fix-zpool-8-list-example-to-match-actual-format.patch b/zfs-patches/0044-Fix-zpool-8-list-example-to-match-actual-format.patch new file mode 100644 index 0000000..6817629 --- /dev/null +++ b/zfs-patches/0044-Fix-zpool-8-list-example-to-match-actual-format.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tomohiro Kusumi +Date: Thu, 1 Mar 2018 01:54:53 +0900 +Subject: [PATCH] Fix zpool(8) list example to match actual format +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +a05dfd00 (Illumos 5147) has swapped FRAG and EXPANDSZ, +so it's natural to modify these examples. + + # zpool list | head -1 + NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT + ^^^^^^^^^^^^^^^ + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Signed-off-by: Tomohiro Kusumi +Closes #7244 +(cherry picked from commit bcaba38e428be8dc90564d15c7e13f154c535edd) +Signed-off-by: Fabian Grünbichler +--- + man/man8/zpool.8 | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/man/man8/zpool.8 b/man/man8/zpool.8 +index 22579101a..7c99f5868 100644 +--- a/man/man8/zpool.8 ++++ b/man/man8/zpool.8 +@@ -2087,10 +2087,10 @@ is faulted due to a missing device. + The results from this command are similar to the following: + .Bd -literal + # zpool list +-NAME SIZE ALLOC FREE FRAG EXPANDSZ CAP DEDUP HEALTH ALTROOT +-rpool 19.9G 8.43G 11.4G 33% - 42% 1.00x ONLINE - +-tank 61.5G 20.0G 41.5G 48% - 32% 1.00x ONLINE - +-zion - - - - - - - FAULTED - ++NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT ++rpool 19.9G 8.43G 11.4G - 33% 42% 1.00x ONLINE - ++tank 61.5G 20.0G 41.5G - 48% 32% 1.00x ONLINE - ++zion - - - - - - - FAULTED - + .Ed + .It Sy Example 7 No Destroying a ZFS Storage Pool + The following command destroys the pool +@@ -2215,12 +2215,12 @@ In this example, the pool will not be able to utilize this extra capacity until + all the devices under the raidz vdev have been expanded. + .Bd -literal + # zpool list -v data +-NAME SIZE ALLOC FREE FRAG EXPANDSZ CAP DEDUP HEALTH ALTROOT +-data 23.9G 14.6G 9.30G 48% - 61% 1.00x ONLINE - +- raidz1 23.9G 14.6G 9.30G 48% - +- sda - - - - - +- sdb - - - - 10G +- sdc - - - - - ++NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT ++data 23.9G 14.6G 9.30G - 48% 61% 1.00x ONLINE - ++ raidz1 23.9G 14.6G 9.30G - 48% ++ sda - - - - - ++ sdb - - - 10G - ++ sdc - - - - - + .Ed + .It Sy Example 16 No Adding output columns + Additional columns can be added to the +-- +2.14.2 + diff --git a/zfs-patches/0045-Fix-some-typos.patch b/zfs-patches/0045-Fix-some-typos.patch new file mode 100644 index 0000000..43da44d --- /dev/null +++ b/zfs-patches/0045-Fix-some-typos.patch @@ -0,0 +1,275 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: John Eismeier <32205350+jeis2497052@users.noreply.github.com> +Date: Wed, 28 Feb 2018 11:57:10 -0500 +Subject: [PATCH] Fix some typos +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Brian Behlendorf +Reviewed by: George Melikov +Signed-off-by: John Eismeier +Closes #7237 +(cherry picked from commit 33bb1e82568a9734cc3f41d3e1d33003ebf0e123) +Signed-off-by: Fabian Grünbichler +--- + cmd/arcstat/arcstat.py | 4 ++-- + cmd/dbufstat/dbufstat.py | 4 ++-- + contrib/initramfs/scripts/zfs | 2 +- + man/man8/zpool.8 | 2 +- + tests/zfs-tests/tests/functional/migration/migration_001_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_002_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_003_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_004_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_005_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_006_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_007_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_008_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_009_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_010_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_011_pos.ksh | 4 ++-- + tests/zfs-tests/tests/functional/migration/migration_012_pos.ksh | 4 ++-- + 16 files changed, 30 insertions(+), 30 deletions(-) + +diff --git a/cmd/arcstat/arcstat.py b/cmd/arcstat/arcstat.py +index aa54ee87a..85c83ccc4 100755 +--- a/cmd/arcstat/arcstat.py ++++ b/cmd/arcstat/arcstat.py +@@ -280,7 +280,7 @@ def init(): + "outfile", + "help", + "verbose", +- "seperator", ++ "separator", + "columns" + ] + ) +@@ -299,7 +299,7 @@ def init(): + hflag = True + if opt in ('-v', '--verbose'): + vflag = True +- if opt in ('-s', '--seperator'): ++ if opt in ('-s', '--separator'): + sep = arg + i += 1 + if opt in ('-f', '--columns'): +diff --git a/cmd/dbufstat/dbufstat.py b/cmd/dbufstat/dbufstat.py +index dda0a143f..42bb0c7c7 100755 +--- a/cmd/dbufstat/dbufstat.py ++++ b/cmd/dbufstat/dbufstat.py +@@ -474,7 +474,7 @@ def main(): + "help", + "infile", + "outfile", +- "seperator", ++ "separator", + "types", + "verbose", + "extended" +@@ -499,7 +499,7 @@ def main(): + ofile = arg + if opt in ('-r', '--raw'): + raw += 1 +- if opt in ('-s', '--seperator'): ++ if opt in ('-s', '--separator'): + sep = arg + if opt in ('-t', '--types'): + tflag = True +diff --git a/contrib/initramfs/scripts/zfs b/contrib/initramfs/scripts/zfs +index 8770a2e8e..86329e764 100644 +--- a/contrib/initramfs/scripts/zfs ++++ b/contrib/initramfs/scripts/zfs +@@ -478,7 +478,7 @@ destroy_fs() + echo "Message: $ZFS_STDERR" + echo "Error: $ZFS_ERROR" + echo "" +- echo "Failed to destroy '$fs'. Please make sure that '$fs' is not availible." ++ echo "Failed to destroy '$fs'. Please make sure that '$fs' is not available." + echo "Hint: Try: zfs destroy -Rfn $fs" + echo "If this dryrun looks good, then remove the 'n' from '-Rfn' and try again." + /bin/sh +diff --git a/man/man8/zpool.8 b/man/man8/zpool.8 +index 7c99f5868..6d7c2271c 100644 +--- a/man/man8/zpool.8 ++++ b/man/man8/zpool.8 +@@ -733,7 +733,7 @@ man page. In order to enable this property each host must set a unique hostid. + See + .Xr genhostid 1 + .Xr zgenhostid 8 +-.Xr spl-module-paramters 5 ++.Xr spl-module-parameters 5 + for additional details. The default value is + .Sy off . + .It Sy version Ns = Ns Ar version +diff --git a/tests/zfs-tests/tests/functional/migration/migration_001_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_001_pos.ksh +index 4d5fbb9ff..875d2f7c7 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_001_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_001_pos.ksh +@@ -60,7 +60,7 @@ prepare $DNAME "tar cf $TESTDIR/tar$$.tar $BNAME" + (( $? != 0 )) && log_fail "Unable to create src archive" + + migrate $TESTDIR $SUMA $SUMB "tar xf $TESTDIR/tar$$.tar" +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to ZFS fs" + +-log_pass "Successully migrated test file from ZFS fs to ZFS fs". ++log_pass "Successfully migrated test file from ZFS fs to ZFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_002_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_002_pos.ksh +index e0655248d..6b97e2a40 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_002_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_002_pos.ksh +@@ -60,7 +60,7 @@ prepare $DNAME "tar cf $TESTDIR/tar$$.tar $BNAME" + (( $? != 0 )) && log_fail "Unable to create src archive" + + migrate $NONZFS_TESTDIR $SUMA $SUMB "tar xf $TESTDIR/tar$$.tar" +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to UFS fs" + +-log_pass "Successully migrated test file from ZFS fs to UFS fs". ++log_pass "Successfully migrated test file from ZFS fs to UFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_003_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_003_pos.ksh +index 904a2b1a0..dd0baeaa9 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_003_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_003_pos.ksh +@@ -60,7 +60,7 @@ prepare $DNAME "tar cf $NONZFS_TESTDIR/tar$$.tar $BNAME" + (( $? != 0 )) && log_fail "Unable to create src archive" + + migrate $TESTDIR $SUMA $SUMB "tar xvf $NONZFS_TESTDIR/tar$$.tar" +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "UFS fs to ZFS fs" + +-log_pass "Successully migrated test file from UFS fs to ZFS fs". ++log_pass "Successfully migrated test file from UFS fs to ZFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_004_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_004_pos.ksh +index 6d33dd5b3..00a6cc172 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_004_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_004_pos.ksh +@@ -67,7 +67,7 @@ cd $cwd + (( $? != 0 )) && log_untested "Could not change directory to $cwd" + + migrate_cpio $TESTDIR "$TESTDIR/cpio$$.cpio" $SUMA $SUMB +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to ZFS fs" + +-log_pass "Successully migrated test file from ZFS fs to ZFS fs". ++log_pass "Successfully migrated test file from ZFS fs to ZFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_005_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_005_pos.ksh +index a41b19b5f..4386596f7 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_005_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_005_pos.ksh +@@ -67,7 +67,7 @@ cd $cwd + (( $? != 0 )) && log_untested "Could not change directory to $cwd" + + migrate_cpio $NONZFS_TESTDIR "$TESTDIR/cpio$$.cpio" $SUMA $SUMB +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to UFS fs" + +-log_pass "Successully migrated test file from ZFS fs to UFS fs". ++log_pass "Successfully migrated test file from ZFS fs to UFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_006_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_006_pos.ksh +index 5b444421a..9b5c9166e 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_006_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_006_pos.ksh +@@ -67,7 +67,7 @@ cd $cwd + (( $? != 0 )) && log_untested "Could not change directory to $cwd" + + migrate_cpio $TESTDIR "$NONZFS_TESTDIR/cpio$$.cpio" $SUMA $SUMB +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to ZFS fs" + +-log_pass "Successully migrated test file from UFS fs to ZFS fs". ++log_pass "Successfully migrated test file from UFS fs to ZFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_007_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_007_pos.ksh +index c3197052c..0d136550f 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_007_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_007_pos.ksh +@@ -60,7 +60,7 @@ prepare $DNAME "dd if=$BNAME obs=128k of=$TESTDIR/dd$$.dd" + (( $? != 0 )) && log_fail "Unable to create src archive" + + migrate $TESTDIR $SUMA $SUMB "dd if=$TESTDIR/dd$$.dd obs=128k of=$BNAME" +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to ZFS fs" + +-log_pass "Successully migrated test file from ZFS fs to ZFS fs". ++log_pass "Successfully migrated test file from ZFS fs to ZFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_008_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_008_pos.ksh +index 2e51eef36..f62b1f33a 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_008_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_008_pos.ksh +@@ -60,7 +60,7 @@ prepare $DNAME "dd if=$BNAME obs=128k of=$TESTDIR/dd$$.dd" + (( $? != 0 )) && log_fail "Unable to create src archive" + + migrate $NONZFS_TESTDIR $SUMA $SUMB "dd if=$TESTDIR/dd$$.dd obs=128k of=$BNAME" +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to ZFS fs" + +-log_pass "Successully migrated test file from ZFS fs to UFS fs". ++log_pass "Successfully migrated test file from ZFS fs to UFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_009_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_009_pos.ksh +index 7749494e5..907be39eb 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_009_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_009_pos.ksh +@@ -60,7 +60,7 @@ prepare $DNAME "dd if=$BNAME obs=128k of=$NONZFS_TESTDIR/dd$$.dd" + (( $? != 0 )) && log_fail "Unable to create src archive" + + migrate $TESTDIR $SUMA $SUMB "dd if=$NONZFS_TESTDIR/dd$$.dd obs=128k of=$BNAME" +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to ZFS fs" + +-log_pass "Successully migrated test file from UFS fs to ZFS fs". ++log_pass "Successfully migrated test file from UFS fs to ZFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_010_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_010_pos.ksh +index a11ab72df..e80dd67cd 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_010_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_010_pos.ksh +@@ -60,7 +60,7 @@ prepare $DNAME "cp $BNAME $TESTDIR/cp$$.cp" + (( $? != 0 )) && log_fail "Unable to create src archive" + + migrate $TESTDIR $SUMA $SUMB "cp $TESTDIR/cp$$.cp $BNAME" +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to ZFS fs" + +-log_pass "Successully migrated test file from ZFS fs to ZFS fs". ++log_pass "Successfully migrated test file from ZFS fs to ZFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_011_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_011_pos.ksh +index 17e1c78f9..2d7ecb45e 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_011_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_011_pos.ksh +@@ -60,7 +60,7 @@ prepare $DNAME "cp $BNAME $TESTDIR/cp$$.cp" + (( $? != 0 )) && log_fail "Unable to create src archive" + + migrate $NONZFS_TESTDIR $SUMA $SUMB "cp $TESTDIR/cp$$.cp $BNAME" +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "ZFS fs to UFS fs" + +-log_pass "Successully migrated test file from ZFS fs to UFS fs". ++log_pass "Successfully migrated test file from ZFS fs to UFS fs". +diff --git a/tests/zfs-tests/tests/functional/migration/migration_012_pos.ksh b/tests/zfs-tests/tests/functional/migration/migration_012_pos.ksh +index 823dabeae..fd9c45491 100755 +--- a/tests/zfs-tests/tests/functional/migration/migration_012_pos.ksh ++++ b/tests/zfs-tests/tests/functional/migration/migration_012_pos.ksh +@@ -60,7 +60,7 @@ prepare $DNAME "cp $BNAME $NONZFS_TESTDIR/cp$$.cp" + (( $? != 0 )) && log_fail "Unable to create src archive" + + migrate $TESTDIR $SUMA $SUMB "cp $NONZFS_TESTDIR/cp$$.cp $BNAME" +-(( $? != 0 )) && log_fail "Uable to successfully migrate test file from" \ ++(( $? != 0 )) && log_fail "Unable to successfully migrate test file from" \ + "UFS fs to ZFS fs" + +-log_pass "Successully migrated test file from UFS fs to ZFS fs". ++log_pass "Successfully migrated test file from UFS fs to ZFS fs". +-- +2.14.2 + diff --git a/zfs-patches/0046-Increment-zil_itx_needcopy_bytes-properly.patch b/zfs-patches/0046-Increment-zil_itx_needcopy_bytes-properly.patch new file mode 100644 index 0000000..f66d8db --- /dev/null +++ b/zfs-patches/0046-Increment-zil_itx_needcopy_bytes-properly.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: chrisrd +Date: Sat, 3 Mar 2018 05:01:53 +1100 +Subject: [PATCH] Increment zil_itx_needcopy_bytes properly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In zil_lwb_commit() with TX_WRITE, we copy the log write record (lrw) +into the log write block (lwb) and send it off using zil_lwb_add_txg(). +If we also have WR_NEED_COPY, we additionally copy the lwr's data into +the lwb to be sent off. If the lwr + data doesn't fit into the lwb, we +send the lrw and as much data as will fit (dnow bytes), then go back +and do the same with the remaining data. + +Each time through this loop we're sending dnow data bytes. I.e. +zil_itx_needcopy_bytes should be incremented by dnow. + +Reviewed-by: Richard Elling +Reviewed-by: Brian Behlendorf +Signed-off-by: Chris Dunlop +Closes #6988 +Closes #7176 +(cherry picked from commit 792f88131c647a70440c709c78d43210db6c6534) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/zil.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/module/zfs/zil.c b/module/zfs/zil.c +index 4d714cefc..645b1d4d8 100644 +--- a/module/zfs/zil.c ++++ b/module/zfs/zil.c +@@ -1167,8 +1167,7 @@ cont: + lrw->lr_offset += dnow; + lrw->lr_length -= dnow; + ZIL_STAT_BUMP(zil_itx_needcopy_count); +- ZIL_STAT_INCR(zil_itx_needcopy_bytes, +- lrw->lr_length); ++ ZIL_STAT_INCR(zil_itx_needcopy_bytes, dnow); + } else { + ASSERT(itx->itx_wr_state == WR_INDIRECT); + dbuf = NULL; +-- +2.14.2 + diff --git a/zfs-patches/0047-Change-checksum-IO-delay-ratelimit-values.patch b/zfs-patches/0047-Change-checksum-IO-delay-ratelimit-values.patch new file mode 100644 index 0000000..0c36c60 --- /dev/null +++ b/zfs-patches/0047-Change-checksum-IO-delay-ratelimit-values.patch @@ -0,0 +1,201 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tony Hutter +Date: Sun, 4 Mar 2018 17:34:51 -0800 +Subject: [PATCH] Change checksum & IO delay ratelimit values +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Change checksum & IO delay ratelimit thresholds from 5/sec to 20/sec. +This allows zed to actually trigger if a bunch of these events arrive in +a short period of time (zed has a threshold of 10 events in 10 sec). +Previously, if you had, say, 100 checksum errors in 1 sec, it would get +ratelimited to 5/sec which wouldn't trigger zed to fault the drive. + +Also, convert the checksum and IO delay thresholds to module params for +easy testing. + +Reviewed-by: loli10K +Reviewed-by: Brian Behlendorf +Reviewed-by: Giuseppe Di Natale +Signed-off-by: Tony Hutter +Closes #7252 +(cherry picked from commit 6dc40e2ada2d0d008bd314ff3525f2b0acc2bb01) +Signed-off-by: Fabian Grünbichler +--- + include/sys/vdev_impl.h | 2 -- + include/sys/zfs_ratelimit.h | 12 +++++++++--- + module/zcommon/zfs_comutil.c | 4 ++-- + module/zfs/vdev.c | 23 +++++++++++++++++++++-- + man/man5/zfs-module-parameters.5 | 39 +++++++++++++++++++++++++++++++++++++++ + 5 files changed, 71 insertions(+), 9 deletions(-) + +diff --git a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h +index 13c495822..4f9f1a903 100644 +--- a/include/sys/vdev_impl.h ++++ b/include/sys/vdev_impl.h +@@ -255,8 +255,6 @@ struct vdev { + * We rate limit ZIO delay and ZIO checksum events, since they + * can flood ZED with tons of events when a drive is acting up. + */ +-#define DELAYS_PER_SECOND 5 +-#define CHECKSUMS_PER_SECOND 5 + zfs_ratelimit_t vdev_delay_rl; + zfs_ratelimit_t vdev_checksum_rl; + }; +diff --git a/include/sys/zfs_ratelimit.h b/include/sys/zfs_ratelimit.h +index f36e07841..012825fad 100644 +--- a/include/sys/zfs_ratelimit.h ++++ b/include/sys/zfs_ratelimit.h +@@ -25,13 +25,19 @@ + typedef struct { + hrtime_t start; + unsigned int count; +- unsigned int burst; /* Number to allow per interval */ +- unsigned int interval; /* Interval length in seconds */ ++ ++ /* ++ * Pointer to number of events per interval. We do this to ++ * allow the burst to be a (changeable) module parameter. ++ */ ++ unsigned int *burst; ++ ++ unsigned int interval; /* Interval length in seconds */ + kmutex_t lock; + } zfs_ratelimit_t; + + int zfs_ratelimit(zfs_ratelimit_t *rl); +-void zfs_ratelimit_init(zfs_ratelimit_t *rl, unsigned int burst, ++void zfs_ratelimit_init(zfs_ratelimit_t *rl, unsigned int *burst, + unsigned int interval); + void zfs_ratelimit_fini(zfs_ratelimit_t *rl); + +diff --git a/module/zcommon/zfs_comutil.c b/module/zcommon/zfs_comutil.c +index 52cb7e365..44cdc8523 100644 +--- a/module/zcommon/zfs_comutil.c ++++ b/module/zcommon/zfs_comutil.c +@@ -215,7 +215,7 @@ const char *zfs_history_event_names[ZFS_NUM_LEGACY_HISTORY_EVENTS] = { + * interval: Interval time in seconds + */ + void +-zfs_ratelimit_init(zfs_ratelimit_t *rl, unsigned int burst, ++zfs_ratelimit_init(zfs_ratelimit_t *rl, unsigned int *burst, + unsigned int interval) + { + rl->count = 0; +@@ -270,7 +270,7 @@ zfs_ratelimit(zfs_ratelimit_t *rl) + rl->start = now; + rl->count = 0; + } else { +- if (rl->count >= rl->burst) { ++ if (rl->count >= *rl->burst) { + rc = 0; /* We're ratelimiting */ + } + } +diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c +index df07d893d..0786fbb83 100644 +--- a/module/zfs/vdev.c ++++ b/module/zfs/vdev.c +@@ -56,6 +56,16 @@ + */ + int metaslabs_per_vdev = 200; + ++/* ++ * Rate limit delay events to this many IO delays per second. ++ */ ++unsigned int zfs_delays_per_second = 20; ++ ++/* ++ * Rate limit checksum events after this many checksum errors per second. ++ */ ++unsigned int zfs_checksums_per_second = 20; ++ + /* + * Virtual device management. + */ +@@ -357,8 +367,8 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops) + * and checksum events so that we don't overwhelm ZED with thousands + * of events when a disk is acting up. + */ +- zfs_ratelimit_init(&vd->vdev_delay_rl, DELAYS_PER_SECOND, 1); +- zfs_ratelimit_init(&vd->vdev_checksum_rl, CHECKSUMS_PER_SECOND, 1); ++ zfs_ratelimit_init(&vd->vdev_delay_rl, &zfs_delays_per_second, 1); ++ zfs_ratelimit_init(&vd->vdev_checksum_rl, &zfs_checksums_per_second, 1); + + list_link_init(&vd->vdev_config_dirty_node); + list_link_init(&vd->vdev_state_dirty_node); +@@ -3776,5 +3786,14 @@ module_param(metaslabs_per_vdev, int, 0644); + MODULE_PARM_DESC(metaslabs_per_vdev, + "Divide added vdev into approximately (but no more than) this number " + "of metaslabs"); ++ ++module_param(zfs_delays_per_second, uint, 0644); ++MODULE_PARM_DESC(zfs_delays_per_second, "Rate limit delay events to this many " ++ "IO delays per second"); ++ ++module_param(zfs_checksums_per_second, uint, 0644); ++ MODULE_PARM_DESC(zfs_checksums_per_second, "Rate limit checksum events " ++ "to this many checksum errors per second (do not set below zed" ++ "threshold)."); + /* END CSTYLED */ + #endif +diff --git a/man/man5/zfs-module-parameters.5 b/man/man5/zfs-module-parameters.5 +index d4daffde6..8d5ac2576 100644 +--- a/man/man5/zfs-module-parameters.5 ++++ b/man/man5/zfs-module-parameters.5 +@@ -739,6 +739,34 @@ Disable pool import at module load by ignoring the cache file (typically \fB/etc + Use \fB1\fR for yes (default) and \fB0\fR for no. + .RE + ++.sp ++.ne 2 ++.na ++\fBzfs_checksums_per_second\fR (int) ++.ad ++.RS 12n ++Rate limit checksum events to this many per second. Note that this should ++not be set below the zed thresholds (currently 10 checksums over 10 sec) ++or else zed may not trigger any action. ++.sp ++Default value: 20 ++.RE ++ ++.sp ++.ne 2 ++.na ++\fBzfs_commit_timeout_pct\fR (int) ++.ad ++.RS 12n ++This controls the amount of time that a ZIL block (lwb) will remain "open" ++when it isn't "full", and it has a thread waiting for it to be committed to ++stable storage. The timeout is scaled based on a percentage of the last lwb ++latency to avoid significantly impacting the latency of each individual ++transaction record (itx). ++.sp ++Default value: \fB5\fR%. ++.RE ++ + .sp + .ne 2 + .na +@@ -866,6 +894,17 @@ Note: \fBzfs_delay_scale\fR * \fBzfs_dirty_data_max\fR must be < 2^64. + Default value: \fB500,000\fR. + .RE + ++.sp ++.ne 2 ++.na ++\fBzfs_delays_per_second\fR (int) ++.ad ++.RS 12n ++Rate limit IO delay events to this many per second. ++.sp ++Default value: 20 ++.RE ++ + .sp + .ne 2 + .na +-- +2.14.2 + diff --git a/zfs-patches/0048-Linux-4.16-compat-get_disk_and_module.patch b/zfs-patches/0048-Linux-4.16-compat-get_disk_and_module.patch new file mode 100644 index 0000000..93acdef --- /dev/null +++ b/zfs-patches/0048-Linux-4.16-compat-get_disk_and_module.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Giuseppe Di Natale +Date: Mon, 5 Mar 2018 12:44:35 -0800 +Subject: [PATCH] Linux 4.16 compat: get_disk_and_module() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As of https://github.com/torvalds/linux/commit/fb6d47a, get_disk() +is now get_disk_and_module(). Add a configure check to determine +if we need to use get_disk_and_module(). + +Reviewed-by: loli10K +Reviewed-by: Brian Behlendorf +Signed-off-by: Giuseppe Di Natale +Closes #7264 +(cherry picked from commit 8d7f17798d0faa0001bf7257759be0c688b91044) +Signed-off-by: Fabian Grünbichler +--- + include/linux/blkdev_compat.h | 8 ++++++++ + module/zfs/zvol.c | 2 +- + config/kernel-get-disk-and-module.m4 | 19 +++++++++++++++++++ + config/kernel.m4 | 1 + + 4 files changed, 29 insertions(+), 1 deletion(-) + create mode 100644 config/kernel-get-disk-and-module.m4 + +diff --git a/include/linux/blkdev_compat.h b/include/linux/blkdev_compat.h +index c8a8e856d..4406493e4 100644 +--- a/include/linux/blkdev_compat.h ++++ b/include/linux/blkdev_compat.h +@@ -139,6 +139,14 @@ blk_queue_set_read_ahead(struct request_queue *q, unsigned long ra_pages) + #endif + } + ++#ifndef HAVE_GET_DISK_AND_MODULE ++static inline struct kobject * ++get_disk_and_module(struct gendisk *disk) ++{ ++ return (get_disk(disk)); ++} ++#endif ++ + #ifndef HAVE_GET_DISK_RO + static inline int + get_disk_ro(struct gendisk *disk) +diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c +index aac494209..62176e1cf 100644 +--- a/module/zfs/zvol.c ++++ b/module/zfs/zvol.c +@@ -1559,7 +1559,7 @@ zvol_probe(dev_t dev, int *part, void *arg) + struct kobject *kobj; + + zv = zvol_find_by_dev(dev); +- kobj = zv ? get_disk(zv->zv_disk) : NULL; ++ kobj = zv ? get_disk_and_module(zv->zv_disk) : NULL; + ASSERT(zv == NULL || MUTEX_HELD(&zv->zv_state_lock)); + if (zv) + mutex_exit(&zv->zv_state_lock); +diff --git a/config/kernel-get-disk-and-module.m4 b/config/kernel-get-disk-and-module.m4 +new file mode 100644 +index 000000000..2a51a5af7 +--- /dev/null ++++ b/config/kernel-get-disk-and-module.m4 +@@ -0,0 +1,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([ ++ #include ++ ], [ ++ struct gendisk *disk = NULL; ++ (void) get_disk_and_module(disk); ++ ], [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]) ++ ], [ ++ AC_MSG_RESULT(no) ++ ]) ++]) +diff --git a/config/kernel.m4 b/config/kernel.m4 +index 3e499e447..419ed1a2c 100644 +--- a/config/kernel.m4 ++++ b/config/kernel.m4 +@@ -40,6 +40,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ + 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_GET_DISK_AND_MODULE + ZFS_AC_KERNEL_GET_DISK_RO + ZFS_AC_KERNEL_GET_GENDISK + ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS +-- +2.14.2 + diff --git a/zfs-patches/0049-Detect-long-config-lock-acquisition-in-mmp.patch b/zfs-patches/0049-Detect-long-config-lock-acquisition-in-mmp.patch new file mode 100644 index 0000000..6e53d3d --- /dev/null +++ b/zfs-patches/0049-Detect-long-config-lock-acquisition-in-mmp.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Olaf Faaland +Date: Tue, 20 Feb 2018 17:33:51 -0800 +Subject: [PATCH] Detect long config lock acquisition in mmp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If something holds the config lock as a writer for too long, MMP will +fail to issue MMP writes in a timely manner. This will result either in +the pool being suspended, or in an extreme case, in the pool not being +protected. + +If the time to acquire the config lock exceeds 1/10 of the minimum +zfs_multihost_interval, report it in the zfs debug log. + +Reviewed-by: Brian Behlendorf +Signed-off-by: Olaf Faaland +Closes #7212 +(cherry picked from commit c17922b8a9db00ad7e7d59a5ff975b2a1edcf887) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/mmp.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c +index ee8e9201b..634e48287 100644 +--- a/module/zfs/mmp.c ++++ b/module/zfs/mmp.c +@@ -323,7 +323,13 @@ mmp_write_uberblock(spa_t *spa) + int label; + uint64_t offset; + ++ hrtime_t lock_acquire_time = gethrtime(); + spa_config_enter(spa, SCL_STATE, mmp_tag, RW_READER); ++ lock_acquire_time = gethrtime() - lock_acquire_time; ++ if (lock_acquire_time > (MSEC2NSEC(MMP_MIN_INTERVAL) / 10)) ++ zfs_dbgmsg("SCL_STATE acquisition took %llu ns\n", ++ (u_longlong_t)lock_acquire_time); ++ + vd = mmp_random_leaf(spa->spa_root_vdev); + if (vd == NULL) { + spa_config_exit(spa, SCL_STATE, FTAG); +-- +2.14.2 + diff --git a/zfs-patches/0050-Take-user-namespaces-into-account-in-policy-checks.patch b/zfs-patches/0050-Take-user-namespaces-into-account-in-policy-checks.patch new file mode 100644 index 0000000..604a33d --- /dev/null +++ b/zfs-patches/0050-Take-user-namespaces-into-account-in-policy-checks.patch @@ -0,0 +1,786 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Wolfgang Bumiller +Date: Thu, 8 Mar 2018 00:40:42 +0100 +Subject: [PATCH] Take user namespaces into account in policy checks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Change file related checks to use user namespaces and make +sure involved uids/gids are mappable in the current +namespace. + +Note that checks without file ownership information will +still not take user namespaces into account, as some of +these should be handled via 'zfs allow' (otherwise root in a +user namespace could issue commands such as `zpool export`). + +This also adds an initial user namespace regression test +for the setgid bit loss, with a user_ns_exec helper usable +in further tests. + +Additionally, configure checks for the required user +namespace related features are added for: + * ns_capable + * kuid/kgid_has_mapping() + * user_ns in cred_t + +Reviewed-by: Brian Behlendorf +Signed-off-by: Wolfgang Bumiller +Closes #6800 +Closes #7270 +(cherry picked from commit 3808006edfc46b18f0a40a2e9df54c6567bf52cc) +Signed-off-by: Fabian Grünbichler +--- + configure.ac | 2 + + tests/zfs-tests/cmd/Makefile.am | 1 + + tests/zfs-tests/cmd/user_ns_exec/Makefile.am | 6 + + tests/zfs-tests/tests/functional/Makefile.am | 1 + + .../tests/functional/user_namespace/Makefile.am | 7 + + module/zfs/policy.c | 66 +++++++- + tests/zfs-tests/cmd/user_ns_exec/user_ns_exec.c | 179 +++++++++++++++++++++ + config/kernel-userns-capabilities.m4 | 67 ++++++++ + config/kernel.m4 | 1 + + tests/runfiles/linux.run | 4 + + tests/zfs-tests/cmd/user_ns_exec/.gitignore | 1 + + tests/zfs-tests/include/commands.cfg | 1 + + .../tests/functional/user_namespace/cleanup.ksh | 25 +++ + .../tests/functional/user_namespace/setup.ksh | 32 ++++ + .../functional/user_namespace/user_namespace.cfg | 23 +++ + .../user_namespace/user_namespace_001.ksh | 89 ++++++++++ + .../user_namespace/user_namespace_common.kshlib | 23 +++ + 17 files changed, 521 insertions(+), 7 deletions(-) + create mode 100644 tests/zfs-tests/cmd/user_ns_exec/Makefile.am + create mode 100644 tests/zfs-tests/tests/functional/user_namespace/Makefile.am + create mode 100644 tests/zfs-tests/cmd/user_ns_exec/user_ns_exec.c + create mode 100644 config/kernel-userns-capabilities.m4 + create mode 100644 tests/zfs-tests/cmd/user_ns_exec/.gitignore + create mode 100755 tests/zfs-tests/tests/functional/user_namespace/cleanup.ksh + create mode 100755 tests/zfs-tests/tests/functional/user_namespace/setup.ksh + create mode 100644 tests/zfs-tests/tests/functional/user_namespace/user_namespace.cfg + create mode 100755 tests/zfs-tests/tests/functional/user_namespace/user_namespace_001.ksh + create mode 100644 tests/zfs-tests/tests/functional/user_namespace/user_namespace_common.kshlib + +diff --git a/configure.ac b/configure.ac +index d71712e4c..77e5764fc 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -153,6 +153,7 @@ AC_CONFIG_FILES([ + tests/zfs-tests/callbacks/Makefile + tests/zfs-tests/cmd/Makefile + tests/zfs-tests/cmd/chg_usr_exec/Makefile ++ tests/zfs-tests/cmd/user_ns_exec/Makefile + tests/zfs-tests/cmd/devname2devid/Makefile + tests/zfs-tests/cmd/dir_rd_update/Makefile + tests/zfs-tests/cmd/file_check/Makefile +@@ -284,6 +285,7 @@ AC_CONFIG_FILES([ + tests/zfs-tests/tests/functional/threadsappend/Makefile + tests/zfs-tests/tests/functional/tmpfile/Makefile + tests/zfs-tests/tests/functional/truncate/Makefile ++ tests/zfs-tests/tests/functional/user_namespace/Makefile + tests/zfs-tests/tests/functional/userquota/Makefile + tests/zfs-tests/tests/functional/upgrade/Makefile + tests/zfs-tests/tests/functional/vdev_zaps/Makefile +diff --git a/tests/zfs-tests/cmd/Makefile.am b/tests/zfs-tests/cmd/Makefile.am +index f55ff8ce2..1cce6947b 100644 +--- a/tests/zfs-tests/cmd/Makefile.am ++++ b/tests/zfs-tests/cmd/Makefile.am +@@ -2,6 +2,7 @@ EXTRA_DIST = file_common.h + + SUBDIRS = \ + chg_usr_exec \ ++ user_ns_exec \ + devname2devid \ + dir_rd_update \ + file_check \ +diff --git a/tests/zfs-tests/cmd/user_ns_exec/Makefile.am b/tests/zfs-tests/cmd/user_ns_exec/Makefile.am +new file mode 100644 +index 000000000..5b4bc9aaa +--- /dev/null ++++ b/tests/zfs-tests/cmd/user_ns_exec/Makefile.am +@@ -0,0 +1,6 @@ ++include $(top_srcdir)/config/Rules.am ++ ++pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin ++ ++pkgexec_PROGRAMS = user_ns_exec ++user_ns_exec_SOURCES = user_ns_exec.c +diff --git a/tests/zfs-tests/tests/functional/Makefile.am b/tests/zfs-tests/tests/functional/Makefile.am +index d68f254ef..cd60324f3 100644 +--- a/tests/zfs-tests/tests/functional/Makefile.am ++++ b/tests/zfs-tests/tests/functional/Makefile.am +@@ -58,6 +58,7 @@ SUBDIRS = \ + tmpfile \ + truncate \ + upgrade \ ++ user_namespace \ + userquota \ + vdev_zaps \ + write_dirs \ +diff --git a/tests/zfs-tests/tests/functional/user_namespace/Makefile.am b/tests/zfs-tests/tests/functional/user_namespace/Makefile.am +new file mode 100644 +index 000000000..0c0f6887a +--- /dev/null ++++ b/tests/zfs-tests/tests/functional/user_namespace/Makefile.am +@@ -0,0 +1,7 @@ ++pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/user_namespace ++dist_pkgdata_SCRIPTS = \ ++ setup.ksh \ ++ cleanup.ksh \ ++ user_namespace_common.kshlib \ ++ user_namespace.cfg \ ++ user_namespace_001.ksh +diff --git a/module/zfs/policy.c b/module/zfs/policy.c +index 03e8f748b..55c932747 100644 +--- a/module/zfs/policy.c ++++ b/module/zfs/policy.c +@@ -42,19 +42,47 @@ + * all other cases this function must fail and return the passed err. + */ + static int +-priv_policy(const cred_t *cr, int capability, boolean_t all, int err) ++priv_policy_ns(const cred_t *cr, int capability, boolean_t all, int err, ++ struct user_namespace *ns) + { + ASSERT3S(all, ==, B_FALSE); + + if (cr != CRED() && (cr != kcred)) + return (err); + ++#if defined(CONFIG_USER_NS) && defined(HAVE_NS_CAPABLE) ++ if (!(ns ? ns_capable(ns, capability) : capable(capability))) ++#else + if (!capable(capability)) ++#endif + return (err); + + return (0); + } + ++static int ++priv_policy(const cred_t *cr, int capability, boolean_t all, int err) ++{ ++ return (priv_policy_ns(cr, capability, all, err, NULL)); ++} ++ ++static int ++priv_policy_user(const cred_t *cr, int capability, boolean_t all, int err) ++{ ++ /* ++ * All priv_policy_user checks are preceeded by kuid/kgid_has_mapping() ++ * checks. If we cannot do them, we shouldn't be using ns_capable() ++ * since we don't know whether the affected files are valid in our ++ * namespace. Note that kuid_has_mapping() came after cred->user_ns, so ++ * we shouldn't need to re-check for HAVE_CRED_USER_NS ++ */ ++#if defined(CONFIG_USER_NS) && defined(HAVE_KUID_HAS_MAPPING) ++ return (priv_policy_ns(cr, capability, all, err, cr->user_ns)); ++#else ++ return (priv_policy_ns(cr, capability, all, err, NULL)); ++#endif ++} ++ + /* + * Checks for operations that are either client-only or are used by + * both clients and servers. +@@ -102,10 +130,15 @@ secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner) + if (zpl_inode_owner_or_capable(ip)) + return (0); + +- if (priv_policy(cr, CAP_DAC_OVERRIDE, B_FALSE, EPERM) == 0) ++#if defined(CONFIG_USER_NS) && defined(HAVE_KUID_HAS_MAPPING) ++ if (!kuid_has_mapping(cr->user_ns, SUID_TO_KUID(owner))) ++ return (EPERM); ++#endif ++ ++ if (priv_policy_user(cr, CAP_DAC_OVERRIDE, B_FALSE, EPERM) == 0) + return (0); + +- if (priv_policy(cr, CAP_DAC_READ_SEARCH, B_FALSE, EPERM) == 0) ++ if (priv_policy_user(cr, CAP_DAC_READ_SEARCH, B_FALSE, EPERM) == 0) + return (0); + + return (EPERM); +@@ -120,7 +153,12 @@ secpolicy_vnode_chown(const cred_t *cr, uid_t owner) + if (crgetfsuid(cr) == owner) + return (0); + +- return (priv_policy(cr, CAP_FOWNER, B_FALSE, EPERM)); ++#if defined(CONFIG_USER_NS) && defined(HAVE_KUID_HAS_MAPPING) ++ if (!kuid_has_mapping(cr->user_ns, SUID_TO_KUID(owner))) ++ return (EPERM); ++#endif ++ ++ return (priv_policy_user(cr, CAP_FOWNER, B_FALSE, EPERM)); + } + + /* +@@ -152,7 +190,12 @@ secpolicy_vnode_setdac(const cred_t *cr, uid_t owner) + if (crgetfsuid(cr) == owner) + return (0); + +- return (priv_policy(cr, CAP_FOWNER, B_FALSE, EPERM)); ++#if defined(CONFIG_USER_NS) && defined(HAVE_KUID_HAS_MAPPING) ++ if (!kuid_has_mapping(cr->user_ns, SUID_TO_KUID(owner))) ++ return (EPERM); ++#endif ++ ++ return (priv_policy_user(cr, CAP_FOWNER, B_FALSE, EPERM)); + } + + /* +@@ -175,8 +218,12 @@ secpolicy_vnode_setid_retain(const cred_t *cr, boolean_t issuidroot) + int + secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid) + { ++#if defined(CONFIG_USER_NS) && defined(HAVE_KUID_HAS_MAPPING) ++ if (!kgid_has_mapping(cr->user_ns, SGID_TO_KGID(gid))) ++ return (EPERM); ++#endif + if (crgetfsgid(cr) != gid && !groupmember(gid, cr)) +- return (priv_policy(cr, CAP_FSETID, B_FALSE, EPERM)); ++ return (priv_policy_user(cr, CAP_FSETID, B_FALSE, EPERM)); + + return (0); + } +@@ -222,7 +269,12 @@ secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner) + if (crgetfsuid(cr) == owner) + return (0); + +- return (priv_policy(cr, CAP_FSETID, B_FALSE, EPERM)); ++#if defined(CONFIG_USER_NS) && defined(HAVE_KUID_HAS_MAPPING) ++ if (!kuid_has_mapping(cr->user_ns, SUID_TO_KUID(owner))) ++ return (EPERM); ++#endif ++ ++ return (priv_policy_user(cr, CAP_FSETID, B_FALSE, EPERM)); + } + + /* +diff --git a/tests/zfs-tests/cmd/user_ns_exec/user_ns_exec.c b/tests/zfs-tests/cmd/user_ns_exec/user_ns_exec.c +new file mode 100644 +index 000000000..cd46738bd +--- /dev/null ++++ b/tests/zfs-tests/cmd/user_ns_exec/user_ns_exec.c +@@ -0,0 +1,179 @@ ++/* ++ * CDDL HEADER START ++ * ++ * The contents of this file are subject to the terms of the ++ * Common Development and Distribution License (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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define EXECSHELL "/bin/sh" ++#define UIDMAP "0 100000 65536" ++ ++static int ++child_main(int argc, char *argv[], int sync_pipe) ++{ ++ char sync_buf; ++ char cmds[BUFSIZ] = { 0 }; ++ char sep[] = " "; ++ int i, len; ++ ++ if (unshare(CLONE_NEWUSER | CLONE_NEWNS) != 0) { ++ perror("unshare"); ++ return (1); ++ } ++ ++ /* tell parent we entered the new namespace */ ++ if (write(sync_pipe, "1", 1) != 1) { ++ perror("write"); ++ return (1); ++ } ++ ++ /* wait for parent to setup the uid mapping */ ++ if (read(sync_pipe, &sync_buf, 1) != 1) { ++ (void) fprintf(stderr, "user namespace setup failed\n"); ++ return (1); ++ } ++ ++ close(sync_pipe); ++ ++ if (setuid(0) != 0) { ++ perror("setuid"); ++ return (1); ++ } ++ if (setgid(0) != 0) { ++ perror("setgid"); ++ return (1); ++ } ++ ++ len = 0; ++ for (i = 1; i < argc; i++) { ++ (void) snprintf(cmds+len, sizeof (cmds)-len, ++ "%s%s", argv[i], sep); ++ len += strlen(argv[i]) + strlen(sep); ++ } ++ ++ if (execl(EXECSHELL, "sh", "-c", cmds, (char *)NULL) != 0) { ++ perror("execl: " EXECSHELL); ++ return (1); ++ } ++ ++ return (0); ++} ++ ++static int ++set_idmap(pid_t pid, const char *file) ++{ ++ int result = 0; ++ int mapfd; ++ char path[PATH_MAX]; ++ ++ (void) snprintf(path, sizeof (path), "/proc/%d/%s", (int)pid, file); ++ ++ mapfd = open(path, O_WRONLY); ++ if (mapfd < 0) { ++ result = errno; ++ perror("open"); ++ return (errno); ++ } ++ ++ if (write(mapfd, UIDMAP, sizeof (UIDMAP)-1) != sizeof (UIDMAP)-1) { ++ perror("write"); ++ result = (errno); ++ } ++ ++ close(mapfd); ++ ++ return (result); ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++ char sync_buf; ++ int result, wstatus; ++ int syncfd[2]; ++ pid_t child; ++ ++ if (argc < 2 || strlen(argv[1]) == 0) { ++ (void) printf("\tUsage: %s ...\n", argv[0]); ++ return (1); ++ } ++ ++ if (socketpair(AF_UNIX, SOCK_STREAM, 0, syncfd) != 0) { ++ perror("socketpair"); ++ return (1); ++ } ++ ++ child = fork(); ++ if (child == (pid_t)-1) { ++ perror("fork"); ++ return (1); ++ } ++ ++ if (child == 0) { ++ close(syncfd[0]); ++ return (child_main(argc, argv, syncfd[1])); ++ } ++ ++ close(syncfd[1]); ++ ++ result = 0; ++ /* wait for the child to have unshared its namespaces */ ++ if (read(syncfd[0], &sync_buf, 1) != 1) { ++ perror("read"); ++ kill(child, SIGKILL); ++ result = 1; ++ goto reap; ++ } ++ ++ /* write uid mapping */ ++ if (set_idmap(child, "uid_map") != 0 || ++ set_idmap(child, "gid_map") != 0) { ++ result = 1; ++ kill(child, SIGKILL); ++ goto reap; ++ } ++ ++ /* tell the child to proceed */ ++ if (write(syncfd[0], "1", 1) != 1) { ++ perror("write"); ++ kill(child, SIGKILL); ++ result = 1; ++ goto reap; ++ } ++ close(syncfd[0]); ++ ++reap: ++ while (waitpid(child, &wstatus, 0) != child) ++ kill(child, SIGKILL); ++ if (result == 0) ++ result = WEXITSTATUS(wstatus); ++ ++ return (result); ++} +diff --git a/config/kernel-userns-capabilities.m4 b/config/kernel-userns-capabilities.m4 +new file mode 100644 +index 000000000..fa3381978 +--- /dev/null ++++ b/config/kernel-userns-capabilities.m4 +@@ -0,0 +1,67 @@ ++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([ ++ #include ++ ],[ ++ ns_capable((struct user_namespace *)NULL, CAP_SYS_ADMIN); ++ ],[ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_NS_CAPABLE, 1, ++ [ns_capable exists]) ++ ],[ ++ AC_MSG_RESULT(no) ++ ]) ++]) ++ ++dnl # ++dnl # 2.6.39 API change ++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([ ++ #include ++ ],[ ++ struct cred cr; ++ cr.user_ns = (struct user_namespace *)NULL; ++ ],[ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_CRED_USER_NS, 1, ++ [cred_t->user_ns exists]) ++ ],[ ++ AC_MSG_RESULT(no) ++ ]) ++]) ++ ++dnl # ++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([ ++ #include ++ ],[ ++ kuid_has_mapping((struct user_namespace *)NULL, KUIDT_INIT(0)); ++ kgid_has_mapping((struct user_namespace *)NULL, KGIDT_INIT(0)); ++ ],[ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_KUID_HAS_MAPPING, 1, ++ [kuid_has_mapping/kgid_has_mapping exist]) ++ ],[ ++ AC_MSG_RESULT(no) ++ ]) ++]) ++ ++AC_DEFUN([ZFS_AC_KERNEL_USERNS_CAPABILITIES], [ ++ ZFS_AC_KERNEL_NS_CAPABLE ++ ZFS_AC_KERNEL_CRED_USER_NS ++ ZFS_AC_KERNEL_KUID_HAS_MAPPING ++]) +diff --git a/config/kernel.m4 b/config/kernel.m4 +index 419ed1a2c..910d4ff25 100644 +--- a/config/kernel.m4 ++++ b/config/kernel.m4 +@@ -126,6 +126,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ + ZFS_AC_KERNEL_CURRENT_TIME + ZFS_AC_KERNEL_GLOBAL_PAGE_STATE + ZFS_AC_KERNEL_ACL_HAS_REFCOUNT ++ ZFS_AC_KERNEL_USERNS_CAPABILITIES + + AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ + KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" +diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run +index 89c923db1..25ae3fe5e 100644 +--- a/tests/runfiles/linux.run ++++ b/tests/runfiles/linux.run +@@ -648,6 +648,10 @@ tags = ['functional', 'truncate'] + tests = [ 'upgrade_userobj_001_pos' ] + tags = ['functional', 'upgrade'] + ++[tests/functional/user_namespace] ++tests = ['user_namespace_001'] ++tags = ['functional', 'user_namespace'] ++ + [tests/functional/userquota] + tests = [ + 'userquota_001_pos', 'userquota_002_pos', 'userquota_003_pos', +diff --git a/tests/zfs-tests/cmd/user_ns_exec/.gitignore b/tests/zfs-tests/cmd/user_ns_exec/.gitignore +new file mode 100644 +index 000000000..655867a64 +--- /dev/null ++++ b/tests/zfs-tests/cmd/user_ns_exec/.gitignore +@@ -0,0 +1 @@ ++/user_ns_exec +diff --git a/tests/zfs-tests/include/commands.cfg b/tests/zfs-tests/include/commands.cfg +index 936e54c1a..0d768a3cf 100644 +--- a/tests/zfs-tests/include/commands.cfg ++++ b/tests/zfs-tests/include/commands.cfg +@@ -164,4 +164,5 @@ export ZFSTEST_FILES='chg_usr_exec + rename_dir + rm_lnkcnt_zero_file + threadsappend ++ user_ns_exec + xattrtest' +diff --git a/tests/zfs-tests/tests/functional/user_namespace/cleanup.ksh b/tests/zfs-tests/tests/functional/user_namespace/cleanup.ksh +new file mode 100755 +index 000000000..61caf3910 +--- /dev/null ++++ b/tests/zfs-tests/tests/functional/user_namespace/cleanup.ksh +@@ -0,0 +1,25 @@ ++#!/bin/ksh -p ++# ++# CDDL HEADER START ++# ++# The contents of this file are subject to the terms of the ++# Common Development and Distribution License (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 ++# ++ ++. $STF_SUITE/include/libtest.shlib ++ ++default_cleanup +diff --git a/tests/zfs-tests/tests/functional/user_namespace/setup.ksh b/tests/zfs-tests/tests/functional/user_namespace/setup.ksh +new file mode 100755 +index 000000000..354cc9a6b +--- /dev/null ++++ b/tests/zfs-tests/tests/functional/user_namespace/setup.ksh +@@ -0,0 +1,32 @@ ++#!/bin/ksh -p ++# ++# CDDL HEADER START ++# ++# The contents of this file are subject to the terms of the ++# Common Development and Distribution License (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 ++# ++ ++. $STF_SUITE/include/libtest.shlib ++ ++if ! [ -f /proc/self/uid_map ]; then ++ log_unsupported "The kernel doesn't support user namespaces." ++fi ++ ++verify_runnable "both" ++ ++DISK=${DISKS%% *} ++default_setup $DISK +diff --git a/tests/zfs-tests/tests/functional/user_namespace/user_namespace.cfg b/tests/zfs-tests/tests/functional/user_namespace/user_namespace.cfg +new file mode 100644 +index 000000000..9e55398e2 +--- /dev/null ++++ b/tests/zfs-tests/tests/functional/user_namespace/user_namespace.cfg +@@ -0,0 +1,23 @@ ++# ++# CDDL HEADER START ++# ++# The contents of this file are subject to the terms of the ++# Common Development and Distribution License (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 ++# ++ ++export ROOT_UID=100000 ++export OTHER_UID=101000 +diff --git a/tests/zfs-tests/tests/functional/user_namespace/user_namespace_001.ksh b/tests/zfs-tests/tests/functional/user_namespace/user_namespace_001.ksh +new file mode 100755 +index 000000000..6be30ab4d +--- /dev/null ++++ b/tests/zfs-tests/tests/functional/user_namespace/user_namespace_001.ksh +@@ -0,0 +1,89 @@ ++#!/bin/ksh -p ++# ++# CDDL HEADER START ++# ++# The contents of this file are subject to the terms of the ++# Common Development and Distribution License (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 ++# ++ ++. $STF_SUITE/tests/functional/user_namespace/user_namespace_common.kshlib ++ ++# ++# ++# DESCRIPTION: ++# Regression test for secpolicy_vnode_setids_setgids ++# ++# ++# STRATEGY: ++# 1. Create files with various owners. ++# 2. Try to set setgid bit. ++# ++ ++verify_runnable "both" ++ ++# rroot: real root, ++# uroot: root within user namespace ++# uother: other user within user namespace ++set -A files rroot_rroot uroot_uroot uroot_other uother_uroot uother_uother ++ ++function cleanup ++{ ++ for i in ${files[*]}; do ++ log_must rm -f $TESTDIR/$i ++ done ++} ++ ++log_onexit cleanup ++ ++log_assert "Check root in user namespaces" ++ ++TOUCH=$(readlink -e $(which touch)) ++CHMOD=$(readlink -e $(which chmod)) ++ ++for i in ${files[*]}; do ++ log_must $TOUCH $TESTDIR/$i ++ log_must $CHMOD 0644 $TESTDIR/$i ++done ++ ++log_must chown 0:0 $TESTDIR/rroot_rroot ++log_must chown $ROOT_UID:$ROOT_UID $TESTDIR/uroot_uroot ++log_must chown $ROOT_UID:$OTHER_UID $TESTDIR/uroot_other ++log_must chown $OTHER_UID:$ROOT_UID $TESTDIR/uother_uroot ++log_must chown $OTHER_UID:$OTHER_UID $TESTDIR/uother_uother ++ ++log_mustnot user_ns_exec $CHMOD 02755 $TESTDIR/rroot_rroot ++log_mustnot test -g $TESTDIR/rroot_rroot ++ ++log_must user_ns_exec $CHMOD 02755 $TESTDIR/uroot_uroot ++log_must test -g $TESTDIR/uroot_uroot ++ ++log_must user_ns_exec $CHMOD 02755 $TESTDIR/uroot_other ++log_must test -g $TESTDIR/uroot_other ++ ++log_must user_ns_exec $CHMOD 02755 $TESTDIR/uother_uroot ++log_must test -g $TESTDIR/uother_uroot ++ ++log_must user_ns_exec $CHMOD 02755 $TESTDIR/uother_uother ++log_must test -g $TESTDIR/uother_uother ++ ++log_mustnot user_ns_exec $TOUCH $TESTDIR/rroot_rroot ++log_must $CHMOD 0666 $TESTDIR/rroot_rroot ++for i in ${files[*]}; do ++ log_must user_ns_exec $TOUCH $TESTDIR/$i ++done ++ ++log_pass "Check root in user namespaces" +diff --git a/tests/zfs-tests/tests/functional/user_namespace/user_namespace_common.kshlib b/tests/zfs-tests/tests/functional/user_namespace/user_namespace_common.kshlib +new file mode 100644 +index 000000000..8577294d0 +--- /dev/null ++++ b/tests/zfs-tests/tests/functional/user_namespace/user_namespace_common.kshlib +@@ -0,0 +1,23 @@ ++# ++# CDDL HEADER START ++# ++# The contents of this file are subject to the terms of the ++# Common Development and Distribution License (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 ++# ++ ++. $STF_SUITE/include/libtest.shlib ++. $STF_SUITE/tests/functional/user_namespace/user_namespace.cfg +-- +2.14.2 + diff --git a/zfs-patches/0051-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch b/zfs-patches/0051-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch new file mode 100644 index 0000000..bebe5b1 --- /dev/null +++ b/zfs-patches/0051-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch @@ -0,0 +1,232 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Zuchowski <31706010+PaulZ-98@users.noreply.github.com> +Date: Wed, 7 Mar 2018 20:03:33 -0500 +Subject: [PATCH] zdb and inuse tests don't pass with real disks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Due to zpool create auto-partioning in Linux (i.e. sdb1), +certain utilities need to use the parition (sdb1) while +others use the whole disk name (sdb). + +Reviewed-by: Brian Behlendorf +Signed-off-by: Paul Zuchowski +Closes #6939 +Closes #7261 +(cherry picked from commit 0a0af41bd926ca20a26d7476d792ce82bca9c077) +Signed-off-by: Fabian Grünbichler +--- + tests/zfs-tests/include/libtest.shlib | 31 +++++++++++++++++++--- + .../tests/functional/cli_root/zdb/zdb_003_pos.ksh | 5 ++++ + .../tests/functional/cli_root/zdb/zdb_004_pos.ksh | 11 +++++--- + .../tests/functional/cli_root/zdb/zdb_005_pos.ksh | 4 +++ + .../tests/functional/inuse/inuse_005_pos.ksh | 8 +++--- + .../tests/functional/inuse/inuse_008_pos.ksh | 5 ++-- + .../tests/functional/inuse/inuse_009_pos.ksh | 10 +++++-- + 7 files changed, 59 insertions(+), 15 deletions(-) + +diff --git a/tests/zfs-tests/include/libtest.shlib b/tests/zfs-tests/include/libtest.shlib +index 48fb5e7c5..d51d73e61 100644 +--- a/tests/zfs-tests/include/libtest.shlib ++++ b/tests/zfs-tests/include/libtest.shlib +@@ -767,7 +767,11 @@ function zero_partitions # + typeset i + + if is_linux; then +- log_must parted $DEV_DSKDIR/$diskname -s -- mklabel gpt ++ DSK=$DEV_DSKDIR/$diskname ++ DSK=$(echo $DSK | sed -e "s|//|/|g") ++ log_must parted $DSK -s -- mklabel gpt ++ blockdev --rereadpt $DSK 2>/dev/null ++ block_device_wait + else + for i in 0 1 3 4 5 6 7 + do +@@ -795,10 +799,11 @@ function set_partition # /dev/null + block_device_wait + else ++ if [[ -z $slicenum || -z $size || -z $disk ]]; then ++ log_fail "The slice, size or disk name is unspecified." ++ fi ++ + typeset format_file=/var/tmp/format_in.$$ + + echo "partition" >$format_file +@@ -3634,3 +3643,19 @@ function get_tunable_impl + + return 1 + } ++ ++# ++# Get actual devices used by the pool (i.e. linux sdb1 not sdb). ++# ++function get_pool_devices #testpool #devdir ++{ ++ typeset testpool=$1 ++ typeset devdir=$2 ++ typeset out="" ++ ++ if is_linux; then ++ out=$(zpool status -P $testpool |grep ${devdir} | awk '{print $1}') ++ out=$(echo $out | sed -e "s|${devdir}/||g" | tr '\n' ' ') ++ fi ++ echo $out ++} +diff --git a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_003_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_003_pos.ksh +index 4c57cb587..3c444ae98 100755 +--- a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_003_pos.ksh ++++ b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_003_pos.ksh +@@ -43,6 +43,11 @@ config_count=(1 2) + set -A DISK $DISKS + + default_mirror_setup_noexit $DISKS ++ ++DEVS=$(get_pool_devices ${TESTPOOL} ${DEV_RDSKDIR}) ++log_note "$DEVS" ++[[ -n $DEVS ]] && set -A DISK $DEVS ++ + log_must dd if=/dev/${DISK[0]} of=/dev/${DISK[1]} bs=1K count=256 conv=notrunc + + for x in 0 1 ; do +diff --git a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_004_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_004_pos.ksh +index 2b4057aa7..91a5c9799 100755 +--- a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_004_pos.ksh ++++ b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_004_pos.ksh +@@ -45,17 +45,22 @@ function cleanup + verify_runnable "global" + verify_disk_count "$DISKS" 2 + set -A DISK $DISKS ++WHOLE_DISK=${DISK[0]} + + default_mirror_setup_noexit $DISKS +-log_must zpool offline $TESTPOOL ${DISK[0]} ++DEVS=$(get_pool_devices ${TESTPOOL} ${DEV_RDSKDIR}) ++[[ -n $DEVS ]] && set -A DISK $DEVS ++ ++log_must zpool offline $TESTPOOL ${WHOLE_DISK} + log_must dd if=/dev/urandom of=$TESTDIR/testfile bs=1K count=2 + log_must zpool export $TESTPOOL ++ + log_must dd if=$DEV_RDSKDIR/${DISK[0]} of=$DEV_RDSKDIR/${DISK[1]} bs=1K count=256 conv=notrunc + +-ubs=$(zdb -lu $DEV_RDSKDIR/${DISK[1]} | grep -e LABEL -e Uberblock -e 'labels = ') ++ubs=$(zdb -lu ${DISK[1]} | grep -e LABEL -e Uberblock -e 'labels = ') + log_note "vdev 1: ubs $ubs" + +-ub_dump_counts=$(zdb -lu $DEV_RDSKDIR/${DISK[1]} | \ ++ub_dump_counts=$(zdb -lu ${DISK[1]} | \ + awk ' /LABEL/ {label=$NF; blocks[label]=0}; + /Uberblock/ {blocks[label]++}; + END {print blocks[0],blocks[1],blocks[2],blocks[3]}') +diff --git a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_005_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_005_pos.ksh +index 60bbb5615..f6730f611 100755 +--- a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_005_pos.ksh ++++ b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_005_pos.ksh +@@ -44,6 +44,10 @@ verify_disk_count "$DISKS" 2 + set -A DISK $DISKS + + default_mirror_setup_noexit $DISKS ++DEVS=$(get_pool_devices ${TESTPOOL} ${DEV_RDSKDIR}) ++log_note "$DEVS" ++[[ -n $DEVS ]] && set -A DISK $DEVS ++ + log_must dd if=/dev/zero of=$DEV_RDSKDIR/${DISK[1]} bs=1K count=256 conv=notrunc + log_must truncate -s 0 $TEMPFILE + +diff --git a/tests/zfs-tests/tests/functional/inuse/inuse_005_pos.ksh b/tests/zfs-tests/tests/functional/inuse/inuse_005_pos.ksh +index 9dd1e25bf..6b0abf429 100755 +--- a/tests/zfs-tests/tests/functional/inuse/inuse_005_pos.ksh ++++ b/tests/zfs-tests/tests/functional/inuse/inuse_005_pos.ksh +@@ -82,19 +82,18 @@ typeset -i i=0 + + unset NOINUSE_CHECK + while (( i < ${#vdevs[*]} )); do +- + for num in 0 1 2 3 ; do + eval typeset disk=\${FS_DISK$num} + zero_partitions $disk + done +- + typeset cyl="" + for num in 0 1 2 3 ; do + eval typeset slice=\${FS_SIDE$num} + disk=${slice%${SLICE_PREFIX}*} +- slice=${slice##*${SLICE_PREFIX}} ++ [[ -z $SLICE_PREFIX ]] && eval typeset disk=\${FS_DISK$num} ++ slice=$(echo $slice | awk '{ print substr($1,length($1),1) }') + log_must set_partition $slice "$cyl" $FS_SIZE $disk +- cyl=$(get_endslice $disk $slice) ++ [[ $num < 3 ]] && cyl=$(get_endslice $disk $slice) + done + + if [[ -n $SINGLE_DISK && -n ${vdevs[i]} ]]; then +@@ -115,7 +114,6 @@ while (( i < ${#vdevs[*]} )); do + (( i = i + 1 )) + continue + fi +- + create_pool $TESTPOOL1 ${vdevs[i]} $vdisks spare $sdisks + verify_assertion "$rawtargets" + destroy_pool $TESTPOOL1 +diff --git a/tests/zfs-tests/tests/functional/inuse/inuse_008_pos.ksh b/tests/zfs-tests/tests/functional/inuse/inuse_008_pos.ksh +index 95d39d958..ddc8fa7a4 100755 +--- a/tests/zfs-tests/tests/functional/inuse/inuse_008_pos.ksh ++++ b/tests/zfs-tests/tests/functional/inuse/inuse_008_pos.ksh +@@ -92,9 +92,10 @@ done + for num in 0 1 2 3 ; do + eval typeset slice=\${FS_SIDE$num} + disk=${slice%${SLICE_PREFIX}*} +- slice=${slice##*${SLICE_PREFIX}} ++ [[ -z $SLICE_PREFIX ]] && eval typeset disk=\${FS_DISK$num} ++ slice=$(echo $slice | awk '{ print substr($1,length($1),1) }') + log_must set_partition $slice "$cyl" $FS_SIZE $disk +- cyl=$(get_endslice $disk $slice) ++ [[ $num < 3 ]] && cyl=$(get_endslice $disk $slice) + done + + while (( i < ${#vdevs[*]} )); do +diff --git a/tests/zfs-tests/tests/functional/inuse/inuse_009_pos.ksh b/tests/zfs-tests/tests/functional/inuse/inuse_009_pos.ksh +index 6a9b9623c..a5e9fda59 100755 +--- a/tests/zfs-tests/tests/functional/inuse/inuse_009_pos.ksh ++++ b/tests/zfs-tests/tests/functional/inuse/inuse_009_pos.ksh +@@ -82,13 +82,19 @@ typeset -i i=0 + + while (( i < ${#vdevs[*]} )); do + ++ for num in 0 1 2 3 ; do ++ eval typeset disk=\${FS_DISK$num} ++ zero_partitions $disk ++ done ++ + typeset cyl="" + for num in 0 1 2 3 ; do + eval typeset slice=\${FS_SIDE$num} + disk=${slice%${SLICE_PREFIX}*} +- slice=${slice##*${SLICE_PREFIX}} ++ [[ -z $SLICE_PREFIX ]] && eval typeset disk=\${FS_DISK$num} ++ slice=$(echo $slice | awk '{ print substr($1,length($1),1) }') + log_must set_partition $slice "$cyl" $FS_SIZE $disk +- cyl=$(get_endslice $disk $slice) ++ [[ $num < 3 ]] && cyl=$(get_endslice $disk $slice) + done + + if [[ -n $SINGLE_DISK && -n ${vdevs[i]} ]]; then +-- +2.14.2 + diff --git a/zfs-patches/0052-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch b/zfs-patches/0052-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch new file mode 100644 index 0000000..12cbe4d --- /dev/null +++ b/zfs-patches/0052-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: LOLi +Date: Fri, 9 Mar 2018 22:52:37 +0100 +Subject: [PATCH] Fix zfs-kmod builds when using rpm >= 4.14 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With rpm-software-management/rpm@5e94633 a package version containing +invalid characters (most commonly a double '-') causes the kmod package +generation to terminate with an error. This change takes advantage of +the newly introduced rpm macro "_wrong_version_format_terminate_build" +to allow kmod packages to be built. + +Reviewed-by: Brian Behlendorf +Signed-off-by: loli10K +Closes #7284 +(cherry picked from commit dc0176eeec9719827610fc68742ea3c76796a81f) +Signed-off-by: Fabian Grünbichler +--- + config/zfs-build.m4 | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 +index 7c19cecd6..8fc3863f4 100644 +--- a/config/zfs-build.m4 ++++ b/config/zfs-build.m4 +@@ -162,6 +162,8 @@ AC_DEFUN([ZFS_AC_RPM], [ + RPM_DEFINE_COMMON='--define "$(DEBUG_ZFS) 1"' + RPM_DEFINE_UTIL='--define "_dracutdir $(dracutdir)" --define "_udevdir $(udevdir)" --define "_udevruledir $(udevruledir)" --define "_initconfdir $(DEFAULT_INITCONF_DIR)" $(DEFINE_INITRAMFS) $(DEFINE_SYSTEMD)' + RPM_DEFINE_KMOD='--define "kernels $(LINUX_VERSION)" --define "require_spldir $(SPL)" --define "require_splobj $(SPL_OBJ)" --define "ksrc $(LINUX)" --define "kobj $(LINUX_OBJ)"' ++ RPM_DEFINE_KMOD+=' --define "_wrong_version_format_terminate_build 0"' ++ + RPM_DEFINE_DKMS= + + dnl # Override default lib directory on Debian/Ubuntu systems. The provided +-- +2.14.2 + diff --git a/zfs-patches/0053-Handle-zio_resume-and-mmp-off.patch b/zfs-patches/0053-Handle-zio_resume-and-mmp-off.patch new file mode 100644 index 0000000..3dfc727 --- /dev/null +++ b/zfs-patches/0053-Handle-zio_resume-and-mmp-off.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Olaf Faaland +Date: Thu, 8 Mar 2018 15:21:54 -0800 +Subject: [PATCH] Handle zio_resume and mmp => off +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When multihost is disabled on a pool, and the pool is resumed via zpool +clear, within a single cycle of the mmp thread's loop (e.g. while it's +in the cv_timedwait call), both mmp_last_write and mmp_delay should be +updated. + +The original code mistakenly treated the two cases as if they could not +occur at the same time. + +Reviewed-by: Brian Behlendorf +Reviewed-by: Tony Hutter +Signed-off-by: Olaf Faaland +Closes #7286 +(cherry picked from commit 267fd7b0f14251026c35d7ceab4fbbe2f06717e6) +Signed-off-by: Fabian Grünbichler +--- + module/zfs/mmp.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c +index 634e48287..15eea41ab 100644 +--- a/module/zfs/mmp.c ++++ b/module/zfs/mmp.c +@@ -409,16 +409,22 @@ mmp_thread(spa_t *spa) + } + + /* +- * When MMP goes off => on, or spa goes suspended => +- * !suspended, we know no writes occurred recently. We +- * update mmp_last_write to give us some time to try. ++ * MMP off => on, or suspended => !suspended: ++ * No writes occurred recently. Update mmp_last_write to give ++ * us some time to try. + */ + if ((!last_spa_multihost && multihost) || + (last_spa_suspended && !suspended)) { + mutex_enter(&mmp->mmp_io_lock); + mmp->mmp_last_write = gethrtime(); + mutex_exit(&mmp->mmp_io_lock); +- } else if (last_spa_multihost && !multihost) { ++ } ++ ++ /* ++ * MMP on => off: ++ * mmp_delay == 0 tells importing node to skip activity check. ++ */ ++ if (last_spa_multihost && !multihost) { + mutex_enter(&mmp->mmp_io_lock); + mmp->mmp_delay = 0; + mutex_exit(&mmp->mmp_io_lock); +-- +2.14.2 + diff --git a/zfs-patches/0054-Fix-MMP-write-frequency-for-large-pools.patch b/zfs-patches/0054-Fix-MMP-write-frequency-for-large-pools.patch new file mode 100644 index 0000000..1b334a2 --- /dev/null +++ b/zfs-patches/0054-Fix-MMP-write-frequency-for-large-pools.patch @@ -0,0 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Mon, 12 Mar 2018 11:26:05 -0700 +Subject: [PATCH] Fix MMP write frequency for large pools +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When a single pool contains more vdevs than the CONFIG_HZ for +for the kernel the mmp thread will not delay properly. Switch +to using cv_timedwait_sig_hires() to handle higher resolution +delays. + +This issue was reported on Arch Linux where HZ defaults to only +100 and this could be fairly easily reproduced with a reasonably +large pool. Most distribution kernels set CONFIG_HZ=250 or +CONFIG_HZ=1000 and thus are unlikely to be impacted. + +Reviewed-by: George Melikov +Reviewed-by: Giuseppe Di Natale +Reviewed-by: Olaf Faaland +Reviewed-by: Tony Hutter +Signed-off-by: Brian Behlendorf +Closes #7205 +Closes #7289 +(cherry picked from commit c30e716c8149b7df7cf968373c22aa00b48d17b8) +Signed-off-by: Fabian Grünbichler +--- + lib/libspl/include/sys/time.h | 6 +++++- + module/zfs/mmp.c | 6 +++--- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/lib/libspl/include/sys/time.h b/lib/libspl/include/sys/time.h +index f05fcaa1c..dc645fa5c 100644 +--- a/lib/libspl/include/sys/time.h ++++ b/lib/libspl/include/sys/time.h +@@ -54,10 +54,14 @@ + #define MSEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MILLISEC)) + #endif + +-#ifndef NSEC2MSEC ++#ifndef NSEC2MSEC + #define NSEC2MSEC(n) ((n) / (NANOSEC / MILLISEC)) + #endif + ++#ifndef USEC2NSEC ++#define USEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MICROSEC)) ++#endif ++ + #ifndef NSEC2SEC + #define NSEC2SEC(n) ((n) / (NANOSEC / SEC)) + #endif +diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c +index 15eea41ab..dc5c6a74f 100644 +--- a/module/zfs/mmp.c ++++ b/module/zfs/mmp.c +@@ -462,9 +462,9 @@ mmp_thread(spa_t *spa) + mmp_write_uberblock(spa); + + CALLB_CPR_SAFE_BEGIN(&cpr); +- (void) cv_timedwait_sig(&mmp->mmp_thread_cv, +- &mmp->mmp_thread_lock, ddi_get_lbolt() + +- ((next_time - gethrtime()) / (NANOSEC / hz))); ++ (void) cv_timedwait_sig_hires(&mmp->mmp_thread_cv, ++ &mmp->mmp_thread_lock, next_time, USEC2NSEC(1), ++ CALLOUT_FLAG_ABSOLUTE); + CALLB_CPR_SAFE_END(&cpr, &mmp->mmp_thread_lock); + } + +-- +2.14.2 + diff --git a/zfs-patches/0055-Tag-zfs-0.7.7.patch b/zfs-patches/0055-Tag-zfs-0.7.7.patch new file mode 100644 index 0000000..edd2710 --- /dev/null +++ b/zfs-patches/0055-Tag-zfs-0.7.7.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tony Hutter +Date: Wed, 14 Mar 2018 16:16:43 -0700 +Subject: [PATCH] Tag zfs-0.7.7 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +META file and changelog updated. + +Signed-off-by: Tony Hutter +(cherry picked from commit 240ccfc13adb46faf3d6e5e17e25a9769dd06733) +Signed-off-by: Fabian Grünbichler +--- + rpm/generic/zfs-kmod.spec.in | 3 +++ + rpm/generic/zfs.spec.in | 3 +++ + META | 2 +- + 3 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/rpm/generic/zfs-kmod.spec.in b/rpm/generic/zfs-kmod.spec.in +index cb23b0a8f..bf52fa2c4 100644 +--- a/rpm/generic/zfs-kmod.spec.in ++++ b/rpm/generic/zfs-kmod.spec.in +@@ -191,6 +191,9 @@ chmod u+x ${RPM_BUILD_ROOT}%{kmodinstdir_prefix}/*/extra/*/*/* + rm -rf $RPM_BUILD_ROOT + + %changelog ++* Wed Mar 14 2018 Tony Hutter - 0.7.7-1 ++- Released 0.7.7-1, detailed release notes are available at: ++- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.7 + * Thu Feb 01 2018 Tony Hutter - 0.7.6-1 + - Released 0.7.6-1, detailed release notes are available at: + - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.6 +diff --git a/rpm/generic/zfs.spec.in b/rpm/generic/zfs.spec.in +index ce028794c..7479e987e 100644 +--- a/rpm/generic/zfs.spec.in ++++ b/rpm/generic/zfs.spec.in +@@ -352,6 +352,9 @@ systemctl --system daemon-reload >/dev/null || true + %endif + + %changelog ++* Wed Mar 14 2018 Tony Hutter - 0.7.7-1 ++- Released 0.7.7-1, detailed release notes are available at: ++- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.7 + * Thu Feb 01 2018 Tony Hutter - 0.7.6-1 + - Released 0.7.6-1, detailed release notes are available at: + - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.6 +diff --git a/META b/META +index 1f4686df7..eefafb10d 100644 +--- a/META ++++ b/META +@@ -1,7 +1,7 @@ + Meta: 1 + Name: zfs + Branch: 1.0 +-Version: 0.7.6 ++Version: 0.7.7 + Release: 1 + Release-Tags: relext + License: CDDL +-- +2.14.2 + diff --git a/zfs-patches/series b/zfs-patches/series index 5b7bede..c04c60f 100644 --- a/zfs-patches/series +++ b/zfs-patches/series @@ -1,4 +1,55 @@ 0001-remove-DKMS-modules-and-dracut-build.patch 0002-import-with-d-dev-disk-by-id-in-scan-service.patch -0003-Use-user-namespaces-for-FSETID-policy-check.patch -0004-always-load-ZFS-module-on-boot.patch +0003-always-load-ZFS-module-on-boot.patch +0004-Make-enable-debug-fail-when-given-bogus-args.patch +0005-Implement-enable-debuginfo-to-force-debuginfo.patch +0006-Add-configure-option-to-enable-gcov-analysis.patch +0007-Make-fno-inline-compile-option-more-accessible.patch +0008-Add-support-for-enable-code-coverage-option.patch +0009-Update-codecov.yml.patch +0010-Fix-enable-code-coverage-debug-build.patch +0011-Remove-vn_rename-and-vn_remove-dependency.patch +0012-Fix-with-systemd-on-Debian-based-distributions-6963.patch +0013-ZTS-Fix-create-o_ashift-test-case.patch +0014-Emit-an-error-message-before-MMP-suspends-pool.patch +0015-Fix-systemd_-RPM-macros-usage-on-Debian-based-distri.patch +0016-Bug-fix-in-qat_compress.c-for-vmalloc-addr-check.patch +0017-Fix-default-libdir-for-Debian-Ubuntu.patch +0018-Remove-deprecated-zfs_arc_p_aggressive_disable.patch +0019-OpenZFS-8966-Source-file-zfs_acl.c-function-zfs_acls.patch +0020-Linux-4.16-compat-inode_set_iversion.patch +0021-Linux-4.11-compat-avoid-refcount_t-name-conflict.patch +0022-Fix-zdb-c-traverse-stop-on-damaged-objset-root.patch +0023-Fix-zle_decompress-out-of-bound-access.patch +0024-Fix-racy-assignment-of-zcb.zcb_haderrors.patch +0025-Fix-zdb-R-decompression.patch +0026-Fix-zdb-E-segfault.patch +0027-Fix-zdb-ed-on-objset-for-exported-pool.patch +0028-Handle-zap_add-failures-in-mixed-case-mode.patch +0029-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch +0030-contrib-initramfs-add-missing-conf.d-zfs.patch +0031-zfs-receive-fails-with-dataset-is-busy.patch +0032-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch +0033-Clarify-zinject-8-explanation-of-e.patch +0034-Fix-config-issues-frame-size-and-headers.patch +0035-Correct-count_uberblocks-in-mmp.kshlib.patch +0036-Add-SMART-attributes-for-SSD-and-NVMe.patch +0037-Allow-modprobe-to-fail-when-called-within-systemd.patch +0038-Linux-4.16-compat-use-correct-_dec_and_test.patch +0039-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch +0040-Report-duration-and-error-in-mmp_history-entries.patch +0041-Fix-free-memory-calculation-on-v3.14.patch +0042-Add-scrub-after-resilver-zed-script.patch +0043-Add-SMART-self-test-results-to-zpool-status-c.patch +0044-Fix-zpool-8-list-example-to-match-actual-format.patch +0045-Fix-some-typos.patch +0046-Increment-zil_itx_needcopy_bytes-properly.patch +0047-Change-checksum-IO-delay-ratelimit-values.patch +0048-Linux-4.16-compat-get_disk_and_module.patch +0049-Detect-long-config-lock-acquisition-in-mmp.patch +0050-Take-user-namespaces-into-account-in-policy-checks.patch +0051-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch +0052-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch +0053-Handle-zio_resume-and-mmp-off.patch +0054-Fix-MMP-write-frequency-for-large-pools.patch +0055-Tag-zfs-0.7.7.patch