]> git.proxmox.com Git - zfsonlinux.git/commitdiff
no-change update to 0.7.8
authorFabian Grünbichler <f.gruenbichler@proxmox.com>
Mon, 30 Apr 2018 11:46:29 +0000 (13:46 +0200)
committerFabian Grünbichler <f.gruenbichler@proxmox.com>
Mon, 30 Apr 2018 11:46:29 +0000 (13:46 +0200)
to reduce version number confusion

60 files changed:
spl-patches/0014-Tag-spl-0.7.8.patch [new file with mode: 0644]
spl-patches/series
zfs-patches/0028-Handle-zap_add-failures-in-mixed-case-mode.patch [new file with mode: 0644]
zfs-patches/0028-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch [deleted file]
zfs-patches/0029-contrib-initramfs-add-missing-conf.d-zfs.patch [deleted file]
zfs-patches/0029-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch [new file with mode: 0644]
zfs-patches/0030-contrib-initramfs-add-missing-conf.d-zfs.patch [new file with mode: 0644]
zfs-patches/0030-zfs-receive-fails-with-dataset-is-busy.patch [deleted file]
zfs-patches/0031-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch [deleted file]
zfs-patches/0031-zfs-receive-fails-with-dataset-is-busy.patch [new file with mode: 0644]
zfs-patches/0032-Clarify-zinject-8-explanation-of-e.patch [deleted file]
zfs-patches/0032-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch [new file with mode: 0644]
zfs-patches/0033-Clarify-zinject-8-explanation-of-e.patch [new file with mode: 0644]
zfs-patches/0033-Fix-config-issues-frame-size-and-headers.patch [deleted file]
zfs-patches/0034-Correct-count_uberblocks-in-mmp.kshlib.patch [deleted file]
zfs-patches/0034-Fix-config-issues-frame-size-and-headers.patch [new file with mode: 0644]
zfs-patches/0035-Add-SMART-attributes-for-SSD-and-NVMe.patch [deleted file]
zfs-patches/0035-Correct-count_uberblocks-in-mmp.kshlib.patch [new file with mode: 0644]
zfs-patches/0036-Add-SMART-attributes-for-SSD-and-NVMe.patch [new file with mode: 0644]
zfs-patches/0036-Allow-modprobe-to-fail-when-called-within-systemd.patch [deleted file]
zfs-patches/0037-Allow-modprobe-to-fail-when-called-within-systemd.patch [new file with mode: 0644]
zfs-patches/0037-Linux-4.16-compat-use-correct-_dec_and_test.patch [deleted file]
zfs-patches/0038-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch [deleted file]
zfs-patches/0038-Linux-4.16-compat-use-correct-_dec_and_test.patch [new file with mode: 0644]
zfs-patches/0039-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch [new file with mode: 0644]
zfs-patches/0039-Report-duration-and-error-in-mmp_history-entries.patch [deleted file]
zfs-patches/0040-Fix-free-memory-calculation-on-v3.14.patch [deleted file]
zfs-patches/0040-Report-duration-and-error-in-mmp_history-entries.patch [new file with mode: 0644]
zfs-patches/0041-Add-scrub-after-resilver-zed-script.patch [deleted file]
zfs-patches/0041-Fix-free-memory-calculation-on-v3.14.patch [new file with mode: 0644]
zfs-patches/0042-Add-SMART-self-test-results-to-zpool-status-c.patch [deleted file]
zfs-patches/0042-Add-scrub-after-resilver-zed-script.patch [new file with mode: 0644]
zfs-patches/0043-Add-SMART-self-test-results-to-zpool-status-c.patch [new file with mode: 0644]
zfs-patches/0043-Fix-zpool-8-list-example-to-match-actual-format.patch [deleted file]
zfs-patches/0044-Fix-some-typos.patch [deleted file]
zfs-patches/0044-Fix-zpool-8-list-example-to-match-actual-format.patch [new file with mode: 0644]
zfs-patches/0045-Fix-some-typos.patch [new file with mode: 0644]
zfs-patches/0045-Increment-zil_itx_needcopy_bytes-properly.patch [deleted file]
zfs-patches/0046-Change-checksum-IO-delay-ratelimit-values.patch [deleted file]
zfs-patches/0046-Increment-zil_itx_needcopy_bytes-properly.patch [new file with mode: 0644]
zfs-patches/0047-Change-checksum-IO-delay-ratelimit-values.patch [new file with mode: 0644]
zfs-patches/0047-Linux-4.16-compat-get_disk_and_module.patch [deleted file]
zfs-patches/0048-Detect-long-config-lock-acquisition-in-mmp.patch [deleted file]
zfs-patches/0048-Linux-4.16-compat-get_disk_and_module.patch [new file with mode: 0644]
zfs-patches/0049-Detect-long-config-lock-acquisition-in-mmp.patch [new file with mode: 0644]
zfs-patches/0049-Take-user-namespaces-into-account-in-policy-checks.patch [deleted file]
zfs-patches/0050-Take-user-namespaces-into-account-in-policy-checks.patch [new file with mode: 0644]
zfs-patches/0050-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch [deleted file]
zfs-patches/0051-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch [deleted file]
zfs-patches/0051-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch [new file with mode: 0644]
zfs-patches/0052-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch [new file with mode: 0644]
zfs-patches/0052-Handle-zio_resume-and-mmp-off.patch [deleted file]
zfs-patches/0053-Fix-MMP-write-frequency-for-large-pools.patch [deleted file]
zfs-patches/0053-Handle-zio_resume-and-mmp-off.patch [new file with mode: 0644]
zfs-patches/0054-Fix-MMP-write-frequency-for-large-pools.patch [new file with mode: 0644]
zfs-patches/0054-Tag-zfs-0.7.7.patch [deleted file]
zfs-patches/0055-Tag-zfs-0.7.7.patch [new file with mode: 0644]
zfs-patches/0056-Revert-Handle-zap_add-failures-in-mixed.patch [new file with mode: 0644]
zfs-patches/0057-Tag-zfs-0.7.8.patch [new file with mode: 0644]
zfs-patches/series

diff --git a/spl-patches/0014-Tag-spl-0.7.8.patch b/spl-patches/0014-Tag-spl-0.7.8.patch
new file mode 100644 (file)
index 0000000..85a281a
--- /dev/null
@@ -0,0 +1,63 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tony Hutter <hutter2@llnl.gov>
+Date: Mon, 9 Apr 2018 14:31:47 -0700
+Subject: [PATCH] Tag spl-0.7.8
+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 <hutter2@llnl.gov>
+(cherry picked from commit 557af2687fd70191120beb406f644392de39f747)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ rpm/generic/spl-kmod.spec.in | 3 +++
+ rpm/generic/spl.spec.in      | 3 +++
+ META                         | 2 +-
+ 3 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/rpm/generic/spl-kmod.spec.in b/rpm/generic/spl-kmod.spec.in
+index 6af292d..a604e1f 100644
+--- a/rpm/generic/spl-kmod.spec.in
++++ b/rpm/generic/spl-kmod.spec.in
+@@ -167,6 +167,9 @@ chmod u+x ${RPM_BUILD_ROOT}%{kmodinstdir_prefix}/*/extra/*/*/*
+ rm -rf $RPM_BUILD_ROOT
+ %changelog
++* Mon Apr 09 2018 Tony Hutter <hutter2@llnl.gov> - 0.7.8-1
++- Released 0.7.8-1, detailed release notes are available at:
++- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.8
+ * Wed Mar 14 2018 Tony Hutter <hutter2@llnl.gov> - 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
+diff --git a/rpm/generic/spl.spec.in b/rpm/generic/spl.spec.in
+index b693bdc..e7a718a 100644
+--- a/rpm/generic/spl.spec.in
++++ b/rpm/generic/spl.spec.in
+@@ -34,6 +34,9 @@ make install DESTDIR=%{?buildroot}
+ %{_mandir}/man5/*
+ %changelog
++* Mon Apr 09 2018 Tony Hutter <hutter2@llnl.gov> - 0.7.8-1
++- Released 0.7.8-1, detailed release notes are available at:
++- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.8
+ * Wed Mar 14 2018 Tony Hutter <hutter2@llnl.gov> - 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
+diff --git a/META b/META
+index 64a07f1..0a5132f 100644
+--- a/META
++++ b/META
+@@ -1,7 +1,7 @@
+ Meta:         1
+ Name:         spl
+ Branch:       1.0
+-Version:      0.7.7
++Version:      0.7.8
+ Release:      1
+ Release-Tags: relext
+ License:      GPL
+-- 
+2.14.2
+
index 88fb8e21112e26094be14f1c2b0b536e60e22197..84344e940ae85403c8035e0dd420cb4856c745fb 100644 (file)
@@ -11,3 +11,4 @@
 0011-Fix-more-cstyle-warnings.patch
 0012-Fix-spl-kmod-builds-when-using-rpm-4.14.patch
 0013-Tag-spl-0.7.7.patch
+0014-Tag-spl-0.7.8.patch
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 (file)
index 0000000..94d0ca1
--- /dev/null
@@ -0,0 +1,553 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: sanjeevbagewadi <sanjeev.bagewadi@gmail.com>
+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 <mahrens@delphix.com>
+Reviewed-by: Chunwei Chen <david.chen@nutanix.com>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Sanjeev Bagewadi <sanjeev.bagewadi@gmail.com>
+Closes #7011
+Closes #7054
+(cherry picked from commit b3da003ebfad673bb4ada35f87a18a1ef175e95d)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ .../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->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/0028-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch b/zfs-patches/0028-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch
deleted file mode 100644 (file)
index 87c2f04..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: sanjeevbagewadi <sanjeev.bagewadi@gmail.com>
-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 <faaland1@llnl.gov>
-Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
-Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: Sanjeev Bagewadi <sanjeev.bagewadi@gmail.com>
-Closes #6530
-Closes #7155
-(cherry picked from commit d85011ed696b41f4de963f7932dfb53ea871278b)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0029-contrib-initramfs-add-missing-conf.d-zfs.patch b/zfs-patches/0029-contrib-initramfs-add-missing-conf.d-zfs.patch
deleted file mode 100644 (file)
index ec7ce71..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: LOLi <loli10K@users.noreply.github.com>
-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 <behlendorf1@llnl.gov>
-Reviewed-by: Richard Laager <rlaager@wiktel.com>
-Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
-Closes #7158
-(cherry picked from commit a9ff89e05cd2f420e44b0e50c92d97c166772d2b)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/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 (file)
index 0000000..87c2f04
--- /dev/null
@@ -0,0 +1,56 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: sanjeevbagewadi <sanjeev.bagewadi@gmail.com>
+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 <faaland1@llnl.gov>
+Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
+Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Sanjeev Bagewadi <sanjeev.bagewadi@gmail.com>
+Closes #6530
+Closes #7155
+(cherry picked from commit d85011ed696b41f4de963f7932dfb53ea871278b)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 (file)
index 0000000..ec7ce71
--- /dev/null
@@ -0,0 +1,66 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: LOLi <loli10K@users.noreply.github.com>
+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 <behlendorf1@llnl.gov>
+Reviewed-by: Richard Laager <rlaager@wiktel.com>
+Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
+Closes #7158
+(cherry picked from commit a9ff89e05cd2f420e44b0e50c92d97c166772d2b)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0030-zfs-receive-fails-with-dataset-is-busy.patch b/zfs-patches/0030-zfs-receive-fails-with-dataset-is-busy.patch
deleted file mode 100644 (file)
index bae187b..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: LOLi <loli10K@users.noreply.github.com>
-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 <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Reviewed-by: George Melikov <mail@gmelikov.ru>
-Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
-Closes #7129
-Closes #7154
-(cherry picked from commit 1d805a534b5e1768413a0242b8e92b97cb1a796c)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0031-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch b/zfs-patches/0031-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch
deleted file mode 100644 (file)
index 8fc2b50..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: George Wilson <george.wilson@delphix.com>
-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 <george.wilson@delphix.com>
-Reviewed by: Matthew Ahrens <mahrens@delphix.com>
-Reviewed by: Andriy Gapon <avg@FreeBSD.org>
-Reviewed by: Youzhong Yang <youzhong@gmail.com>
-Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
-Approved by: Dan McDonald <danmcd@omniti.com>
-Ported-by: Giuseppe Di Natale <dinatale2@llnl.gov>
-
-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 <f.gruenbichler@proxmox.com>
----
- 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/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 (file)
index 0000000..bae187b
--- /dev/null
@@ -0,0 +1,90 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: LOLi <loli10K@users.noreply.github.com>
+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 <dinatale2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Reviewed-by: George Melikov <mail@gmelikov.ru>
+Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
+Closes #7129
+Closes #7154
+(cherry picked from commit 1d805a534b5e1768413a0242b8e92b97cb1a796c)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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-Clarify-zinject-8-explanation-of-e.patch b/zfs-patches/0032-Clarify-zinject-8-explanation-of-e.patch
deleted file mode 100644 (file)
index 561a646..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Olaf Faaland <faaland1@llnl.gov>
-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 <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Reviewed-by: George Melikov <mail@gmelikov.ru>
-Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
-Closes #7172
-(cherry picked from commit 26941ce90b8f056949a3bc29da606513af799781)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/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 (file)
index 0000000..8fc2b50
--- /dev/null
@@ -0,0 +1,247 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: George Wilson <george.wilson@delphix.com>
+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 <george.wilson@delphix.com>
+Reviewed by: Matthew Ahrens <mahrens@delphix.com>
+Reviewed by: Andriy Gapon <avg@FreeBSD.org>
+Reviewed by: Youzhong Yang <youzhong@gmail.com>
+Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
+Approved by: Dan McDonald <danmcd@omniti.com>
+Ported-by: Giuseppe Di Natale <dinatale2@llnl.gov>
+
+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 <f.gruenbichler@proxmox.com>
+---
+ 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 (file)
index 0000000..561a646
--- /dev/null
@@ -0,0 +1,40 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Olaf Faaland <faaland1@llnl.gov>
+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 <dinatale2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Reviewed-by: George Melikov <mail@gmelikov.ru>
+Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
+Closes #7172
+(cherry picked from commit 26941ce90b8f056949a3bc29da606513af799781)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0033-Fix-config-issues-frame-size-and-headers.patch b/zfs-patches/0033-Fix-config-issues-frame-size-and-headers.patch
deleted file mode 100644 (file)
index 656e845..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: chrisrd <chris@onthe.net.au>
-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 <behlendorf1@llnl.gov>
-Signed-off-by: Chris Dunlop <chris@onthe.net.au>
-Closes #7169
-(cherry picked from commit 5a84c60fb95ee7ca1393efe93d9d17c80497c6b6)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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 <linux/fs.h>
-+              #include <linux/sched.h>
-               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 <linux/fs.h>
-+              #include <linux/sched.h>
-               #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 <linux/dcache.h>
-+              #include <linux/sched.h>
-               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 <linux/fs.h>
-+              #include <linux/sched.h>
-               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 <linux/mm.h>
-               #include <linux/vmstat.h>
--        ],[
-+      ],[
-                       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/0034-Correct-count_uberblocks-in-mmp.kshlib.patch b/zfs-patches/0034-Correct-count_uberblocks-in-mmp.kshlib.patch
deleted file mode 100644 (file)
index db1e329..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Giuseppe Di Natale <dinatale2@users.noreply.github.com>
-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 <behlendorf1@llnl.gov>
-Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
-Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
-Signed-off-by: Giuseppe Di Natale <dinatale2@llnl.gov>
-Closes #7191
-(cherry picked from commit d5b10b3ef3b5e82b9e5a9bee122f1a0be007dae2)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/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 (file)
index 0000000..656e845
--- /dev/null
@@ -0,0 +1,199 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: chrisrd <chris@onthe.net.au>
+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 <behlendorf1@llnl.gov>
+Signed-off-by: Chris Dunlop <chris@onthe.net.au>
+Closes #7169
+(cherry picked from commit 5a84c60fb95ee7ca1393efe93d9d17c80497c6b6)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 <linux/fs.h>
++              #include <linux/sched.h>
+               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 <linux/fs.h>
++              #include <linux/sched.h>
+               #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 <linux/dcache.h>
++              #include <linux/sched.h>
+               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 <linux/fs.h>
++              #include <linux/sched.h>
+               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 <linux/mm.h>
+               #include <linux/vmstat.h>
+-        ],[
++      ],[
+                       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-Add-SMART-attributes-for-SSD-and-NVMe.patch b/zfs-patches/0035-Add-SMART-attributes-for-SSD-and-NVMe.patch
deleted file mode 100644 (file)
index a18d02d..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: bunder2015 <omfgbunder@gmail.com>
-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 <ezomori.nozomu@gmail.com>
-Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
-Reviewed-by: Tony Hutter <hutter2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: bunder2015 <omfgbunder@gmail.com>
-Closes #7183
-Closes #7193
-(cherry picked from commit c705d8386b21b08aefdc62b6b1a556aab6717316)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0035-Correct-count_uberblocks-in-mmp.kshlib.patch b/zfs-patches/0035-Correct-count_uberblocks-in-mmp.kshlib.patch
new file mode 100644 (file)
index 0000000..db1e329
--- /dev/null
@@ -0,0 +1,38 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Giuseppe Di Natale <dinatale2@users.noreply.github.com>
+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 <behlendorf1@llnl.gov>
+Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
+Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
+Signed-off-by: Giuseppe Di Natale <dinatale2@llnl.gov>
+Closes #7191
+(cherry picked from commit d5b10b3ef3b5e82b9e5a9bee122f1a0be007dae2)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 (file)
index 0000000..a18d02d
--- /dev/null
@@ -0,0 +1,131 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: bunder2015 <omfgbunder@gmail.com>
+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 <ezomori.nozomu@gmail.com>
+Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
+Reviewed-by: Tony Hutter <hutter2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: bunder2015 <omfgbunder@gmail.com>
+Closes #7183
+Closes #7193
+(cherry picked from commit c705d8386b21b08aefdc62b6b1a556aab6717316)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0036-Allow-modprobe-to-fail-when-called-within-systemd.patch b/zfs-patches/0036-Allow-modprobe-to-fail-when-called-within-systemd.patch
deleted file mode 100644 (file)
index a918450..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Matthew Thode <mthode@mthode.org>
-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 <ezomori.nozomu@gmail.com>
-Reviewed-by: Kash Pande <kash@tripleback.net>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: Matthew Thode <mthode@mthode.org>
-Closes #7174
-(cherry picked from commit 30ac8de48a2bb680e15dfe8879faaa7b461b771c)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/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 (file)
index 0000000..a918450
--- /dev/null
@@ -0,0 +1,52 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Matthew Thode <mthode@mthode.org>
+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 <ezomori.nozomu@gmail.com>
+Reviewed-by: Kash Pande <kash@tripleback.net>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Matthew Thode <mthode@mthode.org>
+Closes #7174
+(cherry picked from commit 30ac8de48a2bb680e15dfe8879faaa7b461b771c)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0037-Linux-4.16-compat-use-correct-_dec_and_test.patch b/zfs-patches/0037-Linux-4.16-compat-use-correct-_dec_and_test.patch
deleted file mode 100644 (file)
index 00d4b4f..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tony Hutter <hutter2@llnl.gov>
-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 <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: Tony Hutter <hutter2@llnl.gov>
-Closes: #7179
-Closes: #7211
-(cherry picked from commit e5ba614d05bde1e98ba46d5b75cf6b8a0701c2ca)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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 <linux/backing-dev.h>
-+              #include <linux/refcount.h>
-+              #include <linux/posix_acl.h>
-+      ],[
-+              struct posix_acl acl;
-+              refcount_t *r __attribute__ ((unused)) = &acl.a_refcount;
-+      ],[
-+              AC_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/0038-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch b/zfs-patches/0038-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch
deleted file mode 100644 (file)
index ad004d2..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Olaf Faaland <faaland1@llnl.gov>
-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 <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
-Closes #7182
-(cherry picked from commit b1f61f05b4b2edc77ec5f3d28d041d7b3c873f01)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/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 (file)
index 0000000..00d4b4f
--- /dev/null
@@ -0,0 +1,85 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tony Hutter <hutter2@llnl.gov>
+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 <dinatale2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Tony Hutter <hutter2@llnl.gov>
+Closes: #7179
+Closes: #7211
+(cherry picked from commit e5ba614d05bde1e98ba46d5b75cf6b8a0701c2ca)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 <linux/backing-dev.h>
++              #include <linux/refcount.h>
++              #include <linux/posix_acl.h>
++      ],[
++              struct posix_acl acl;
++              refcount_t *r __attribute__ ((unused)) = &acl.a_refcount;
++      ],[
++              AC_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 (file)
index 0000000..ad004d2
--- /dev/null
@@ -0,0 +1,39 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Olaf Faaland <faaland1@llnl.gov>
+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 <dinatale2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
+Closes #7182
+(cherry picked from commit b1f61f05b4b2edc77ec5f3d28d041d7b3c873f01)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0039-Report-duration-and-error-in-mmp_history-entries.patch b/zfs-patches/0039-Report-duration-and-error-in-mmp_history-entries.patch
deleted file mode 100644 (file)
index f05ac98..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Olaf Faaland <faaland1@llnl.gov>
-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 <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
-Closes #7190
-(cherry picked from commit 2644784f49a6b6be063d54ca0e1662ee6bef7ebd)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0040-Fix-free-memory-calculation-on-v3.14.patch b/zfs-patches/0040-Fix-free-memory-calculation-on-v3.14.patch
deleted file mode 100644 (file)
index 5c55057..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: chrisrd <chris@onthe.net.au>
-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 <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Reviewed-by: George Melikov <mail@gmelikov.ru>
-Signed-off-by: Chris Dunlop <chris@onthe.net.au>
-Closes #7170
-(cherry picked from commit 338523dd6ec641cc4d552c3f67e1becfb9e22b0a)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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 <sys/fs/swapnode.h>
- #include <sys/zpl.h>
- #include <linux/mm_compat.h>
-+#include <linux/page_compat.h>
- #endif
- #include <sys/callb.h>
- #include <sys/kstat.h>
-@@ -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 <linux/mm.h>
-+              #include <linux/vmstat.h>
-+      ],[
-+              (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 <linux/mm.h>
-+              #include <linux/vmstat.h>
-+      ],[
-+              (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 <linux/mm.h>
--              #include <linux/vmstat.h>
--      ],[
--                      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 = <<EOT;
-+usage: config-enum enum [file ...]
-+
-+Returns the elements from an enum declaration.
-+
-+"Best effort": we're not building an entire C interpreter here!
-+EOT
-+
-+use warnings;
-+use strict;
-+use Getopt::Std;
-+
-+my %opts;
-+
-+if (!getopts("", \%opts) || @ARGV < 1) {
-+      print $usage;
-+      exit 2;
-+}
-+
-+my $enum = shift;
-+
-+my $in_enum = 0;
-+
-+while (<>) {
-+      # 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/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 (file)
index 0000000..f05ac98
--- /dev/null
@@ -0,0 +1,237 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Olaf Faaland <faaland1@llnl.gov>
+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 <dinatale2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
+Closes #7190
+(cherry picked from commit 2644784f49a6b6be063d54ca0e1662ee6bef7ebd)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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-Add-scrub-after-resilver-zed-script.patch b/zfs-patches/0041-Add-scrub-after-resilver-zed-script.patch
deleted file mode 100644 (file)
index 7c6002c..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tony Hutter <hutter2@llnl.gov>
-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 <behlendorf1@llnl.gov>
-Reviewed-by: Richard Laager <rlaager@wiktel.com>
-Signed-off-by: Tony Hutter <hutter2@llnl.gov>
-Closes #4662
-Closes #7086
-(cherry picked from commit 99920d823e8e1510a0ad133c985bd2aa11a02834)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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 ea2dbb282..e4a11a0fa 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/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 (file)
index 0000000..5c55057
--- /dev/null
@@ -0,0 +1,451 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: chrisrd <chris@onthe.net.au>
+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 <dinatale2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Reviewed-by: George Melikov <mail@gmelikov.ru>
+Signed-off-by: Chris Dunlop <chris@onthe.net.au>
+Closes #7170
+(cherry picked from commit 338523dd6ec641cc4d552c3f67e1becfb9e22b0a)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 <sys/fs/swapnode.h>
+ #include <sys/zpl.h>
+ #include <linux/mm_compat.h>
++#include <linux/page_compat.h>
+ #endif
+ #include <sys/callb.h>
+ #include <sys/kstat.h>
+@@ -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 <linux/mm.h>
++              #include <linux/vmstat.h>
++      ],[
++              (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 <linux/mm.h>
++              #include <linux/vmstat.h>
++      ],[
++              (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 <linux/mm.h>
+-              #include <linux/vmstat.h>
+-      ],[
+-                      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 = <<EOT;
++usage: config-enum enum [file ...]
++
++Returns the elements from an enum declaration.
++
++"Best effort": we're not building an entire C interpreter here!
++EOT
++
++use warnings;
++use strict;
++use Getopt::Std;
++
++my %opts;
++
++if (!getopts("", \%opts) || @ARGV < 1) {
++      print $usage;
++      exit 2;
++}
++
++my $enum = shift;
++
++my $in_enum = 0;
++
++while (<>) {
++      # 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-SMART-self-test-results-to-zpool-status-c.patch b/zfs-patches/0042-Add-SMART-self-test-results-to-zpool-status-c.patch
deleted file mode 100644 (file)
index a562ecd..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tony Hutter <hutter2@llnl.gov>
-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 <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: Tony Hutter <hutter2@llnl.gov>
-Closes #7178
-(cherry picked from commit 5e3085e360161456fe2af697494c479de0ee2085)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0042-Add-scrub-after-resilver-zed-script.patch b/zfs-patches/0042-Add-scrub-after-resilver-zed-script.patch
new file mode 100644 (file)
index 0000000..ee8b608
--- /dev/null
@@ -0,0 +1,516 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tony Hutter <hutter2@llnl.gov>
+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 <behlendorf1@llnl.gov>
+Reviewed-by: Richard Laager <rlaager@wiktel.com>
+Signed-off-by: Tony Hutter <hutter2@llnl.gov>
+Closes #4662
+Closes #7086
+(cherry picked from commit 99920d823e8e1510a0ad133c985bd2aa11a02834)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 (file)
index 0000000..a562ecd
--- /dev/null
@@ -0,0 +1,322 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tony Hutter <hutter2@llnl.gov>
+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 <dinatale2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Tony Hutter <hutter2@llnl.gov>
+Closes #7178
+(cherry picked from commit 5e3085e360161456fe2af697494c479de0ee2085)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0043-Fix-zpool-8-list-example-to-match-actual-format.patch b/zfs-patches/0043-Fix-zpool-8-list-example-to-match-actual-format.patch
deleted file mode 100644 (file)
index 6817629..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
-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 <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: Tomohiro Kusumi <kusumi.tomohiro@osnexus.com>
-Closes #7244
-(cherry picked from commit bcaba38e428be8dc90564d15c7e13f154c535edd)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0044-Fix-some-typos.patch b/zfs-patches/0044-Fix-some-typos.patch
deleted file mode 100644 (file)
index 43da44d..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-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 <dinatale2@llnl.gov>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Reviewed by: George Melikov <mail@gmelikov.ru>
-Signed-off-by: John Eismeier <john.eismeier@gmail.com>
-Closes #7237
-(cherry picked from commit 33bb1e82568a9734cc3f41d3e1d33003ebf0e123)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/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 (file)
index 0000000..6817629
--- /dev/null
@@ -0,0 +1,66 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
+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 <dinatale2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Tomohiro Kusumi <kusumi.tomohiro@osnexus.com>
+Closes #7244
+(cherry picked from commit bcaba38e428be8dc90564d15c7e13f154c535edd)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 (file)
index 0000000..43da44d
--- /dev/null
@@ -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 <dinatale2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Reviewed by: George Melikov <mail@gmelikov.ru>
+Signed-off-by: John Eismeier <john.eismeier@gmail.com>
+Closes #7237
+(cherry picked from commit 33bb1e82568a9734cc3f41d3e1d33003ebf0e123)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0045-Increment-zil_itx_needcopy_bytes-properly.patch b/zfs-patches/0045-Increment-zil_itx_needcopy_bytes-properly.patch
deleted file mode 100644 (file)
index f66d8db..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: chrisrd <chris@onthe.net.au>
-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 <Richard.Elling@RichardElling.com>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: Chris Dunlop <chris@onthe.net.au>
-Closes #6988
-Closes #7176
-(cherry picked from commit 792f88131c647a70440c709c78d43210db6c6534)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0046-Change-checksum-IO-delay-ratelimit-values.patch b/zfs-patches/0046-Change-checksum-IO-delay-ratelimit-values.patch
deleted file mode 100644 (file)
index 0c36c60..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tony Hutter <hutter2@llnl.gov>
-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 <ezomori.nozomu@gmail.com>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
-Signed-off-by: Tony Hutter <hutter2@llnl.gov>
-Closes #7252
-(cherry picked from commit 6dc40e2ada2d0d008bd314ff3525f2b0acc2bb01)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0046-Increment-zil_itx_needcopy_bytes-properly.patch b/zfs-patches/0046-Increment-zil_itx_needcopy_bytes-properly.patch
new file mode 100644 (file)
index 0000000..f66d8db
--- /dev/null
@@ -0,0 +1,46 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: chrisrd <chris@onthe.net.au>
+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 <Richard.Elling@RichardElling.com>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Chris Dunlop <chris@onthe.net.au>
+Closes #6988
+Closes #7176
+(cherry picked from commit 792f88131c647a70440c709c78d43210db6c6534)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 (file)
index 0000000..0c36c60
--- /dev/null
@@ -0,0 +1,201 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tony Hutter <hutter2@llnl.gov>
+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 <ezomori.nozomu@gmail.com>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
+Signed-off-by: Tony Hutter <hutter2@llnl.gov>
+Closes #7252
+(cherry picked from commit 6dc40e2ada2d0d008bd314ff3525f2b0acc2bb01)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0047-Linux-4.16-compat-get_disk_and_module.patch b/zfs-patches/0047-Linux-4.16-compat-get_disk_and_module.patch
deleted file mode 100644 (file)
index 93acdef..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Giuseppe Di Natale <dinatale2@users.noreply.github.com>
-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 <ezomori.nozomu@gmail.com>
-Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Signed-off-by: Giuseppe Di Natale <dinatale2@llnl.gov>
-Closes #7264
-(cherry picked from commit 8d7f17798d0faa0001bf7257759be0c688b91044)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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 <linux/genhd.h>
-+      ], [
-+              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/0048-Detect-long-config-lock-acquisition-in-mmp.patch b/zfs-patches/0048-Detect-long-config-lock-acquisition-in-mmp.patch
deleted file mode 100644 (file)
index 6e53d3d..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Olaf Faaland <faaland1@llnl.gov>
-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 <behlendorf1@llnl.gov>
-Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
-Closes #7212
-(cherry picked from commit c17922b8a9db00ad7e7d59a5ff975b2a1edcf887)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/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 (file)
index 0000000..93acdef
--- /dev/null
@@ -0,0 +1,98 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Giuseppe Di Natale <dinatale2@users.noreply.github.com>
+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 <ezomori.nozomu@gmail.com>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Giuseppe Di Natale <dinatale2@llnl.gov>
+Closes #7264
+(cherry picked from commit 8d7f17798d0faa0001bf7257759be0c688b91044)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 <linux/genhd.h>
++      ], [
++              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 (file)
index 0000000..6e53d3d
--- /dev/null
@@ -0,0 +1,46 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Olaf Faaland <faaland1@llnl.gov>
+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 <behlendorf1@llnl.gov>
+Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
+Closes #7212
+(cherry picked from commit c17922b8a9db00ad7e7d59a5ff975b2a1edcf887)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0049-Take-user-namespaces-into-account-in-policy-checks.patch b/zfs-patches/0049-Take-user-namespaces-into-account-in-policy-checks.patch
deleted file mode 100644 (file)
index c0349e8..0000000
+++ /dev/null
@@ -1,786 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Wolfgang Bumiller <Blub@users.noreply.github.com>
-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 <behlendorf1@llnl.gov>
-Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-Closes #6800
-Closes #7270
-(cherry picked from commit 3808006edfc46b18f0a40a2e9df54c6567bf52cc)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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 <stdio.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <limits.h>
-+#include <sys/types.h>
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <sys/wait.h>
-+#include <fcntl.h>
-+#include <errno.h>
-+#include <signal.h>
-+#include <sched.h>
-+
-+#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 <commands> ...\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 <linux/capability.h>
-+      ],[
-+              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 <linux/cred.h>
-+      ],[
-+              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 <linux/uidgid.h>
-+      ],[
-+              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 e4a11a0fa..4b2694202 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/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 (file)
index 0000000..604a33d
--- /dev/null
@@ -0,0 +1,786 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Wolfgang Bumiller <Blub@users.noreply.github.com>
+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 <behlendorf1@llnl.gov>
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Closes #6800
+Closes #7270
+(cherry picked from commit 3808006edfc46b18f0a40a2e9df54c6567bf52cc)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 <stdio.h>
++#include <unistd.h>
++#include <string.h>
++#include <limits.h>
++#include <sys/types.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <sys/wait.h>
++#include <fcntl.h>
++#include <errno.h>
++#include <signal.h>
++#include <sched.h>
++
++#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 <commands> ...\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 <linux/capability.h>
++      ],[
++              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 <linux/cred.h>
++      ],[
++              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 <linux/uidgid.h>
++      ],[
++              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/0050-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch b/zfs-patches/0050-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch
deleted file mode 100644 (file)
index bebe5b1..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-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 <behlendorf1@llnl.gov>
-Signed-off-by: Paul Zuchowski <pzuchowski@datto.com>
-Closes #6939
-Closes #7261
-(cherry picked from commit 0a0af41bd926ca20a26d7476d792ce82bca9c077)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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 #<whole_disk_name>
-       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 #<slice_num> <slice_start> <size_plus_units>  <whole_disk
-       typeset start=$2
-       typeset size=$3
-       typeset disk=$4
--      [[ -z $slicenum || -z $size || -z $disk ]] && \
--          log_fail "The slice, size or disk name is unspecified."
-       if is_linux; then
-+              if [[ -z $size || -z $disk ]]; then
-+                      log_fail "The size or disk name is unspecified."
-+              fi
-               typeset size_mb=${size%%[mMgG]}
-               size_mb=${size_mb%%[mMgG][bB]}
-@@ -841,6 +846,10 @@ function set_partition #<slice_num> <slice_start> <size_plus_units>  <whole_disk
-               blockdev --rereadpt $DEV_DSKDIR/$disk 2>/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/0051-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch b/zfs-patches/0051-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch
deleted file mode 100644 (file)
index 12cbe4d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: LOLi <loli10K@users.noreply.github.com>
-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 <behlendorf1@llnl.gov>
-Signed-off-by:  loli10K <ezomori.nozomu@gmail.com>
-Closes #7284
-(cherry picked from commit dc0176eeec9719827610fc68742ea3c76796a81f)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/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 (file)
index 0000000..bebe5b1
--- /dev/null
@@ -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 <behlendorf1@llnl.gov>
+Signed-off-by: Paul Zuchowski <pzuchowski@datto.com>
+Closes #6939
+Closes #7261
+(cherry picked from commit 0a0af41bd926ca20a26d7476d792ce82bca9c077)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 #<whole_disk_name>
+       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 #<slice_num> <slice_start> <size_plus_units>  <whole_disk
+       typeset start=$2
+       typeset size=$3
+       typeset disk=$4
+-      [[ -z $slicenum || -z $size || -z $disk ]] && \
+-          log_fail "The slice, size or disk name is unspecified."
+       if is_linux; then
++              if [[ -z $size || -z $disk ]]; then
++                      log_fail "The size or disk name is unspecified."
++              fi
+               typeset size_mb=${size%%[mMgG]}
+               size_mb=${size_mb%%[mMgG][bB]}
+@@ -841,6 +846,10 @@ function set_partition #<slice_num> <slice_start> <size_plus_units>  <whole_disk
+               blockdev --rereadpt $DEV_DSKDIR/$disk 2>/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 (file)
index 0000000..12cbe4d
--- /dev/null
@@ -0,0 +1,39 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: LOLi <loli10K@users.noreply.github.com>
+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 <behlendorf1@llnl.gov>
+Signed-off-by:  loli10K <ezomori.nozomu@gmail.com>
+Closes #7284
+(cherry picked from commit dc0176eeec9719827610fc68742ea3c76796a81f)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0052-Handle-zio_resume-and-mmp-off.patch b/zfs-patches/0052-Handle-zio_resume-and-mmp-off.patch
deleted file mode 100644 (file)
index 3dfc727..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Olaf Faaland <faaland1@llnl.gov>
-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 <behlendorf1@llnl.gov>
-Reviewed-by: Tony Hutter <hutter2@llnl.gov>
-Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
-Closes #7286
-(cherry picked from commit 267fd7b0f14251026c35d7ceab4fbbe2f06717e6)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0053-Fix-MMP-write-frequency-for-large-pools.patch b/zfs-patches/0053-Fix-MMP-write-frequency-for-large-pools.patch
deleted file mode 100644 (file)
index 1b334a2..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Brian Behlendorf <behlendorf1@llnl.gov>
-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 <mail@gmelikov.ru>
-Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
-Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
-Reviewed-by: Tony Hutter <hutter2@llnl.gov>
-Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
-Closes #7205
-Closes #7289
-(cherry picked from commit c30e716c8149b7df7cf968373c22aa00b48d17b8)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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/0053-Handle-zio_resume-and-mmp-off.patch b/zfs-patches/0053-Handle-zio_resume-and-mmp-off.patch
new file mode 100644 (file)
index 0000000..3dfc727
--- /dev/null
@@ -0,0 +1,60 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Olaf Faaland <faaland1@llnl.gov>
+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 <behlendorf1@llnl.gov>
+Reviewed-by: Tony Hutter <hutter2@llnl.gov>
+Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
+Closes #7286
+(cherry picked from commit 267fd7b0f14251026c35d7ceab4fbbe2f06717e6)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 (file)
index 0000000..1b334a2
--- /dev/null
@@ -0,0 +1,72 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Brian Behlendorf <behlendorf1@llnl.gov>
+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 <mail@gmelikov.ru>
+Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
+Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
+Reviewed-by: Tony Hutter <hutter2@llnl.gov>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes #7205
+Closes #7289
+(cherry picked from commit c30e716c8149b7df7cf968373c22aa00b48d17b8)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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/0054-Tag-zfs-0.7.7.patch b/zfs-patches/0054-Tag-zfs-0.7.7.patch
deleted file mode 100644 (file)
index edd2710..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tony Hutter <hutter2@llnl.gov>
-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 <hutter2@llnl.gov>
-(cherry picked from commit 240ccfc13adb46faf3d6e5e17e25a9769dd06733)
-Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
----
- 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 <hutter2@llnl.gov> - 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 <hutter2@llnl.gov> - 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 <hutter2@llnl.gov> - 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 <hutter2@llnl.gov> - 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/0055-Tag-zfs-0.7.7.patch b/zfs-patches/0055-Tag-zfs-0.7.7.patch
new file mode 100644 (file)
index 0000000..edd2710
--- /dev/null
@@ -0,0 +1,63 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tony Hutter <hutter2@llnl.gov>
+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 <hutter2@llnl.gov>
+(cherry picked from commit 240ccfc13adb46faf3d6e5e17e25a9769dd06733)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 <hutter2@llnl.gov> - 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 <hutter2@llnl.gov> - 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 <hutter2@llnl.gov> - 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 <hutter2@llnl.gov> - 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/0056-Revert-Handle-zap_add-failures-in-mixed.patch b/zfs-patches/0056-Revert-Handle-zap_add-failures-in-mixed.patch
new file mode 100644 (file)
index 0000000..77f3ecb
--- /dev/null
@@ -0,0 +1,551 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tony Hutter <hutter2@llnl.gov>
+Date: Mon, 9 Apr 2018 14:24:46 -0700
+Subject: [PATCH] Revert "Handle zap_add() failures in mixed ... "
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This reverts commit cc63068e95ee725cce03b1b7ce50179825a6cda5.
+
+Under certain circumstances this change can result in an ENOSPC
+error when adding new files to a directory.  See #7401 for full
+details.
+
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Tony Hutter <hutter2@llnl.gov>
+Issue #7401
+Closes #7416
+(cherry picked from commit 9a2e90c9fc469d377c14eb863952261f9ec12d2c)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ .../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, 32 insertions(+), 289 deletions(-)
+ delete 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 00cb59074..00a19c7ff 100644
+--- a/tests/zfs-tests/tests/functional/casenorm/Makefile.am
++++ b/tests/zfs-tests/tests/functional/casenorm/Makefile.am
+@@ -9,7 +9,6 @@ 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 a3da1036a..e784c5963 100644
+--- a/include/sys/zap_leaf.h
++++ b/include/sys/zap_leaf.h
+@@ -46,15 +46,10 @@ struct zap_stats;
+  * block size (1<<l->l_bs) - hash entry size (2) * number of hash
+  * entries - header space (2*chunksize)
+  */
+-#define       ZAP_LEAF_NUMCHUNKS_BS(bs) \
+-      (((1<<(bs)) - 2*ZAP_LEAF_HASH_NUMENTRIES_BS(bs)) / \
++#define       ZAP_LEAF_NUMCHUNKS(l) \
++      (((1<<(l)->l_bs) - 2*ZAP_LEAF_HASH_NUMENTRIES(l)) / \
+       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)
+@@ -79,10 +74,8 @@ struct zap_stats;
+  * which is less than block size / CHUNKSIZE (24) / minimum number of
+  * chunks per entry (3).
+  */
+-#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)))
++#define       ZAP_LEAF_HASH_SHIFT(l) ((l)->l_bs - 5)
++#define       ZAP_LEAF_HASH_NUMENTRIES(l) (1 << ZAP_LEAF_HASH_SHIFT(l))
+ /*
+  * 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 9843d8c50..ee9962bff 100644
+--- a/module/zfs/zap.c
++++ b/module/zfs/zap.c
+@@ -819,19 +819,15 @@ 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);
+@@ -855,29 +851,10 @@ 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) {
+-                      prev_l = l;
+-                      expand_retries++;
++              if (err == 0)
+                       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 526e46606..c342695c7 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 34bef3e63..3ebf995c6 100644
+--- a/module/zfs/zap_micro.c
++++ b/module/zfs/zap_micro.c
+@@ -363,41 +363,6 @@ 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)
+ {
+@@ -1226,8 +1191,7 @@ 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 ||
+-          !mze_canfit_fzap_leaf(zn, zn->zn_hash)) {
++          strlen(key) >= MZAP_NAME_LEN) {
+               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 6398a1d15..9a8bbccd9 100644
+--- a/module/zfs/zfs_dir.c
++++ b/module/zfs/zfs_dir.c
+@@ -742,11 +742,7 @@ zfs_dirent(znode_t *zp, uint64_t mode)
+ }
+ /*
+- * 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.
++ * Link zp into dl.  Can only fail if zp has been unlinked.
+  */
+ int
+ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
+@@ -780,24 +776,6 @@ 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,
+@@ -835,6 +813,11 @@ 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 8a7ad702c..6f6ce79db 100644
+--- a/module/zfs/zfs_vnops.c
++++ b/module/zfs/zfs_vnops.c
+@@ -1443,22 +1443,10 @@ 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;
+@@ -2049,18 +2037,13 @@ 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.
+        */
+-      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);
++      (void) zfs_link_create(dl, zp, tx, ZNEW);
+       *ipp = ZTOI(zp);
+@@ -2070,7 +2053,6 @@ 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);
+@@ -2080,14 +2062,10 @@ out:
+       if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+               zil_commit(zilog, 0);
+-      if (error != 0) {
+-              iput(ZTOI(zp));
+-      } else {
+-              zfs_inode_update(dzp);
+-              zfs_inode_update(zp);
+-      }
++      zfs_inode_update(dzp);
++      zfs_inode_update(zp);
+       ZFS_EXIT(zfsvfs);
+-      return (error);
++      return (0);
+ }
+ /*
+@@ -3705,13 +3683,6 @@ 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);
+               }
+       }
+@@ -3882,18 +3853,14 @@ top:
+       /*
+        * Insert the new object into the directory.
+        */
+-      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);
++      (void) zfs_link_create(dl, zp, tx, ZNEW);
+-              zfs_inode_update(dzp);
+-              zfs_inode_update(zp);
+-      }
++      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_acl_ids_free(&acl_ids);
+@@ -3901,14 +3868,10 @@ top:
+       zfs_dirent_unlock(dl);
+-      if (error == 0) {
+-              *ipp = ZTOI(zp);
++      *ipp = ZTOI(zp);
+-              if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+-                      zil_commit(zilog, 0);
+-      } else {
+-              iput(ZTOI(zp));
+-      }
++      if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
++              zil_commit(zilog, 0);
+       ZFS_EXIT(zfsvfs);
+       return (error);
+diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run
+index 25ae3fe5e..4b2694202 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', 'mixed_create_failure']
++tests = ['case_all_values', 'norm_all_values']
+ 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
+deleted file mode 100755
+index 51b5bb3f6..000000000
+--- a/tests/zfs-tests/tests/functional/casenorm/mixed_create_failure.ksh
++++ /dev/null
+@@ -1,136 +0,0 @@
+-#!/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/0057-Tag-zfs-0.7.8.patch b/zfs-patches/0057-Tag-zfs-0.7.8.patch
new file mode 100644 (file)
index 0000000..e923c1b
--- /dev/null
@@ -0,0 +1,63 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tony Hutter <hutter2@llnl.gov>
+Date: Mon, 9 Apr 2018 14:31:57 -0700
+Subject: [PATCH] Tag zfs-0.7.8
+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 <hutter2@llnl.gov>
+(cherry picked from commit bd69ae3b537ac4e796c53b0c3d6efdc92d652da6)
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ 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 bf52fa2c4..9db8e370a 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
++* Mon Apr 09 2018 Tony Hutter <hutter2@llnl.gov> - 0.7.8-1
++- Released 0.7.8-1, detailed release notes are available at:
++- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.8
+ * Wed Mar 14 2018 Tony Hutter <hutter2@llnl.gov> - 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
+diff --git a/rpm/generic/zfs.spec.in b/rpm/generic/zfs.spec.in
+index 7479e987e..769bdab10 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
++* Mon Apr 09 2018 Tony Hutter <hutter2@llnl.gov> - 0.7.8-1
++- Released 0.7.8-1, detailed release notes are available at:
++- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.8
+ * Wed Mar 14 2018 Tony Hutter <hutter2@llnl.gov> - 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
+diff --git a/META b/META
+index eefafb10d..615008960 100644
+--- a/META
++++ b/META
+@@ -1,7 +1,7 @@
+ Meta:         1
+ Name:         zfs
+ Branch:       1.0
+-Version:      0.7.7
++Version:      0.7.8
+ Release:      1
+ Release-Tags: relext
+ License:      CDDL
+-- 
+2.14.2
+
index e248e85e25eacf46eaa6cfb26d4e6701ab0e281e..5ae2941f6c907afe61879fc26c7cc624ee0240f5 100644 (file)
 0025-Fix-zdb-R-decompression.patch
 0026-Fix-zdb-E-segfault.patch
 0027-Fix-zdb-ed-on-objset-for-exported-pool.patch
-0028-mmp-should-use-a-fixed-tag-for-spa_config-locks.patch
-0029-contrib-initramfs-add-missing-conf.d-zfs.patch
-0030-zfs-receive-fails-with-dataset-is-busy.patch
-0031-OpenZFS-8857-zio_remove_child-panic-due-to-already-d.patch
-0032-Clarify-zinject-8-explanation-of-e.patch
-0033-Fix-config-issues-frame-size-and-headers.patch
-0034-Correct-count_uberblocks-in-mmp.kshlib.patch
-0035-Add-SMART-attributes-for-SSD-and-NVMe.patch
-0036-Allow-modprobe-to-fail-when-called-within-systemd.patch
-0037-Linux-4.16-compat-use-correct-_dec_and_test.patch
-0038-Do-not-initiate-MMP-writes-while-pool-is-suspended.patch
-0039-Report-duration-and-error-in-mmp_history-entries.patch
-0040-Fix-free-memory-calculation-on-v3.14.patch
-0041-Add-scrub-after-resilver-zed-script.patch
-0042-Add-SMART-self-test-results-to-zpool-status-c.patch
-0043-Fix-zpool-8-list-example-to-match-actual-format.patch
-0044-Fix-some-typos.patch
-0045-Increment-zil_itx_needcopy_bytes-properly.patch
-0046-Change-checksum-IO-delay-ratelimit-values.patch
-0047-Linux-4.16-compat-get_disk_and_module.patch
-0048-Detect-long-config-lock-acquisition-in-mmp.patch
-0049-Take-user-namespaces-into-account-in-policy-checks.patch
-0050-zdb-and-inuse-tests-don-t-pass-with-real-disks.patch
-0051-Fix-zfs-kmod-builds-when-using-rpm-4.14.patch
-0052-Handle-zio_resume-and-mmp-off.patch
-0053-Fix-MMP-write-frequency-for-large-pools.patch
-0054-Tag-zfs-0.7.7.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
+0056-Revert-Handle-zap_add-failures-in-mixed.patch
+0057-Tag-zfs-0.7.8.patch