]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/spa.c
Report pool suspended due to MMP
[mirror_zfs.git] / module / zfs / spa.c
index b9fa45f8299e015bc3889c6aef9bb66311359b4d..561f4d04bfc9c0a17354880e419157afb06126ed 100644 (file)
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2015, Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2013, 2014, Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
+ * Copyright 2013 Saso Kiselkov. All rights reserved.
+ * Copyright (c) 2014 Integros [integros.com]
+ * Copyright 2016 Toomas Soome <tsoome@me.com>
+ * Copyright (c) 2016 Actifio, Inc. All rights reserved.
+ * Copyright (c) 2017 Datto Inc.
+ * Copyright 2017 Joyent, Inc.
  */
 
 /*
@@ -47,6 +55,7 @@
 #include <sys/vdev_disk.h>
 #include <sys/metaslab.h>
 #include <sys/metaslab_impl.h>
+#include <sys/mmp.h>
 #include <sys/uberblock_impl.h>
 #include <sys/txg.h>
 #include <sys/avl.h>
@@ -70,6 +79,8 @@
 #include <sys/zvol.h>
 
 #ifdef _KERNEL
+#include <sys/fm/protocol.h>
+#include <sys/fm/util.h>
 #include <sys/bootprops.h>
 #include <sys/callb.h>
 #include <sys/cpupart.h>
 #include "zfs_prop.h"
 #include "zfs_comutil.h"
 
+/*
+ * The interval, in seconds, at which failed configuration cache file writes
+ * should be retried.
+ */
+static int zfs_ccw_retry_interval = 300;
+
 typedef enum zti_modes {
        ZTI_MODE_FIXED,                 /* value is # of threads (min 1) */
        ZTI_MODE_BATCH,                 /* cpu-intensive; value is ignored */
@@ -126,13 +143,16 @@ static const char *const zio_taskq_types[ZIO_TASKQ_TYPES] = {
 const zio_taskq_info_t zio_taskqs[ZIO_TYPES][ZIO_TASKQ_TYPES] = {
        /* ISSUE        ISSUE_HIGH      INTR            INTR_HIGH */
        { ZTI_ONE,      ZTI_NULL,       ZTI_ONE,        ZTI_NULL }, /* NULL */
-       { ZTI_N(8),     ZTI_NULL,       ZTI_BATCH,      ZTI_NULL }, /* READ */
-       { ZTI_BATCH,    ZTI_N(5),       ZTI_N(16),      ZTI_N(5) }, /* WRITE */
-       { ZTI_P(4, 8),  ZTI_NULL,       ZTI_ONE,        ZTI_NULL }, /* FREE */
+       { ZTI_N(8),     ZTI_NULL,       ZTI_P(12, 8),   ZTI_NULL }, /* READ */
+       { ZTI_BATCH,    ZTI_N(5),       ZTI_P(12, 8),   ZTI_N(5) }, /* WRITE */
+       { ZTI_P(12, 8), ZTI_NULL,       ZTI_ONE,        ZTI_NULL }, /* FREE */
        { ZTI_ONE,      ZTI_NULL,       ZTI_ONE,        ZTI_NULL }, /* CLAIM */
        { ZTI_ONE,      ZTI_NULL,       ZTI_ONE,        ZTI_NULL }, /* IOCTL */
 };
 
+static sysevent_t *spa_event_create(spa_t *spa, vdev_t *vd, nvlist_t *hist_nvl,
+    const char *name);
+static void spa_event_post(sysevent_t *ev);
 static void spa_sync_version(void *arg, dmu_tx_t *tx);
 static void spa_sync_props(void *arg, dmu_tx_t *tx);
 static boolean_t spa_has_active_shared_spare(spa_t *spa);
@@ -170,7 +190,7 @@ spa_prop_add_list(nvlist_t *nvl, zpool_prop_t prop, char *strval,
        const char *propname = zpool_prop_to_name(prop);
        nvlist_t *propval;
 
-       VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_PUSHPAGE) == 0);
+       VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
        VERIFY(nvlist_add_uint64(propval, ZPROP_SOURCE, src) == 0);
 
        if (strval != NULL)
@@ -190,13 +210,10 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
 {
        vdev_t *rvd = spa->spa_root_vdev;
        dsl_pool_t *pool = spa->spa_dsl_pool;
-       uint64_t size;
-       uint64_t alloc;
-       uint64_t space;
-       uint64_t cap, version;
-       zprop_source_t src = ZPROP_SRC_NONE;
+       uint64_t size, alloc, cap, version;
+       const zprop_source_t src = ZPROP_SRC_NONE;
        spa_config_dirent_t *dp;
-       int c;
+       metaslab_class_t *mc = spa_normal_class(spa);
 
        ASSERT(MUTEX_HELD(&spa->spa_props_lock));
 
@@ -209,14 +226,10 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
                spa_prop_add_list(*nvp, ZPOOL_PROP_FREE, NULL,
                    size - alloc, src);
 
-               space = 0;
-               for (c = 0; c < rvd->vdev_children; c++) {
-                       vdev_t *tvd = rvd->vdev_child[c];
-                       space += tvd->vdev_max_asize - tvd->vdev_asize;
-               }
-               spa_prop_add_list(*nvp, ZPOOL_PROP_EXPANDSZ, NULL, space,
-                   src);
-
+               spa_prop_add_list(*nvp, ZPOOL_PROP_FRAGMENTATION, NULL,
+                   metaslab_class_fragmentation(mc), src);
+               spa_prop_add_list(*nvp, ZPOOL_PROP_EXPANDSZ, NULL,
+                   metaslab_class_expandable_space(mc), src);
                spa_prop_add_list(*nvp, ZPOOL_PROP_READONLY, NULL,
                    (spa_mode(spa) == FREAD), src);
 
@@ -230,27 +243,37 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
                    rvd->vdev_state, src);
 
                version = spa_version(spa);
-               if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION))
-                       src = ZPROP_SRC_DEFAULT;
-               else
-                       src = ZPROP_SRC_LOCAL;
-               spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src);
+               if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION)) {
+                       spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL,
+                           version, ZPROP_SRC_DEFAULT);
+               } else {
+                       spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL,
+                           version, ZPROP_SRC_LOCAL);
+               }
        }
 
        if (pool != NULL) {
-               dsl_dir_t *freedir = pool->dp_free_dir;
-
                /*
                 * The $FREE directory was introduced in SPA_VERSION_DEADLISTS,
                 * when opening pools before this version freedir will be NULL.
                 */
-               if (freedir != NULL) {
+               if (pool->dp_free_dir != NULL) {
                        spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING, NULL,
-                           freedir->dd_phys->dd_used_bytes, src);
+                           dsl_dir_phys(pool->dp_free_dir)->dd_used_bytes,
+                           src);
                } else {
                        spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING,
                            NULL, 0, src);
                }
+
+               if (pool->dp_leak_dir != NULL) {
+                       spa_prop_add_list(*nvp, ZPOOL_PROP_LEAKED, NULL,
+                           dsl_dir_phys(pool->dp_leak_dir)->dd_used_bytes,
+                           src);
+               } else {
+                       spa_prop_add_list(*nvp, ZPOOL_PROP_LEAKED,
+                           NULL, 0, src);
+               }
        }
 
        spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src);
@@ -264,6 +287,22 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
                spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root,
                    0, ZPROP_SRC_LOCAL);
 
+       if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_BLOCKS)) {
+               spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL,
+                   MIN(zfs_max_recordsize, SPA_MAXBLOCKSIZE), ZPROP_SRC_NONE);
+       } else {
+               spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL,
+                   SPA_OLD_MAXBLOCKSIZE, ZPROP_SRC_NONE);
+       }
+
+       if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_DNODE)) {
+               spa_prop_add_list(*nvp, ZPOOL_PROP_MAXDNODESIZE, NULL,
+                   DNODE_MAX_SIZE, ZPROP_SRC_NONE);
+       } else {
+               spa_prop_add_list(*nvp, ZPOOL_PROP_MAXDNODESIZE, NULL,
+                   DNODE_MIN_SIZE, ZPROP_SRC_NONE);
+       }
+
        if ((dp = list_head(&spa->spa_config_list)) != NULL) {
                if (dp->scd_path == NULL) {
                        spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
@@ -286,7 +325,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
        zap_attribute_t za;
        int err;
 
-       err = nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_PUSHPAGE);
+       err = nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP);
        if (err)
                return (err);
 
@@ -336,9 +375,8 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
                                        break;
                                }
 
-                               strval = kmem_alloc(
-                                   MAXNAMELEN + strlen(MOS_DIR_NAME) + 1,
-                                   KM_PUSHPAGE);
+                               strval = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN,
+                                   KM_SLEEP);
                                dsl_dataset_name(ds, strval);
                                dsl_dataset_rele(ds, FTAG);
                                dsl_pool_config_exit(dp, FTAG);
@@ -350,14 +388,13 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
                        spa_prop_add_list(*nvp, prop, strval, intval, src);
 
                        if (strval != NULL)
-                               kmem_free(strval,
-                                   MAXNAMELEN + strlen(MOS_DIR_NAME) + 1);
+                               kmem_free(strval, ZFS_MAX_DATASET_NAME_LEN);
 
                        break;
 
                case 1:
                        /* string property */
-                       strval = kmem_alloc(za.za_num_integers, KM_PUSHPAGE);
+                       strval = kmem_alloc(za.za_num_integers, KM_SLEEP);
                        err = zap_lookup(mos, spa->spa_pool_props_object,
                            za.za_name, 1, za.za_num_integers, strval);
                        if (err) {
@@ -455,6 +492,16 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
                                error = SET_ERROR(EINVAL);
                        break;
 
+               case ZPOOL_PROP_MULTIHOST:
+                       error = nvpair_value_uint64(elem, &intval);
+                       if (!error && intval > 1)
+                               error = SET_ERROR(EINVAL);
+
+                       if (!error && !spa_get_hostid())
+                               error = SET_ERROR(ENOTSUP);
+
+                       break;
+
                case ZPOOL_PROP_BOOTFS:
                        /*
                         * If the pool version is less than SPA_VERSION_BOOTFS,
@@ -480,7 +527,7 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
 
                        if (!error) {
                                objset_t *os;
-                               uint64_t compress;
+                               uint64_t propval;
 
                                if (strval == NULL || strval[0] == '\0') {
                                        objnum = zpool_prop_default_numeric(
@@ -492,15 +539,26 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
                                if (error)
                                        break;
 
-                               /* Must be ZPL and not gzip compressed. */
+                               /*
+                                * Must be ZPL, and its property settings
+                                * must be supported by GRUB (compression
+                                * is not gzip, and large blocks or large
+                                * dnodes are not used).
+                                */
 
                                if (dmu_objset_type(os) != DMU_OST_ZFS) {
                                        error = SET_ERROR(ENOTSUP);
                                } else if ((error =
                                    dsl_prop_get_int_ds(dmu_objset_ds(os),
                                    zfs_prop_to_name(ZFS_PROP_COMPRESSION),
-                                   &compress)) == 0 &&
-                                   !BOOTFS_COMPRESS_VALID(compress)) {
+                                   &propval)) == 0 &&
+                                   !BOOTFS_COMPRESS_VALID(propval)) {
+                                       error = SET_ERROR(ENOTSUP);
+                               } else if ((error =
+                                   dsl_prop_get_int_ds(dmu_objset_ds(os),
+                                   zfs_prop_to_name(ZFS_PROP_DNODESIZE),
+                                   &propval)) == 0 &&
+                                   propval != ZFS_DNSIZE_LEGACY) {
                                        error = SET_ERROR(ENOTSUP);
                                } else {
                                        objnum = dmu_objset_id(os);
@@ -511,8 +569,7 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
 
                case ZPOOL_PROP_FAILUREMODE:
                        error = nvpair_value_uint64(elem, &intval);
-                       if (!error && (intval < ZIO_FAILURE_MODE_WAIT ||
-                           intval > ZIO_FAILURE_MODE_PANIC))
+                       if (!error && intval > ZIO_FAILURE_MODE_PANIC)
                                error = SET_ERROR(EINVAL);
 
                        /*
@@ -562,7 +619,6 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
                                        error = SET_ERROR(EINVAL);
                                        break;
                                }
-                               check++;
                        }
                        if (strlen(strval) > ZPROP_MAX_COMMENT)
                                error = SET_ERROR(E2BIG);
@@ -610,7 +666,7 @@ spa_configfile_set(spa_t *spa, nvlist_t *nvp, boolean_t need_sync)
                return;
 
        dp = kmem_alloc(sizeof (spa_config_dirent_t),
-           KM_PUSHPAGE);
+           KM_SLEEP);
 
        if (cachefile[0] == '\0')
                dp->scd_path = spa_strdup(spa_config_path);
@@ -664,7 +720,8 @@ spa_prop_set(spa_t *spa, nvlist_t *nvp)
                         * feature descriptions object.
                         */
                        error = dsl_sync_task(spa->spa_name, NULL,
-                           spa_sync_version, &ver, 6);
+                           spa_sync_version, &ver,
+                           6, ZFS_SPACE_CHECK_RESERVED);
                        if (error)
                                return (error);
                        continue;
@@ -676,7 +733,7 @@ spa_prop_set(spa_t *spa, nvlist_t *nvp)
 
        if (need_sync) {
                return (dsl_sync_task(spa->spa_name, NULL, spa_sync_props,
-                   nvp, 6));
+                   nvp, 6, ZFS_SPACE_CHECK_RESERVED));
        }
 
        return (0);
@@ -757,11 +814,11 @@ spa_change_guid(spa_t *spa)
        guid = spa_generate_guid(NULL);
 
        error = dsl_sync_task(spa->spa_name, spa_change_guid_check,
-           spa_change_guid_sync, &guid, 5);
+           spa_change_guid_sync, &guid, 5, ZFS_SPACE_CHECK_RESERVED);
 
        if (error == 0) {
                spa_config_sync(spa, B_FALSE, B_TRUE);
-               spa_event_notify(spa, NULL, FM_EREPORT_ZFS_POOL_REGUID);
+               spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_REGUID);
        }
 
        mutex_exit(&spa_namespace_lock);
@@ -779,19 +836,14 @@ spa_change_guid(spa_t *spa)
 static int
 spa_error_entry_compare(const void *a, const void *b)
 {
-       spa_error_entry_t *sa = (spa_error_entry_t *)a;
-       spa_error_entry_t *sb = (spa_error_entry_t *)b;
+       const spa_error_entry_t *sa = (const spa_error_entry_t *)a;
+       const spa_error_entry_t *sb = (const spa_error_entry_t *)b;
        int ret;
 
-       ret = bcmp(&sa->se_bookmark, &sb->se_bookmark,
-           sizeof (zbookmark_t));
+       ret = memcmp(&sa->se_bookmark, &sb->se_bookmark,
+           sizeof (zbookmark_phys_t));
 
-       if (ret < 0)
-               return (-1);
-       else if (ret > 0)
-               return (1);
-       else
-               return (0);
+       return (AVL_ISIGN(ret));
 }
 
 /*
@@ -841,12 +893,13 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
        case ZTI_MODE_FIXED:
                ASSERT3U(value, >=, 1);
                value = MAX(value, 1);
+               flags |= TASKQ_DYNAMIC;
                break;
 
        case ZTI_MODE_BATCH:
                batch = B_TRUE;
                flags |= TASKQ_THREADS_CPU_PCT;
-               value = zio_taskq_batch_pct;
+               value = MIN(zio_taskq_batch_pct, 100);
                break;
 
        default:
@@ -877,11 +930,13 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
                        pri_t pri = maxclsyspri;
                        /*
                         * The write issue taskq can be extremely CPU
-                        * intensive.  Run it at slightly lower priority
-                        * than the other taskqs.
+                        * intensive.  Run it at slightly less important
+                        * priority than the other taskqs.  Under Linux this
+                        * means incrementing the priority value on platforms
+                        * like illumos it should be decremented.
                         */
                        if (t == ZIO_TYPE_WRITE && q == ZIO_TASKQ_ISSUE)
-                               pri--;
+                               pri++;
 
                        tq = taskq_create_proc(name, value, pri, 50,
                            INT_MAX, spa->spa_proc, flags);
@@ -1094,10 +1149,12 @@ spa_activate(spa_t *spa, int mode)
 
        list_create(&spa->spa_config_dirty_list, sizeof (vdev_t),
            offsetof(vdev_t, vdev_config_dirty_node));
+       list_create(&spa->spa_evicting_os_list, sizeof (objset_t),
+           offsetof(objset_t, os_evicting_node));
        list_create(&spa->spa_state_dirty_list, sizeof (vdev_t),
            offsetof(vdev_t, vdev_state_dirty_node));
 
-       txg_list_create(&spa->spa_vdev_txg_list,
+       txg_list_create(&spa->spa_vdev_txg_list, spa,
            offsetof(struct vdev, vdev_txg_node));
 
        avl_create(&spa->spa_errlist_scrub,
@@ -1106,6 +1163,31 @@ spa_activate(spa_t *spa, int mode)
        avl_create(&spa->spa_errlist_last,
            spa_error_entry_compare, sizeof (spa_error_entry_t),
            offsetof(spa_error_entry_t, se_avl));
+
+       /*
+        * This taskq is used to perform zvol-minor-related tasks
+        * asynchronously. This has several advantages, including easy
+        * resolution of various deadlocks (zfsonlinux bug #3681).
+        *
+        * The taskq must be single threaded to ensure tasks are always
+        * processed in the order in which they were dispatched.
+        *
+        * A taskq per pool allows one to keep the pools independent.
+        * This way if one pool is suspended, it will not impact another.
+        *
+        * The preferred location to dispatch a zvol minor task is a sync
+        * task. In this context, there is easy access to the spa_t and minimal
+        * error handling is required because the sync task must succeed.
+        */
+       spa->spa_zvol_taskq = taskq_create("z_zvol", 1, defclsyspri,
+           1, INT_MAX, 0);
+
+       /*
+        * The taskq to upgrade datasets in this pool. Currently used by
+        * feature SPA_FEATURE_USEROBJ_ACCOUNTING.
+        */
+       spa->spa_upgrade_taskq = taskq_create("z_upgrade", boot_ncpus,
+           defclsyspri, 1, INT_MAX, TASKQ_DYNAMIC);
 }
 
 /*
@@ -1122,12 +1204,25 @@ spa_deactivate(spa_t *spa)
        ASSERT(spa->spa_async_zio_root == NULL);
        ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
 
+       spa_evicting_os_wait(spa);
+
+       if (spa->spa_zvol_taskq) {
+               taskq_destroy(spa->spa_zvol_taskq);
+               spa->spa_zvol_taskq = NULL;
+       }
+
+       if (spa->spa_upgrade_taskq) {
+               taskq_destroy(spa->spa_upgrade_taskq);
+               spa->spa_upgrade_taskq = NULL;
+       }
+
        txg_list_destroy(&spa->spa_vdev_txg_list);
 
        list_destroy(&spa->spa_config_dirty_list);
+       list_destroy(&spa->spa_evicting_os_list);
        list_destroy(&spa->spa_state_dirty_list);
 
-       taskq_cancel_id(system_taskq, spa->spa_deadman_tqid);
+       taskq_cancel_id(system_delay_taskq, spa->spa_deadman_tqid);
 
        for (t = 0; t < ZIO_TYPES; t++) {
                for (q = 0; q < ZIO_TASKQ_TYPES; q++) {
@@ -1232,7 +1327,7 @@ spa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent,
 static void
 spa_unload(spa_t *spa)
 {
-       int i;
+       int i, c;
 
        ASSERT(MUTEX_HELD(&spa_namespace_lock));
 
@@ -1249,11 +1344,29 @@ spa_unload(spa_t *spa)
                spa->spa_sync_on = B_FALSE;
        }
 
+       /*
+        * Even though vdev_free() also calls vdev_metaslab_fini, we need
+        * to call it earlier, before we wait for async i/o to complete.
+        * This ensures that there is no async metaslab prefetching, by
+        * calling taskq_wait(mg_taskq).
+        */
+       if (spa->spa_root_vdev != NULL) {
+               spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
+               for (c = 0; c < spa->spa_root_vdev->vdev_children; c++)
+                       vdev_metaslab_fini(spa->spa_root_vdev->vdev_child[c]);
+               spa_config_exit(spa, SCL_ALL, FTAG);
+       }
+
+       if (spa->spa_mmp.mmp_thread)
+               mmp_thread_stop(spa);
+
        /*
         * Wait for any outstanding async I/O to complete.
         */
        if (spa->spa_async_zio_root != NULL) {
-               (void) zio_wait(spa->spa_async_zio_root);
+               for (i = 0; i < max_ncpus; i++)
+                       (void) zio_wait(spa->spa_async_zio_root[i]);
+               kmem_free(spa->spa_async_zio_root, max_ncpus * sizeof (void *));
                spa->spa_async_zio_root = NULL;
        }
 
@@ -1279,7 +1392,6 @@ spa_unload(spa_t *spa)
 
        ddt_unload(spa);
 
-
        /*
         * Drop and purge level 2 cache
         */
@@ -1379,7 +1491,7 @@ spa_load_spares(spa_t *spa)
         * active configuration, then we also mark this vdev as an active spare.
         */
        spa->spa_spares.sav_vdevs = kmem_zalloc(nspares * sizeof (void *),
-           KM_PUSHPAGE);
+           KM_SLEEP);
        for (i = 0; i < spa->spa_spares.sav_count; i++) {
                VERIFY(spa_config_parse(spa, &vd, spares[i], NULL, 0,
                    VDEV_ALLOC_SPARE) == 0);
@@ -1427,7 +1539,7 @@ spa_load_spares(spa_t *spa)
            DATA_TYPE_NVLIST_ARRAY) == 0);
 
        spares = kmem_alloc(spa->spa_spares.sav_count * sizeof (void *),
-           KM_PUSHPAGE);
+           KM_SLEEP);
        for (i = 0; i < spa->spa_spares.sav_count; i++)
                spares[i] = vdev_config_generate(spa,
                    spa->spa_spares.sav_vdevs[i], B_TRUE, VDEV_CONFIG_SPARE);
@@ -1458,20 +1570,21 @@ spa_load_l2cache(spa_t *spa)
 
        ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
 
-       if (sav->sav_config != NULL) {
-               VERIFY(nvlist_lookup_nvlist_array(sav->sav_config,
-                   ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0);
-               newvdevs = kmem_alloc(nl2cache * sizeof (void *), KM_PUSHPAGE);
-       } else {
-               nl2cache = 0;
-               newvdevs = NULL;
-       }
-
        oldvdevs = sav->sav_vdevs;
        oldnvdevs = sav->sav_count;
        sav->sav_vdevs = NULL;
        sav->sav_count = 0;
 
+       if (sav->sav_config == NULL) {
+               nl2cache = 0;
+               newvdevs = NULL;
+               goto out;
+       }
+
+       VERIFY(nvlist_lookup_nvlist_array(sav->sav_config,
+           ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0);
+       newvdevs = kmem_alloc(nl2cache * sizeof (void *), KM_SLEEP);
+
        /*
         * Process new nvlist of vdevs.
         */
@@ -1522,6 +1635,24 @@ spa_load_l2cache(spa_t *spa)
                }
        }
 
+       sav->sav_vdevs = newvdevs;
+       sav->sav_count = (int)nl2cache;
+
+       /*
+        * Recompute the stashed list of l2cache devices, with status
+        * information this time.
+        */
+       VERIFY(nvlist_remove(sav->sav_config, ZPOOL_CONFIG_L2CACHE,
+           DATA_TYPE_NVLIST_ARRAY) == 0);
+
+       l2cache = kmem_alloc(sav->sav_count * sizeof (void *), KM_SLEEP);
+       for (i = 0; i < sav->sav_count; i++)
+               l2cache[i] = vdev_config_generate(spa,
+                   sav->sav_vdevs[i], B_TRUE, VDEV_CONFIG_L2CACHE);
+       VERIFY(nvlist_add_nvlist_array(sav->sav_config,
+           ZPOOL_CONFIG_L2CACHE, l2cache, sav->sav_count) == 0);
+
+out:
        /*
         * Purge vdevs that were dropped
         */
@@ -1543,26 +1674,6 @@ spa_load_l2cache(spa_t *spa)
        if (oldvdevs)
                kmem_free(oldvdevs, oldnvdevs * sizeof (void *));
 
-       if (sav->sav_config == NULL)
-               goto out;
-
-       sav->sav_vdevs = newvdevs;
-       sav->sav_count = (int)nl2cache;
-
-       /*
-        * Recompute the stashed list of l2cache devices, with status
-        * information this time.
-        */
-       VERIFY(nvlist_remove(sav->sav_config, ZPOOL_CONFIG_L2CACHE,
-           DATA_TYPE_NVLIST_ARRAY) == 0);
-
-       l2cache = kmem_alloc(sav->sav_count * sizeof (void *), KM_PUSHPAGE);
-       for (i = 0; i < sav->sav_count; i++)
-               l2cache[i] = vdev_config_generate(spa,
-                   sav->sav_vdevs[i], B_TRUE, VDEV_CONFIG_L2CACHE);
-       VERIFY(nvlist_add_nvlist_array(sav->sav_config,
-           ZPOOL_CONFIG_L2CACHE, l2cache, sav->sav_count) == 0);
-out:
        for (i = 0; i < sav->sav_count; i++)
                nvlist_free(l2cache[i]);
        if (sav->sav_count)
@@ -1585,12 +1696,12 @@ load_nvlist(spa_t *spa, uint64_t obj, nvlist_t **value)
        nvsize = *(uint64_t *)db->db_data;
        dmu_buf_rele(db, FTAG);
 
-       packed = kmem_alloc(nvsize, KM_PUSHPAGE | KM_NODEBUG);
+       packed = vmem_alloc(nvsize, KM_SLEEP);
        error = dmu_read(spa->spa_meta_objset, obj, 0, nvsize, packed,
            DMU_READ_PREFETCH);
        if (error == 0)
                error = nvlist_unpack(packed, nvsize, value, 0);
-       kmem_free(packed, nvsize);
+       vmem_free(packed, nvsize);
 
        return (error);
 }
@@ -1609,9 +1720,23 @@ spa_check_removed(vdev_t *vd)
 
        if (vd->vdev_ops->vdev_op_leaf && vdev_is_dead(vd) &&
            !vd->vdev_ishole) {
-               zfs_ereport_post(FM_EREPORT_RESOURCE_AUTOREPLACE,
-                   vd->vdev_spa, vd, NULL, 0, 0);
-               spa_event_notify(vd->vdev_spa, vd, FM_EREPORT_ZFS_DEVICE_CHECK);
+               zfs_post_autoreplace(vd->vdev_spa, vd);
+               spa_event_notify(vd->vdev_spa, vd, NULL, ESC_ZFS_VDEV_CHECK);
+       }
+}
+
+static void
+spa_config_valid_zaps(vdev_t *vd, vdev_t *mvd)
+{
+       uint64_t i;
+
+       ASSERT3U(vd->vdev_children, ==, mvd->vdev_children);
+
+       vd->vdev_top_zap = mvd->vdev_top_zap;
+       vd->vdev_leaf_zap = mvd->vdev_leaf_zap;
+
+       for (i = 0; i < vd->vdev_children; i++) {
+               spa_config_valid_zaps(vd->vdev_child[i], mvd->vdev_child[i]);
        }
 }
 
@@ -1641,9 +1766,9 @@ spa_config_valid(spa_t *spa, nvlist_t *config)
                nvlist_t **child, *nv;
                uint64_t idx = 0;
 
-               child = kmem_alloc(rvd->vdev_children * sizeof (nvlist_t **),
-                   KM_PUSHPAGE);
-               VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_PUSHPAGE) == 0);
+               child = kmem_alloc(rvd->vdev_children * sizeof (nvlist_t *),
+                   KM_SLEEP);
+               VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
 
                for (c = 0; c < rvd->vdev_children; c++) {
                        vdev_t *tvd = rvd->vdev_child[c];
@@ -1719,16 +1844,25 @@ spa_config_valid(spa_t *spa, nvlist_t *config)
                        spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
 
                        vdev_reopen(rvd);
-               } else if (mtvd->vdev_islog) {
+               } else {
+                       if (mtvd->vdev_islog) {
+                               /*
+                                * Load the slog device's state from the MOS
+                                * config since it's possible that the label
+                                * does not contain the most up-to-date
+                                * information.
+                                */
+                               vdev_load_log_state(tvd, mtvd);
+                               vdev_reopen(tvd);
+                       }
+
                        /*
-                        * Load the slog device's state from the MOS config
-                        * since it's possible that the label does not
-                        * contain the most up-to-date information.
+                        * Per-vdev ZAP info is stored exclusively in the MOS.
                         */
-                       vdev_load_log_state(tvd, mtvd);
-                       vdev_reopen(tvd);
+                       spa_config_valid_zaps(tvd, mtvd);
                }
        }
+
        vdev_free(mrvd);
        spa_config_exit(spa, SCL_ALL, FTAG);
 
@@ -1745,6 +1879,7 @@ static boolean_t
 spa_check_logs(spa_t *spa)
 {
        boolean_t rv = B_FALSE;
+       dsl_pool_t *dp = spa_get_dsl(spa);
 
        switch (spa->spa_log_state) {
        default:
@@ -1752,8 +1887,8 @@ spa_check_logs(spa_t *spa)
        case SPA_LOG_MISSING:
                /* need to recheck in case slog has been restored */
        case SPA_LOG_UNKNOWN:
-               rv = (dmu_objset_find(spa->spa_name, zil_check_log_chain,
-                   NULL, DS_FIND_CHILDREN) != 0);
+               rv = (dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
+                   zil_check_log_chain, NULL, DS_FIND_CHILDREN) != 0);
                if (rv)
                        spa_set_log_state(spa, SPA_LOG_MISSING);
                break;
@@ -1856,32 +1991,74 @@ spa_load_verify_done(zio_t *zio)
        spa_load_error_t *sle = zio->io_private;
        dmu_object_type_t type = BP_GET_TYPE(bp);
        int error = zio->io_error;
+       spa_t *spa = zio->io_spa;
 
+       abd_free(zio->io_abd);
        if (error) {
                if ((BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type)) &&
                    type != DMU_OT_INTENT_LOG)
-                       atomic_add_64(&sle->sle_meta_count, 1);
+                       atomic_inc_64(&sle->sle_meta_count);
                else
-                       atomic_add_64(&sle->sle_data_count, 1);
+                       atomic_inc_64(&sle->sle_data_count);
        }
-       zio_data_buf_free(zio->io_data, zio->io_size);
+
+       mutex_enter(&spa->spa_scrub_lock);
+       spa->spa_scrub_inflight--;
+       cv_broadcast(&spa->spa_scrub_io_cv);
+       mutex_exit(&spa->spa_scrub_lock);
 }
 
+/*
+ * Maximum number of concurrent scrub i/os to create while verifying
+ * a pool while importing it.
+ */
+int spa_load_verify_maxinflight = 10000;
+int spa_load_verify_metadata = B_TRUE;
+int spa_load_verify_data = B_TRUE;
+
 /*ARGSUSED*/
 static int
 spa_load_verify_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
-    const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
+    const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg)
 {
-       if (!BP_IS_HOLE(bp) && !BP_IS_EMBEDDED(bp)) {
-               zio_t *rio = arg;
-               size_t size = BP_GET_PSIZE(bp);
-               void *data = zio_data_buf_alloc(size);
+       zio_t *rio;
+       size_t size;
+
+       if (bp == NULL || BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp))
+               return (0);
+       /*
+        * Note: normally this routine will not be called if
+        * spa_load_verify_metadata is not set.  However, it may be useful
+        * to manually set the flag after the traversal has begun.
+        */
+       if (!spa_load_verify_metadata)
+               return (0);
+       if (!BP_IS_METADATA(bp) && !spa_load_verify_data)
+               return (0);
+
+       rio = arg;
+       size = BP_GET_PSIZE(bp);
+
+       mutex_enter(&spa->spa_scrub_lock);
+       while (spa->spa_scrub_inflight >= spa_load_verify_maxinflight)
+               cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock);
+       spa->spa_scrub_inflight++;
+       mutex_exit(&spa->spa_scrub_lock);
+
+       zio_nowait(zio_read(rio, spa, bp, abd_alloc_for_io(size, B_FALSE), size,
+           spa_load_verify_done, rio->io_private, ZIO_PRIORITY_SCRUB,
+           ZIO_FLAG_SPECULATIVE | ZIO_FLAG_CANFAIL |
+           ZIO_FLAG_SCRUB | ZIO_FLAG_RAW, zb));
+       return (0);
+}
+
+/* ARGSUSED */
+int
+verify_dataset_name_len(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
+{
+       if (dsl_dataset_namelen(ds) >= ZFS_MAX_DATASET_NAME_LEN)
+               return (SET_ERROR(ENAMETOOLONG));
 
-               zio_nowait(zio_read(rio, spa, bp, data, size,
-                   spa_load_verify_done, rio->io_private, ZIO_PRIORITY_SCRUB,
-                   ZIO_FLAG_SPECULATIVE | ZIO_FLAG_CANFAIL |
-                   ZIO_FLAG_SCRUB | ZIO_FLAG_RAW, zb));
-       }
        return (0);
 }
 
@@ -1892,18 +2069,29 @@ spa_load_verify(spa_t *spa)
        spa_load_error_t sle = { 0 };
        zpool_rewind_policy_t policy;
        boolean_t verify_ok = B_FALSE;
-       int error;
+       int error = 0;
 
        zpool_get_rewind_policy(spa->spa_config, &policy);
 
        if (policy.zrp_request & ZPOOL_NEVER_REWIND)
                return (0);
 
+       dsl_pool_config_enter(spa->spa_dsl_pool, FTAG);
+       error = dmu_objset_find_dp(spa->spa_dsl_pool,
+           spa->spa_dsl_pool->dp_root_dir_obj, verify_dataset_name_len, NULL,
+           DS_FIND_CHILDREN);
+       dsl_pool_config_exit(spa->spa_dsl_pool, FTAG);
+       if (error != 0)
+               return (error);
+
        rio = zio_root(spa, NULL, &sle,
            ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE);
 
-       error = traverse_pool(spa, spa->spa_verify_min_txg,
-           TRAVERSE_PRE | TRAVERSE_PREFETCH, spa_load_verify_cb, rio);
+       if (spa_load_verify_metadata) {
+               error = traverse_pool(spa, spa->spa_verify_min_txg,
+                   TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA,
+                   spa_load_verify_cb, rio);
+       }
 
        (void) zio_wait(rio);
 
@@ -1999,7 +2187,7 @@ spa_try_repair(spa_t *spa, nvlist_t *config)
            &glist, &gcount) != 0)
                return;
 
-       vd = kmem_zalloc(gcount * sizeof (vdev_t *), KM_PUSHPAGE);
+       vd = kmem_zalloc(gcount * sizeof (vdev_t *), KM_SLEEP);
 
        /* attempt to online all the vdevs & validate */
        attempt_reopen = B_TRUE;
@@ -2085,7 +2273,7 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
                if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_SPLIT,
                    &nvl) == 0) {
                        VERIFY(nvlist_dup(nvl, &spa->spa_config_splitting,
-                           KM_PUSHPAGE) == 0);
+                           KM_SLEEP) == 0);
                }
 
                nvlist_free(spa->spa_load_info);
@@ -2096,6 +2284,11 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
                    mosconfig, &ereport);
        }
 
+       /*
+        * Don't count references from objsets that are already closed
+        * and are making their way through the eviction process.
+        */
+       spa_evicting_os_wait(spa);
        spa->spa_minref = refcount_count(&spa->spa_refcount);
        if (error) {
                if (error != EEXIST) {
@@ -2112,6 +2305,233 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
        return (error);
 }
 
+#ifdef ZFS_DEBUG
+/*
+ * Count the number of per-vdev ZAPs associated with all of the vdevs in the
+ * vdev tree rooted in the given vd, and ensure that each ZAP is present in the
+ * spa's per-vdev ZAP list.
+ */
+static uint64_t
+vdev_count_verify_zaps(vdev_t *vd)
+{
+       spa_t *spa = vd->vdev_spa;
+       uint64_t total = 0;
+       uint64_t i;
+
+       if (vd->vdev_top_zap != 0) {
+               total++;
+               ASSERT0(zap_lookup_int(spa->spa_meta_objset,
+                   spa->spa_all_vdev_zaps, vd->vdev_top_zap));
+       }
+       if (vd->vdev_leaf_zap != 0) {
+               total++;
+               ASSERT0(zap_lookup_int(spa->spa_meta_objset,
+                   spa->spa_all_vdev_zaps, vd->vdev_leaf_zap));
+       }
+
+       for (i = 0; i < vd->vdev_children; i++) {
+               total += vdev_count_verify_zaps(vd->vdev_child[i]);
+       }
+
+       return (total);
+}
+#endif
+
+/*
+ * Determine whether the activity check is required.
+ */
+static boolean_t
+spa_activity_check_required(spa_t *spa, uberblock_t *ub, nvlist_t *label,
+    nvlist_t *config)
+{
+       uint64_t state = 0;
+       uint64_t hostid = 0;
+       uint64_t tryconfig_txg = 0;
+       uint64_t tryconfig_timestamp = 0;
+       nvlist_t *nvinfo;
+
+       if (nvlist_exists(config, ZPOOL_CONFIG_LOAD_INFO)) {
+               nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
+               (void) nvlist_lookup_uint64(nvinfo, ZPOOL_CONFIG_MMP_TXG,
+                   &tryconfig_txg);
+               (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_TIMESTAMP,
+                   &tryconfig_timestamp);
+       }
+
+       (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, &state);
+
+       /*
+        * Disable the MMP activity check - This is used by zdb which
+        * is intended to be used on potentially active pools.
+        */
+       if (spa->spa_import_flags & ZFS_IMPORT_SKIP_MMP)
+               return (B_FALSE);
+
+       /*
+        * Skip the activity check when the MMP feature is disabled.
+        */
+       if (ub->ub_mmp_magic == MMP_MAGIC && ub->ub_mmp_delay == 0)
+               return (B_FALSE);
+       /*
+        * If the tryconfig_* values are nonzero, they are the results of an
+        * earlier tryimport.  If they match the uberblock we just found, then
+        * the pool has not changed and we return false so we do not test a
+        * second time.
+        */
+       if (tryconfig_txg && tryconfig_txg == ub->ub_txg &&
+           tryconfig_timestamp && tryconfig_timestamp == ub->ub_timestamp)
+               return (B_FALSE);
+
+       /*
+        * Allow the activity check to be skipped when importing the pool
+        * on the same host which last imported it.  Since the hostid from
+        * configuration may be stale use the one read from the label.
+        */
+       if (nvlist_exists(label, ZPOOL_CONFIG_HOSTID))
+               hostid = fnvlist_lookup_uint64(label, ZPOOL_CONFIG_HOSTID);
+
+       if (hostid == spa_get_hostid())
+               return (B_FALSE);
+
+       /*
+        * Skip the activity test when the pool was cleanly exported.
+        */
+       if (state != POOL_STATE_ACTIVE)
+               return (B_FALSE);
+
+       return (B_TRUE);
+}
+
+/*
+ * Perform the import activity check.  If the user canceled the import or
+ * we detected activity then fail.
+ */
+static int
+spa_activity_check(spa_t *spa, uberblock_t *ub, nvlist_t *config)
+{
+       uint64_t import_intervals = MAX(zfs_multihost_import_intervals, 1);
+       uint64_t txg = ub->ub_txg;
+       uint64_t timestamp = ub->ub_timestamp;
+       uint64_t import_delay = NANOSEC;
+       hrtime_t import_expire;
+       nvlist_t *mmp_label = NULL;
+       vdev_t *rvd = spa->spa_root_vdev;
+       kcondvar_t cv;
+       kmutex_t mtx;
+       int error = 0;
+
+       cv_init(&cv, NULL, CV_DEFAULT, NULL);
+       mutex_init(&mtx, NULL, MUTEX_DEFAULT, NULL);
+       mutex_enter(&mtx);
+
+       /*
+        * If ZPOOL_CONFIG_MMP_TXG is present an activity check was performed
+        * during the earlier tryimport.  If the txg recorded there is 0 then
+        * the pool is known to be active on another host.
+        *
+        * Otherwise, the pool might be in use on another node.  Check for
+        * changes in the uberblocks on disk if necessary.
+        */
+       if (nvlist_exists(config, ZPOOL_CONFIG_LOAD_INFO)) {
+               nvlist_t *nvinfo = fnvlist_lookup_nvlist(config,
+                   ZPOOL_CONFIG_LOAD_INFO);
+
+               if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_TXG) &&
+                   fnvlist_lookup_uint64(nvinfo, ZPOOL_CONFIG_MMP_TXG) == 0) {
+                       vdev_uberblock_load(rvd, ub, &mmp_label);
+                       error = SET_ERROR(EREMOTEIO);
+                       goto out;
+               }
+       }
+
+       /*
+        * Preferentially use the zfs_multihost_interval from the node which
+        * last imported the pool.  This value is stored in an MMP uberblock as.
+        *
+        * ub_mmp_delay * vdev_count_leaves() == zfs_multihost_interval
+        */
+       if (ub->ub_mmp_magic == MMP_MAGIC && ub->ub_mmp_delay)
+               import_delay = MAX(import_delay, import_intervals *
+                   ub->ub_mmp_delay * MAX(vdev_count_leaves(spa), 1));
+
+       /* Apply a floor using the local default values. */
+       import_delay = MAX(import_delay, import_intervals *
+           MSEC2NSEC(MAX(zfs_multihost_interval, MMP_MIN_INTERVAL)));
+
+       /* Add a small random factor in case of simultaneous imports (0-25%) */
+       import_expire = gethrtime() + import_delay +
+           (import_delay * spa_get_random(250) / 1000);
+
+       while (gethrtime() < import_expire) {
+               vdev_uberblock_load(rvd, ub, &mmp_label);
+
+               if (txg != ub->ub_txg || timestamp != ub->ub_timestamp) {
+                       error = SET_ERROR(EREMOTEIO);
+                       break;
+               }
+
+               if (mmp_label) {
+                       nvlist_free(mmp_label);
+                       mmp_label = NULL;
+               }
+
+               error = cv_timedwait_sig(&cv, &mtx, ddi_get_lbolt() + hz);
+               if (error != -1) {
+                       error = SET_ERROR(EINTR);
+                       break;
+               }
+               error = 0;
+       }
+
+out:
+       mutex_exit(&mtx);
+       mutex_destroy(&mtx);
+       cv_destroy(&cv);
+
+       /*
+        * If the pool is determined to be active store the status in the
+        * spa->spa_load_info nvlist.  If the remote hostname or hostid are
+        * available from configuration read from disk store them as well.
+        * This allows 'zpool import' to generate a more useful message.
+        *
+        * ZPOOL_CONFIG_MMP_STATE    - observed pool status (mandatory)
+        * ZPOOL_CONFIG_MMP_HOSTNAME - hostname from the active pool
+        * ZPOOL_CONFIG_MMP_HOSTID   - hostid from the active pool
+        */
+       if (error == EREMOTEIO) {
+               char *hostname = "<unknown>";
+               uint64_t hostid = 0;
+
+               if (mmp_label) {
+                       if (nvlist_exists(mmp_label, ZPOOL_CONFIG_HOSTNAME)) {
+                               hostname = fnvlist_lookup_string(mmp_label,
+                                   ZPOOL_CONFIG_HOSTNAME);
+                               fnvlist_add_string(spa->spa_load_info,
+                                   ZPOOL_CONFIG_MMP_HOSTNAME, hostname);
+                       }
+
+                       if (nvlist_exists(mmp_label, ZPOOL_CONFIG_HOSTID)) {
+                               hostid = fnvlist_lookup_uint64(mmp_label,
+                                   ZPOOL_CONFIG_HOSTID);
+                               fnvlist_add_uint64(spa->spa_load_info,
+                                   ZPOOL_CONFIG_MMP_HOSTID, hostid);
+                       }
+               }
+
+               fnvlist_add_uint64(spa->spa_load_info,
+                   ZPOOL_CONFIG_MMP_STATE, MMP_STATE_ACTIVE);
+               fnvlist_add_uint64(spa->spa_load_info,
+                   ZPOOL_CONFIG_MMP_TXG, 0);
+
+               error = spa_vdev_err(rvd, VDEV_AUX_ACTIVE, EREMOTEIO);
+       }
+
+       if (mmp_label)
+               nvlist_free(mmp_label);
+
+       return (error);
+}
+
 /*
  * Load an existing storage pool, using the pool's builtin spa_config as a
  * source of configuration information.
@@ -2129,9 +2549,11 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
        uberblock_t *ub = &spa->spa_uberblock;
        uint64_t children, config_cache_txg = spa->spa_config_txg;
        int orig_mode = spa->spa_mode;
-       int parse;
+       int parse, i;
        uint64_t obj;
        boolean_t missing_feat_write = B_FALSE;
+       boolean_t activity_check = B_FALSE;
+       nvlist_t *mos_config;
 
        /*
         * If this is an untrusted config, access the pool in read-only mode.
@@ -2153,8 +2575,13 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
        /*
         * Create "The Godfather" zio to hold all async IOs
         */
-       spa->spa_async_zio_root = zio_root(spa, NULL, NULL,
-           ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | ZIO_FLAG_GODFATHER);
+       spa->spa_async_zio_root = kmem_alloc(max_ncpus * sizeof (void *),
+           KM_SLEEP);
+       for (i = 0; i < max_ncpus; i++) {
+               spa->spa_async_zio_root[i] = zio_root(spa, NULL, NULL,
+                   ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
+                   ZIO_FLAG_GODFATHER);
+       }
 
        /*
         * Parse the configuration into a vdev tree.  We explicitly set the
@@ -2169,6 +2596,8 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                return (error);
 
        ASSERT(spa->spa_root_vdev == rvd);
+       ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
+       ASSERT3U(spa->spa_max_ashift, <=, SPA_MAXBLOCKSHIFT);
 
        if (type != SPA_IMPORT_ASSEMBLE) {
                ASSERT(spa_guid(spa) == pool_guid);
@@ -2221,6 +2650,33 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, ENXIO));
        }
 
+       /*
+        * For pools which have the multihost property on determine if the
+        * pool is truly inactive and can be safely imported.  Prevent
+        * hosts which don't have a hostid set from importing the pool.
+        */
+       activity_check = spa_activity_check_required(spa, ub, label, config);
+       if (activity_check) {
+               if (ub->ub_mmp_magic == MMP_MAGIC && ub->ub_mmp_delay &&
+                   spa_get_hostid() == 0) {
+                       nvlist_free(label);
+                       fnvlist_add_uint64(spa->spa_load_info,
+                           ZPOOL_CONFIG_MMP_STATE, MMP_STATE_NO_HOSTID);
+                       return (spa_vdev_err(rvd, VDEV_AUX_ACTIVE, EREMOTEIO));
+               }
+
+               error = spa_activity_check(spa, ub, config);
+               if (error) {
+                       nvlist_free(label);
+                       return (error);
+               }
+
+               fnvlist_add_uint64(spa->spa_load_info,
+                   ZPOOL_CONFIG_MMP_STATE, MMP_STATE_INACTIVE);
+               fnvlist_add_uint64(spa->spa_load_info,
+                   ZPOOL_CONFIG_MMP_TXG, ub->ub_txg);
+       }
+
        /*
         * If the pool has an unsupported version we can't open it.
         */
@@ -2448,24 +2904,9 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                        VERIFY(nvlist_lookup_string(nvconfig,
                            ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
 
-#ifdef _KERNEL
-                       myhostid = zone_get_hostid(NULL);
-#else  /* _KERNEL */
-                       /*
-                        * We're emulating the system's hostid in userland, so
-                        * we can't use zone_get_hostid().
-                        */
-                       (void) ddi_strtoul(hw_serial, NULL, 10, &myhostid);
-#endif /* _KERNEL */
-                       if (hostid != 0 && myhostid != 0 &&
-                           hostid != myhostid) {
+                       myhostid = spa_get_hostid();
+                       if (hostid && myhostid && hostid != myhostid) {
                                nvlist_free(nvconfig);
-                               cmn_err(CE_WARN, "pool '%s' could not be "
-                                   "loaded as it was last accessed by another "
-                                   "system (host: %s hostid: 0x%lx). See: "
-                                   "http://zfsonlinux.org/msg/ZFS-8000-EY",
-                                   spa_name(spa), hostname,
-                                   (unsigned long)hostid);
                                return (SET_ERROR(EBADF));
                        }
                }
@@ -2482,6 +2923,19 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                return (spa_load(spa, state, SPA_IMPORT_EXISTING, B_TRUE));
        }
 
+       /* Grab the checksum salt from the MOS. */
+       error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+           DMU_POOL_CHECKSUM_SALT, 1,
+           sizeof (spa->spa_cksum_salt.zcs_bytes),
+           spa->spa_cksum_salt.zcs_bytes);
+       if (error == ENOENT) {
+               /* Generate a new salt for subsequent use */
+               (void) random_get_pseudo_bytes(spa->spa_cksum_salt.zcs_bytes,
+                   sizeof (spa->spa_cksum_salt.zcs_bytes));
+       } else if (error != 0) {
+               return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+       }
+
        if (spa_dir_prop(spa, DMU_POOL_SYNC_BPOBJ, &obj) != 0)
                return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
        error = bpobj_open(&spa->spa_deferred_bpobj, spa->spa_meta_objset, obj);
@@ -2523,6 +2977,42 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
        if (error != 0 && error != ENOENT)
                return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
 
+       /*
+        * Load the per-vdev ZAP map. If we have an older pool, this will not
+        * be present; in this case, defer its creation to a later time to
+        * avoid dirtying the MOS this early / out of sync context. See
+        * spa_sync_config_object.
+        */
+
+       /* The sentinel is only available in the MOS config. */
+       if (load_nvlist(spa, spa->spa_config_object, &mos_config) != 0)
+               return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+
+       error = spa_dir_prop(spa, DMU_POOL_VDEV_ZAP_MAP,
+           &spa->spa_all_vdev_zaps);
+
+       if (error == ENOENT) {
+               VERIFY(!nvlist_exists(mos_config,
+                   ZPOOL_CONFIG_HAS_PER_VDEV_ZAPS));
+               spa->spa_avz_action = AVZ_ACTION_INITIALIZE;
+               ASSERT0(vdev_count_verify_zaps(spa->spa_root_vdev));
+       } else if (error != 0) {
+               return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+       } else if (!nvlist_exists(mos_config, ZPOOL_CONFIG_HAS_PER_VDEV_ZAPS)) {
+               /*
+                * An older version of ZFS overwrote the sentinel value, so
+                * we have orphaned per-vdev ZAPs in the MOS. Defer their
+                * destruction to later; see spa_sync_config_object.
+                */
+               spa->spa_avz_action = AVZ_ACTION_DESTROY;
+               /*
+                * We're assuming that no vdevs have had their ZAPs created
+                * before this. Better be sure of it.
+                */
+               ASSERT0(vdev_count_verify_zaps(spa->spa_root_vdev));
+       }
+       nvlist_free(mos_config);
+
        /*
         * If we're assembling the pool from the split-off vdevs of
         * an existing pool, we don't want to attach the spares & cache
@@ -2582,12 +3072,25 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                spa_prop_find(spa, ZPOOL_PROP_DELEGATION, &spa->spa_delegation);
                spa_prop_find(spa, ZPOOL_PROP_FAILUREMODE, &spa->spa_failmode);
                spa_prop_find(spa, ZPOOL_PROP_AUTOEXPAND, &spa->spa_autoexpand);
+               spa_prop_find(spa, ZPOOL_PROP_MULTIHOST, &spa->spa_multihost);
                spa_prop_find(spa, ZPOOL_PROP_DEDUPDITTO,
                    &spa->spa_dedup_ditto);
 
                spa->spa_autoreplace = (autoreplace != 0);
        }
 
+       /*
+        * If the 'multihost' property is set, then never allow a pool to
+        * be imported when the system hostid is zero.  The exception to
+        * this rule is zdb which is always allowed to access pools.
+        */
+       if (spa_multihost(spa) && spa_get_hostid() == 0 &&
+           (spa->spa_import_flags & ZFS_IMPORT_SKIP_MMP) == 0) {
+               fnvlist_add_uint64(spa->spa_load_info,
+                   ZPOOL_CONFIG_MMP_STATE, MMP_STATE_NO_HOSTID);
+               return (spa_vdev_err(rvd, VDEV_AUX_ACTIVE, EREMOTEIO));
+       }
+
        /*
         * If the 'autoreplace' property is set, then post a resource notifying
         * the ZFS DE that it should not issue any faults for unopenable
@@ -2657,7 +3160,7 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN)
                        return (SET_ERROR(ENXIO));
 
-               if (spa_check_logs(spa)) {
+               if (spa_writeable(spa) && spa_check_logs(spa)) {
                        *ereport = FM_EREPORT_ZFS_LOG_REPLAY;
                        return (spa_vdev_err(rvd, VDEV_AUX_BAD_LOG, ENXIO));
                }
@@ -2688,6 +3191,7 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
            spa->spa_load_max_txg == UINT64_MAX)) {
                dmu_tx_t *tx;
                int need_update = B_FALSE;
+               dsl_pool_t *dp = spa_get_dsl(spa);
                int c;
 
                ASSERT(state != SPA_LOAD_TRYIMPORT);
@@ -2701,9 +3205,8 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                 */
                spa->spa_claiming = B_TRUE;
 
-               tx = dmu_tx_create_assigned(spa_get_dsl(spa),
-                   spa_first_txg(spa));
-               (void) dmu_objset_find(spa_name(spa),
+               tx = dmu_tx_create_assigned(dp, spa_first_txg(spa));
+               (void) dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
                    zil_claim, tx, DS_FIND_CHILDREN);
                dmu_tx_commit(tx);
 
@@ -2712,6 +3215,7 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                spa_set_log_state(spa, SPA_LOG_GOOD);
                spa->spa_sync_on = B_TRUE;
                txg_sync_start(spa->spa_dsl_pool);
+               mmp_thread_start(spa);
 
                /*
                 * Wait for all claims to sync.  We sync up to the highest
@@ -2757,7 +3261,7 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                 * Log the fact that we booted up (so that we can detect if
                 * we rebooted in the middle of an operation).
                 */
-               spa_history_log_version(spa, "open");
+               spa_history_log_version(spa, "open", NULL);
 
                /*
                 * Delete any inconsistent datasets.
@@ -2782,7 +3286,7 @@ spa_load_retry(spa_t *spa, spa_load_state_t state, int mosconfig)
        spa_unload(spa);
        spa_deactivate(spa);
 
-       spa->spa_load_max_txg--;
+       spa->spa_load_max_txg = spa->spa_uberblock.ub_txg - 1;
 
        spa_activate(spa, mode);
        spa_async_suspend(spa);
@@ -2812,6 +3316,8 @@ spa_load_best(spa_t *spa, spa_load_state_t state, int mosconfig,
                spa_set_log_state(spa, SPA_LOG_CLEAR);
        } else {
                spa->spa_load_max_txg = max_request;
+               if (max_request != UINT64_MAX)
+                       spa->spa_extreme_rewind = B_TRUE;
        }
 
        load_error = rewind_error = spa_load(spa, state, SPA_IMPORT_EXISTING,
@@ -2864,6 +3370,8 @@ spa_load_best(spa_t *spa, spa_load_state_t state, int mosconfig,
 
        if (config && (rewind_error || state != SPA_LOAD_RECOVER))
                spa_config_set(spa, config);
+       else
+               nvlist_free(config);
 
        if (state == SPA_LOAD_RECOVER) {
                ASSERT3P(loadinfo, ==, NULL);
@@ -2965,7 +3473,7 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t *nvpolicy,
                         */
                        if (config != NULL && spa->spa_config) {
                                VERIFY(nvlist_dup(spa->spa_config, config,
-                                   KM_PUSHPAGE) == 0);
+                                   KM_SLEEP) == 0);
                                VERIFY(nvlist_add_nvlist(*config,
                                    ZPOOL_CONFIG_LOAD_INFO,
                                    spa->spa_load_info) == 0);
@@ -3001,10 +3509,8 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t *nvpolicy,
                mutex_exit(&spa_namespace_lock);
        }
 
-#ifdef _KERNEL
        if (firstopen)
-               zvol_create_minors(spa->spa_name);
-#endif
+               zvol_create_minors(spa, spa_name(spa), B_TRUE);
 
        *spapp = spa;
 
@@ -3152,20 +3658,18 @@ spa_add_l2cache(spa_t *spa, nvlist_t *config)
                            ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc)
                            == 0);
                        vdev_get_stats(vd, vs);
+                       vdev_config_generate_stats(vd, l2cache[i]);
+
                }
        }
 }
 
 static void
-spa_add_feature_stats(spa_t *spa, nvlist_t *config)
+spa_feature_stats_from_disk(spa_t *spa, nvlist_t *features)
 {
-       nvlist_t *features;
        zap_cursor_t zc;
        zap_attribute_t za;
 
-       ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER));
-       VERIFY(nvlist_alloc(&features, NV_UNIQUE_NAME, KM_SLEEP) == 0);
-
        if (spa->spa_feat_for_read_obj != 0) {
                for (zap_cursor_init(&zc, spa->spa_meta_objset,
                    spa->spa_feat_for_read_obj);
@@ -3173,7 +3677,7 @@ spa_add_feature_stats(spa_t *spa, nvlist_t *config)
                    zap_cursor_advance(&zc)) {
                        ASSERT(za.za_integer_length == sizeof (uint64_t) &&
                            za.za_num_integers == 1);
-                       VERIFY3U(0, ==, nvlist_add_uint64(features, za.za_name,
+                       VERIFY0(nvlist_add_uint64(features, za.za_name,
                            za.za_first_integer));
                }
                zap_cursor_fini(&zc);
@@ -3186,15 +3690,62 @@ spa_add_feature_stats(spa_t *spa, nvlist_t *config)
                    zap_cursor_advance(&zc)) {
                        ASSERT(za.za_integer_length == sizeof (uint64_t) &&
                            za.za_num_integers == 1);
-                       VERIFY3U(0, ==, nvlist_add_uint64(features, za.za_name,
+                       VERIFY0(nvlist_add_uint64(features, za.za_name,
                            za.za_first_integer));
                }
                zap_cursor_fini(&zc);
        }
+}
+
+static void
+spa_feature_stats_from_cache(spa_t *spa, nvlist_t *features)
+{
+       int i;
+
+       for (i = 0; i < SPA_FEATURES; i++) {
+               zfeature_info_t feature = spa_feature_table[i];
+               uint64_t refcount;
 
-       VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS,
-           features) == 0);
-       nvlist_free(features);
+               if (feature_get_refcount(spa, &feature, &refcount) != 0)
+                       continue;
+
+               VERIFY0(nvlist_add_uint64(features, feature.fi_guid, refcount));
+       }
+}
+
+/*
+ * Store a list of pool features and their reference counts in the
+ * config.
+ *
+ * The first time this is called on a spa, allocate a new nvlist, fetch
+ * the pool features and reference counts from disk, then save the list
+ * in the spa. In subsequent calls on the same spa use the saved nvlist
+ * and refresh its values from the cached reference counts.  This
+ * ensures we don't block here on I/O on a suspended pool so 'zpool
+ * clear' can resume the pool.
+ */
+static void
+spa_add_feature_stats(spa_t *spa, nvlist_t *config)
+{
+       nvlist_t *features;
+
+       ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER));
+
+       mutex_enter(&spa->spa_feat_stats_lock);
+       features = spa->spa_feat_stats;
+
+       if (features != NULL) {
+               spa_feature_stats_from_cache(spa, features);
+       } else {
+               VERIFY0(nvlist_alloc(&features, NV_UNIQUE_NAME, KM_SLEEP));
+               spa->spa_feat_stats = features;
+               spa_feature_stats_from_disk(spa, features);
+       }
+
+       VERIFY0(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS,
+           features));
+
+       mutex_exit(&spa->spa_feat_stats_lock);
 }
 
 int
@@ -3227,10 +3778,14 @@ spa_get_stats(const char *name, nvlist_t **config,
                            ZPOOL_CONFIG_ERRCOUNT,
                            spa_get_errlog_size(spa)) == 0);
 
-                       if (spa_suspended(spa))
+                       if (spa_suspended(spa)) {
                                VERIFY(nvlist_add_uint64(*config,
                                    ZPOOL_CONFIG_SUSPENDED,
                                    spa->spa_failmode) == 0);
+                               VERIFY(nvlist_add_uint64(*config,
+                                   ZPOOL_CONFIG_SUSPENDED_REASON,
+                                   spa->spa_suspended) == 0);
+                       }
 
                        spa_add_spares(spa, *config);
                        spa_add_l2cache(spa, *config);
@@ -3317,18 +3872,6 @@ spa_validate_aux_devs(spa_t *spa, nvlist_t *nvroot, uint64_t crtxg, int mode,
                        goto out;
                }
 
-               /*
-                * The L2ARC currently only supports disk devices in
-                * kernel context.  For user-level testing, we allow it.
-                */
-#ifdef _KERNEL
-               if ((strcmp(config, ZPOOL_CONFIG_L2CACHE) == 0) &&
-                   strcmp(vd->vdev_ops->vdev_op_type, VDEV_TYPE_DISK) != 0) {
-                       error = SET_ERROR(ENOTBLK);
-                       vdev_free(vd);
-                       goto out;
-               }
-#endif
                vd->vdev_top = vd;
 
                if ((error = vdev_open(vd)) == 0 &&
@@ -3382,20 +3925,20 @@ spa_set_aux_vdevs(spa_aux_vdev_t *sav, nvlist_t **devs, int ndevs,
                nvlist_t **newdevs;
 
                /*
-                * Generate new dev list by concatentating with the
+                * Generate new dev list by concatenating with the
                 * current dev list.
                 */
                VERIFY(nvlist_lookup_nvlist_array(sav->sav_config, config,
                    &olddevs, &oldndevs) == 0);
 
                newdevs = kmem_alloc(sizeof (void *) *
-                   (ndevs + oldndevs), KM_PUSHPAGE);
+                   (ndevs + oldndevs), KM_SLEEP);
                for (i = 0; i < oldndevs; i++)
                        VERIFY(nvlist_dup(olddevs[i], &newdevs[i],
-                           KM_PUSHPAGE) == 0);
+                           KM_SLEEP) == 0);
                for (i = 0; i < ndevs; i++)
                        VERIFY(nvlist_dup(devs[i], &newdevs[i + oldndevs],
-                           KM_PUSHPAGE) == 0);
+                           KM_SLEEP) == 0);
 
                VERIFY(nvlist_remove(sav->sav_config, config,
                    DATA_TYPE_NVLIST_ARRAY) == 0);
@@ -3410,7 +3953,7 @@ spa_set_aux_vdevs(spa_aux_vdev_t *sav, nvlist_t **devs, int ndevs,
                 * Generate a new dev list.
                 */
                VERIFY(nvlist_alloc(&sav->sav_config, NV_UNIQUE_NAME,
-                   KM_PUSHPAGE) == 0);
+                   KM_SLEEP) == 0);
                VERIFY(nvlist_add_nvlist_array(sav->sav_config, config,
                    devs, ndevs) == 0);
        }
@@ -3457,13 +4000,18 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
        uint64_t version, obj;
        boolean_t has_features;
        nvpair_t *elem;
-       int c;
+       int c, i;
+       char *poolname;
+       nvlist_t *nvl;
+
+       if (nvlist_lookup_string(props, "tname", &poolname) != 0)
+               poolname = (char *)pool;
 
        /*
         * If this pool already exists, return failure.
         */
        mutex_enter(&spa_namespace_lock);
-       if (spa_lookup(pool) != NULL) {
+       if (spa_lookup(poolname) != NULL) {
                mutex_exit(&spa_namespace_lock);
                return (SET_ERROR(EEXIST));
        }
@@ -3471,9 +4019,12 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
        /*
         * Allocate a new spa_t structure.
         */
+       nvl = fnvlist_alloc();
+       fnvlist_add_string(nvl, ZPOOL_CONFIG_POOL_NAME, pool);
        (void) nvlist_lookup_string(props,
            zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
-       spa = spa_add(pool, NULL, altroot);
+       spa = spa_add(poolname, nvl, altroot);
+       fnvlist_free(nvl);
        spa_activate(spa, spa_mode_global);
 
        if (props && (error = spa_prop_validate(spa, props))) {
@@ -3483,6 +4034,12 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
                return (error);
        }
 
+       /*
+        * Temporary pool names should never be written to disk.
+        */
+       if (poolname != pool)
+               spa->spa_import_flags |= ZFS_IMPORT_TEMP_NAME;
+
        has_features = B_FALSE;
        for (elem = nvlist_next_nvpair(props, NULL);
            elem != NULL; elem = nvlist_next_nvpair(props, elem)) {
@@ -3500,12 +4057,18 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
        spa->spa_uberblock.ub_txg = txg - 1;
        spa->spa_uberblock.ub_version = version;
        spa->spa_ubsync = spa->spa_uberblock;
+       spa->spa_load_state = SPA_LOAD_CREATE;
 
        /*
         * Create "The Godfather" zio to hold all async IOs
         */
-       spa->spa_async_zio_root = zio_root(spa, NULL, NULL,
-           ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE | ZIO_FLAG_GODFATHER);
+       spa->spa_async_zio_root = kmem_alloc(max_ncpus * sizeof (void *),
+           KM_SLEEP);
+       for (i = 0; i < max_ncpus; i++) {
+               spa->spa_async_zio_root[i] = zio_root(spa, NULL, NULL,
+                   ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
+                   ZIO_FLAG_GODFATHER);
+       }
 
        /*
         * Create the root vdev.
@@ -3546,7 +4109,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
        if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
            &spares, &nspares) == 0) {
                VERIFY(nvlist_alloc(&spa->spa_spares.sav_config, NV_UNIQUE_NAME,
-                   KM_PUSHPAGE) == 0);
+                   KM_SLEEP) == 0);
                VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config,
                    ZPOOL_CONFIG_SPARES, spares, nspares) == 0);
                spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
@@ -3561,7 +4124,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
        if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
            &l2cache, &nl2cache) == 0) {
                VERIFY(nvlist_alloc(&spa->spa_l2cache.sav_config,
-                   NV_UNIQUE_NAME, KM_PUSHPAGE) == 0);
+                   NV_UNIQUE_NAME, KM_SLEEP) == 0);
                VERIFY(nvlist_add_nvlist_array(spa->spa_l2cache.sav_config,
                    ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0);
                spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
@@ -3585,299 +4148,109 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
        tx = dmu_tx_create_assigned(dp, txg);
 
        /*
-        * Create the pool config object.
-        */
-       spa->spa_config_object = dmu_object_alloc(spa->spa_meta_objset,
-           DMU_OT_PACKED_NVLIST, SPA_CONFIG_BLOCKSIZE,
-           DMU_OT_PACKED_NVLIST_SIZE, sizeof (uint64_t), tx);
-
-       if (zap_add(spa->spa_meta_objset,
-           DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CONFIG,
-           sizeof (uint64_t), 1, &spa->spa_config_object, tx) != 0) {
-               cmn_err(CE_PANIC, "failed to add pool config");
-       }
-
-       if (spa_version(spa) >= SPA_VERSION_FEATURES)
-               spa_feature_create_zap_objects(spa, tx);
-
-       if (zap_add(spa->spa_meta_objset,
-           DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CREATION_VERSION,
-           sizeof (uint64_t), 1, &version, tx) != 0) {
-               cmn_err(CE_PANIC, "failed to add pool version");
-       }
-
-       /* Newly created pools with the right version are always deflated. */
-       if (version >= SPA_VERSION_RAIDZ_DEFLATE) {
-               spa->spa_deflate = TRUE;
-               if (zap_add(spa->spa_meta_objset,
-                   DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE,
-                   sizeof (uint64_t), 1, &spa->spa_deflate, tx) != 0) {
-                       cmn_err(CE_PANIC, "failed to add deflate");
-               }
-       }
-
-       /*
-        * Create the deferred-free bpobj.  Turn off compression
-        * because sync-to-convergence takes longer if the blocksize
-        * keeps changing.
-        */
-       obj = bpobj_alloc(spa->spa_meta_objset, 1 << 14, tx);
-       dmu_object_set_compress(spa->spa_meta_objset, obj,
-           ZIO_COMPRESS_OFF, tx);
-       if (zap_add(spa->spa_meta_objset,
-           DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SYNC_BPOBJ,
-           sizeof (uint64_t), 1, &obj, tx) != 0) {
-               cmn_err(CE_PANIC, "failed to add bpobj");
-       }
-       VERIFY3U(0, ==, bpobj_open(&spa->spa_deferred_bpobj,
-           spa->spa_meta_objset, obj));
-
-       /*
-        * Create the pool's history object.
-        */
-       if (version >= SPA_VERSION_ZPOOL_HISTORY)
-               spa_history_create_obj(spa, tx);
-
-       /*
-        * Set pool properties.
-        */
-       spa->spa_bootfs = zpool_prop_default_numeric(ZPOOL_PROP_BOOTFS);
-       spa->spa_delegation = zpool_prop_default_numeric(ZPOOL_PROP_DELEGATION);
-       spa->spa_failmode = zpool_prop_default_numeric(ZPOOL_PROP_FAILUREMODE);
-       spa->spa_autoexpand = zpool_prop_default_numeric(ZPOOL_PROP_AUTOEXPAND);
-
-       if (props != NULL) {
-               spa_configfile_set(spa, props, B_FALSE);
-               spa_sync_props(props, tx);
-       }
-
-       dmu_tx_commit(tx);
-
-       spa->spa_sync_on = B_TRUE;
-       txg_sync_start(spa->spa_dsl_pool);
-
-       /*
-        * We explicitly wait for the first transaction to complete so that our
-        * bean counters are appropriately updated.
-        */
-       txg_wait_synced(spa->spa_dsl_pool, txg);
-
-       spa_config_sync(spa, B_FALSE, B_TRUE);
-
-       spa_history_log_version(spa, "create");
-
-       spa->spa_minref = refcount_count(&spa->spa_refcount);
-
-       mutex_exit(&spa_namespace_lock);
-
-       return (0);
-}
-
-#ifdef _KERNEL
-/*
- * Get the root pool information from the root disk, then import the root pool
- * during the system boot up time.
- */
-extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **);
-
-static nvlist_t *
-spa_generate_rootconf(char *devpath, char *devid, uint64_t *guid)
-{
-       nvlist_t *config;
-       nvlist_t *nvtop, *nvroot;
-       uint64_t pgid;
-
-       if (vdev_disk_read_rootlabel(devpath, devid, &config) != 0)
-               return (NULL);
-
-       /*
-        * Add this top-level vdev to the child array.
-        */
-       VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
-           &nvtop) == 0);
-       VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
-           &pgid) == 0);
-       VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, guid) == 0);
-
-       /*
-        * Put this pool's top-level vdevs into a root vdev.
-        */
-       VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_PUSHPAGE) == 0);
-       VERIFY(nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE,
-           VDEV_TYPE_ROOT) == 0);
-       VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL) == 0);
-       VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, pgid) == 0);
-       VERIFY(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
-           &nvtop, 1) == 0);
-
-       /*
-        * Replace the existing vdev_tree with the new root vdev in
-        * this pool's configuration (remove the old, add the new).
-        */
-       VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0);
-       nvlist_free(nvroot);
-       return (config);
-}
-
-/*
- * Walk the vdev tree and see if we can find a device with "better"
- * configuration. A configuration is "better" if the label on that
- * device has a more recent txg.
- */
-static void
-spa_alt_rootvdev(vdev_t *vd, vdev_t **avd, uint64_t *txg)
-{
-       int c;
-
-       for (c = 0; c < vd->vdev_children; c++)
-               spa_alt_rootvdev(vd->vdev_child[c], avd, txg);
-
-       if (vd->vdev_ops->vdev_op_leaf) {
-               nvlist_t *label;
-               uint64_t label_txg;
-
-               if (vdev_disk_read_rootlabel(vd->vdev_physpath, vd->vdev_devid,
-                   &label) != 0)
-                       return;
-
-               VERIFY(nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_TXG,
-                   &label_txg) == 0);
-
-               /*
-                * Do we have a better boot device?
-                */
-               if (label_txg > *txg) {
-                       *txg = label_txg;
-                       *avd = vd;
-               }
-               nvlist_free(label);
-       }
-}
+        * Create the pool's history object.
+        */
+       if (version >= SPA_VERSION_ZPOOL_HISTORY && !spa->spa_history)
+               spa_history_create_obj(spa, tx);
 
-/*
- * Import a root pool.
- *
- * For x86. devpath_list will consist of devid and/or physpath name of
- * the vdev (e.g. "id1,sd@SSEAGATE..." or "/pci@1f,0/ide@d/disk@0,0:a").
- * The GRUB "findroot" command will return the vdev we should boot.
- *
- * For Sparc, devpath_list consists the physpath name of the booting device
- * no matter the rootpool is a single device pool or a mirrored pool.
- * e.g.
- *     "/pci@1f,0/ide@d/disk@0,0:a"
- */
-int
-spa_import_rootpool(char *devpath, char *devid)
-{
-       spa_t *spa;
-       vdev_t *rvd, *bvd, *avd = NULL;
-       nvlist_t *config, *nvtop;
-       uint64_t guid, txg;
-       char *pname;
-       int error;
+       spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_CREATE);
+       spa_history_log_version(spa, "create", tx);
 
        /*
-        * Read the label from the boot device and generate a configuration.
+        * Create the pool config object.
         */
-       config = spa_generate_rootconf(devpath, devid, &guid);
-#if defined(_OBP) && defined(_KERNEL)
-       if (config == NULL) {
-               if (strstr(devpath, "/iscsi/ssd") != NULL) {
-                       /* iscsi boot */
-                       get_iscsi_bootpath_phy(devpath);
-                       config = spa_generate_rootconf(devpath, devid, &guid);
-               }
-       }
-#endif
-       if (config == NULL) {
-               cmn_err(CE_NOTE, "Cannot read the pool label from '%s'",
-                   devpath);
-               return (SET_ERROR(EIO));
+       spa->spa_config_object = dmu_object_alloc(spa->spa_meta_objset,
+           DMU_OT_PACKED_NVLIST, SPA_CONFIG_BLOCKSIZE,
+           DMU_OT_PACKED_NVLIST_SIZE, sizeof (uint64_t), tx);
+
+       if (zap_add(spa->spa_meta_objset,
+           DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CONFIG,
+           sizeof (uint64_t), 1, &spa->spa_config_object, tx) != 0) {
+               cmn_err(CE_PANIC, "failed to add pool config");
        }
 
-       VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
-           &pname) == 0);
-       VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg) == 0);
+       if (spa_version(spa) >= SPA_VERSION_FEATURES)
+               spa_feature_create_zap_objects(spa, tx);
 
-       mutex_enter(&spa_namespace_lock);
-       if ((spa = spa_lookup(pname)) != NULL) {
-               /*
-                * Remove the existing root pool from the namespace so that we
-                * can replace it with the correct config we just read in.
-                */
-               spa_remove(spa);
+       if (zap_add(spa->spa_meta_objset,
+           DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CREATION_VERSION,
+           sizeof (uint64_t), 1, &version, tx) != 0) {
+               cmn_err(CE_PANIC, "failed to add pool version");
        }
 
-       spa = spa_add(pname, config, NULL);
-       spa->spa_is_root = B_TRUE;
-       spa->spa_import_flags = ZFS_IMPORT_VERBATIM;
+       /* Newly created pools with the right version are always deflated. */
+       if (version >= SPA_VERSION_RAIDZ_DEFLATE) {
+               spa->spa_deflate = TRUE;
+               if (zap_add(spa->spa_meta_objset,
+                   DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE,
+                   sizeof (uint64_t), 1, &spa->spa_deflate, tx) != 0) {
+                       cmn_err(CE_PANIC, "failed to add deflate");
+               }
+       }
 
        /*
-        * Build up a vdev tree based on the boot device's label config.
+        * Create the deferred-free bpobj.  Turn off compression
+        * because sync-to-convergence takes longer if the blocksize
+        * keeps changing.
         */
-       VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
-           &nvtop) == 0);
-       spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
-       error = spa_config_parse(spa, &rvd, nvtop, NULL, 0,
-           VDEV_ALLOC_ROOTPOOL);
-       spa_config_exit(spa, SCL_ALL, FTAG);
-       if (error) {
-               mutex_exit(&spa_namespace_lock);
-               nvlist_free(config);
-               cmn_err(CE_NOTE, "Can not parse the config for pool '%s'",
-                   pname);
-               return (error);
+       obj = bpobj_alloc(spa->spa_meta_objset, 1 << 14, tx);
+       dmu_object_set_compress(spa->spa_meta_objset, obj,
+           ZIO_COMPRESS_OFF, tx);
+       if (zap_add(spa->spa_meta_objset,
+           DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SYNC_BPOBJ,
+           sizeof (uint64_t), 1, &obj, tx) != 0) {
+               cmn_err(CE_PANIC, "failed to add bpobj");
        }
+       VERIFY3U(0, ==, bpobj_open(&spa->spa_deferred_bpobj,
+           spa->spa_meta_objset, obj));
 
        /*
-        * Get the boot vdev.
+        * Generate some random noise for salted checksums to operate on.
         */
-       if ((bvd = vdev_lookup_by_guid(rvd, guid)) == NULL) {
-               cmn_err(CE_NOTE, "Can not find the boot vdev for guid %llu",
-                   (u_longlong_t)guid);
-               error = SET_ERROR(ENOENT);
-               goto out;
-       }
+       (void) random_get_pseudo_bytes(spa->spa_cksum_salt.zcs_bytes,
+           sizeof (spa->spa_cksum_salt.zcs_bytes));
 
        /*
-        * Determine if there is a better boot device.
+        * Set pool properties.
         */
-       avd = bvd;
-       spa_alt_rootvdev(rvd, &avd, &txg);
-       if (avd != bvd) {
-               cmn_err(CE_NOTE, "The boot device is 'degraded'. Please "
-                   "try booting from '%s'", avd->vdev_path);
-               error = SET_ERROR(EINVAL);
-               goto out;
+       spa->spa_bootfs = zpool_prop_default_numeric(ZPOOL_PROP_BOOTFS);
+       spa->spa_delegation = zpool_prop_default_numeric(ZPOOL_PROP_DELEGATION);
+       spa->spa_failmode = zpool_prop_default_numeric(ZPOOL_PROP_FAILUREMODE);
+       spa->spa_autoexpand = zpool_prop_default_numeric(ZPOOL_PROP_AUTOEXPAND);
+       spa->spa_multihost = zpool_prop_default_numeric(ZPOOL_PROP_MULTIHOST);
+
+       if (props != NULL) {
+               spa_configfile_set(spa, props, B_FALSE);
+               spa_sync_props(props, tx);
        }
 
+       dmu_tx_commit(tx);
+
+       spa->spa_sync_on = B_TRUE;
+       txg_sync_start(spa->spa_dsl_pool);
+       mmp_thread_start(spa);
+
        /*
-        * If the boot device is part of a spare vdev then ensure that
-        * we're booting off the active spare.
+        * We explicitly wait for the first transaction to complete so that our
+        * bean counters are appropriately updated.
         */
-       if (bvd->vdev_parent->vdev_ops == &vdev_spare_ops &&
-           !bvd->vdev_isspare) {
-               cmn_err(CE_NOTE, "The boot device is currently spared. Please "
-                   "try booting from '%s'",
-                   bvd->vdev_parent->
-                   vdev_child[bvd->vdev_parent->vdev_children - 1]->vdev_path);
-               error = SET_ERROR(EINVAL);
-               goto out;
-       }
+       txg_wait_synced(spa->spa_dsl_pool, txg);
+
+       spa_config_sync(spa, B_FALSE, B_TRUE);
+
+       /*
+        * Don't count references from objsets that are already closed
+        * and are making their way through the eviction process.
+        */
+       spa_evicting_os_wait(spa);
+       spa->spa_minref = refcount_count(&spa->spa_refcount);
+       spa->spa_load_state = SPA_LOAD_NONE;
 
-       error = 0;
-out:
-       spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
-       vdev_free(rvd);
-       spa_config_exit(spa, SCL_ALL, FTAG);
        mutex_exit(&spa_namespace_lock);
 
-       nvlist_free(config);
-       return (error);
+       return (0);
 }
 
-#endif
-
 /*
  * Import a non-root pool into the system.
  */
@@ -3925,6 +4298,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
                        spa_configfile_set(spa, props, B_FALSE);
 
                spa_config_sync(spa, B_FALSE, B_TRUE);
+               spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT);
 
                mutex_exit(&spa_namespace_lock);
                return (0);
@@ -3977,12 +4351,6 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
 
        VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
            &nvroot) == 0);
-       if (error == 0)
-               error = spa_validate_aux(spa, nvroot, -1ULL,
-                   VDEV_ALLOC_SPARE);
-       if (error == 0)
-               error = spa_validate_aux(spa, nvroot, -1ULL,
-                   VDEV_ALLOC_L2CACHE);
        spa_config_exit(spa, SCL_ALL, FTAG);
 
        if (props != NULL)
@@ -4010,7 +4378,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
                            ZPOOL_CONFIG_SPARES, DATA_TYPE_NVLIST_ARRAY) == 0);
                else
                        VERIFY(nvlist_alloc(&spa->spa_spares.sav_config,
-                           NV_UNIQUE_NAME, KM_PUSHPAGE) == 0);
+                           NV_UNIQUE_NAME, KM_SLEEP) == 0);
                VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config,
                    ZPOOL_CONFIG_SPARES, spares, nspares) == 0);
                spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
@@ -4025,7 +4393,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
                            ZPOOL_CONFIG_L2CACHE, DATA_TYPE_NVLIST_ARRAY) == 0);
                else
                        VERIFY(nvlist_alloc(&spa->spa_l2cache.sav_config,
-                           NV_UNIQUE_NAME, KM_PUSHPAGE) == 0);
+                           NV_UNIQUE_NAME, KM_SLEEP) == 0);
                VERIFY(nvlist_add_nvlist_array(spa->spa_l2cache.sav_config,
                    ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0);
                spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
@@ -4055,12 +4423,13 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
         */
        spa_async_request(spa, SPA_ASYNC_AUTOEXPAND);
 
-       mutex_exit(&spa_namespace_lock);
-       spa_history_log_version(spa, "import");
+       spa_history_log_version(spa, "import", NULL);
 
-#ifdef _KERNEL
-       zvol_create_minors(pool);
-#endif
+       spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT);
+
+       zvol_create_minors(spa, pool, B_TRUE);
+
+       mutex_exit(&spa_namespace_lock);
 
        return (0);
 }
@@ -4116,7 +4485,7 @@ spa_tryimport(nvlist_t *tryconfig)
                 * pools are bootable.
                 */
                if ((!error || error == EEXIST) && spa->spa_bootfs) {
-                       char *tmpname = kmem_alloc(MAXPATHLEN, KM_PUSHPAGE);
+                       char *tmpname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
 
                        /*
                         * We have to play games with the name since the
@@ -4127,7 +4496,7 @@ spa_tryimport(nvlist_t *tryconfig)
                                char *cp;
                                char *dsname;
 
-                               dsname = kmem_alloc(MAXPATHLEN, KM_PUSHPAGE);
+                               dsname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
 
                                cp = strchr(tmpname, '/');
                                if (cp == NULL) {
@@ -4195,33 +4564,39 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig,
        spa_open_ref(spa, FTAG);
        mutex_exit(&spa_namespace_lock);
        spa_async_suspend(spa);
+       if (spa->spa_zvol_taskq) {
+               zvol_remove_minors(spa, spa_name(spa), B_TRUE);
+               taskq_wait(spa->spa_zvol_taskq);
+       }
        mutex_enter(&spa_namespace_lock);
        spa_close(spa, FTAG);
 
+       if (spa->spa_state == POOL_STATE_UNINITIALIZED)
+               goto export_spa;
        /*
-        * The pool will be in core if it's openable,
-        * in which case we can modify its state.
+        * The pool will be in core if it's openable, in which case we can
+        * modify its state.  Objsets may be open only because they're dirty,
+        * so we have to force it to sync before checking spa_refcnt.
         */
-       if (spa->spa_state != POOL_STATE_UNINITIALIZED && spa->spa_sync_on) {
-               /*
-                * Objsets may be open only because they're dirty, so we
-                * have to force it to sync before checking spa_refcnt.
-                */
+       if (spa->spa_sync_on) {
                txg_wait_synced(spa->spa_dsl_pool, 0);
+               spa_evicting_os_wait(spa);
+       }
 
-               /*
-                * A pool cannot be exported or destroyed if there are active
-                * references.  If we are resetting a pool, allow references by
-                * fault injection handlers.
-                */
-               if (!spa_refcount_zero(spa) ||
-                   (spa->spa_inject_ref != 0 &&
-                   new_state != POOL_STATE_UNINITIALIZED)) {
-                       spa_async_resume(spa);
-                       mutex_exit(&spa_namespace_lock);
-                       return (SET_ERROR(EBUSY));
-               }
+       /*
+        * A pool cannot be exported or destroyed if there are active
+        * references.  If we are resetting a pool, allow references by
+        * fault injection handlers.
+        */
+       if (!spa_refcount_zero(spa) ||
+           (spa->spa_inject_ref != 0 &&
+           new_state != POOL_STATE_UNINITIALIZED)) {
+               spa_async_resume(spa);
+               mutex_exit(&spa_namespace_lock);
+               return (SET_ERROR(EBUSY));
+       }
 
+       if (spa->spa_sync_on) {
                /*
                 * A pool cannot be exported if it has an active shared spare.
                 * This is to prevent other pools stealing the active spare
@@ -4250,7 +4625,11 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig,
                }
        }
 
-       spa_event_notify(spa, NULL, FM_EREPORT_ZFS_POOL_DESTROY);
+export_spa:
+       if (new_state == POOL_STATE_DESTROYED)
+               spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_DESTROY);
+       else if (new_state == POOL_STATE_EXPORTED)
+               spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_EXPORT);
 
        if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
                spa_unload(spa);
@@ -4406,6 +4785,7 @@ spa_vdev_add(spa_t *spa, nvlist_t *nvroot)
 
        mutex_enter(&spa_namespace_lock);
        spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
+       spa_event_notify(spa, NULL, NULL, ESC_ZFS_VDEV_ADD);
        mutex_exit(&spa_namespace_lock);
 
        return (0);
@@ -4532,7 +4912,7 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing)
        if (strcmp(oldvd->vdev_path, newvd->vdev_path) == 0) {
                spa_strfree(oldvd->vdev_path);
                oldvd->vdev_path = kmem_alloc(strlen(newvd->vdev_path) + 5,
-                   KM_PUSHPAGE);
+                   KM_SLEEP);
                (void) sprintf(oldvd->vdev_path, "%s/%s",
                    newvd->vdev_path, "old");
                if (oldvd->vdev_devid != NULL) {
@@ -4563,6 +4943,11 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing)
        newvd->vdev_crtxg = oldvd->vdev_crtxg;
        vdev_add_child(pvd, newvd);
 
+       /*
+        * Reevaluate the parent vdev state.
+        */
+       vdev_propagate_state(pvd);
+
        tvd = newvd->vdev_top;
        ASSERT(pvd->vdev_top == tvd);
        ASSERT(tvd->vdev_parent == rvd);
@@ -4581,7 +4966,7 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing)
 
        if (newvd->vdev_isspare) {
                spa_spare_activate(newvd);
-               spa_event_notify(spa, newvd, FM_EREPORT_ZFS_DEVICE_SPARE);
+               spa_event_notify(spa, newvd, NULL, ESC_ZFS_VDEV_SPARE);
        }
 
        oldvdpath = spa_strdup(oldvd->vdev_path);
@@ -4600,6 +4985,11 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing)
         */
        dsl_resilver_restart(spa->spa_dsl_pool, dtl_max_txg);
 
+       if (spa->spa_bootfs)
+               spa_event_notify(spa, newvd, NULL, ESC_ZFS_BOOTFS_VDEV_ATTACH);
+
+       spa_event_notify(spa, newvd, NULL, ESC_ZFS_VDEV_ATTACH);
+
        /*
         * Commit the config
         */
@@ -4614,9 +5004,6 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing)
        spa_strfree(oldvdpath);
        spa_strfree(newvdpath);
 
-       if (spa->spa_bootfs)
-               spa_event_notify(spa, newvd, FM_EREPORT_ZFS_BOOTFS_VDEV_ATTACH);
-
        return (0);
 }
 
@@ -4809,13 +5196,13 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done)
         * But first make sure we're not on any *other* txg's DTL list, to
         * prevent vd from being accessed after it's freed.
         */
-       vdpath = spa_strdup(vd->vdev_path);
+       vdpath = spa_strdup(vd->vdev_path ? vd->vdev_path : "none");
        for (t = 0; t < TXG_SIZE; t++)
                (void) txg_list_remove_this(&tvd->vdev_dtl_list, vd, t);
        vd->vdev_detached = B_TRUE;
        vdev_dirty(tvd, VDD_DTL, vd, txg);
 
-       spa_event_notify(spa, vd, FM_EREPORT_ZFS_DEVICE_REMOVE);
+       spa_event_notify(spa, vd, NULL, ESC_ZFS_VDEV_REMOVE);
 
        /* hang on to the spa before we release the lock */
        spa_open_ref(spa, FTAG);
@@ -4928,8 +5315,8 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
            nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_L2CACHE, &tmp) == 0)
                return (spa_vdev_exit(spa, NULL, txg, EINVAL));
 
-       vml = kmem_zalloc(children * sizeof (vdev_t *), KM_PUSHPAGE);
-       glist = kmem_zalloc(children * sizeof (uint64_t), KM_PUSHPAGE);
+       vml = kmem_zalloc(children * sizeof (vdev_t *), KM_SLEEP);
+       glist = kmem_zalloc(children * sizeof (uint64_t), KM_SLEEP);
 
        /* then, loop over each vdev and validate it */
        for (c = 0; c < children; c++) {
@@ -4990,6 +5377,16 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
                    vml[c]->vdev_top->vdev_asize) == 0);
                VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_ASHIFT,
                    vml[c]->vdev_top->vdev_ashift) == 0);
+
+               /* transfer per-vdev ZAPs */
+               ASSERT3U(vml[c]->vdev_leaf_zap, !=, 0);
+               VERIFY0(nvlist_add_uint64(child[c],
+                   ZPOOL_CONFIG_VDEV_LEAF_ZAP, vml[c]->vdev_leaf_zap));
+
+               ASSERT3U(vml[c]->vdev_top->vdev_top_zap, !=, 0);
+               VERIFY0(nvlist_add_uint64(child[c],
+                   ZPOOL_CONFIG_VDEV_TOP_ZAP,
+                   vml[c]->vdev_parent->vdev_top_zap));
        }
 
        if (error != 0) {
@@ -5009,7 +5406,7 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
         * Temporarily record the splitting vdevs in the spa config.  This
         * will disappear once the config is regenerated.
         */
-       VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_PUSHPAGE) == 0);
+       VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
        VERIFY(nvlist_add_uint64_array(nvl, ZPOOL_CONFIG_SPLIT_LIST,
            glist, children) == 0);
        kmem_free(glist, children * sizeof (uint64_t));
@@ -5031,11 +5428,13 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
            spa->spa_config_txg) == 0);
        VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
            spa_generate_guid(NULL)) == 0);
+       VERIFY0(nvlist_add_boolean(config, ZPOOL_CONFIG_HAS_PER_VDEV_ZAPS));
        (void) nvlist_lookup_string(props,
            zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
 
        /* add the new pool to the namespace */
        newspa = spa_add(newname, config, altroot);
+       newspa->spa_avz_action = AVZ_ACTION_REBUILD;
        newspa->spa_config_txg = spa->spa_config_txg;
        spa_set_log_state(newspa, SPA_LOG_CLEAR);
 
@@ -5056,7 +5455,7 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
        /* if that worked, generate a real config for the new pool */
        if (newspa->spa_root_vdev != NULL) {
                VERIFY(nvlist_alloc(&newspa->spa_config_splitting,
-                   NV_UNIQUE_NAME, KM_PUSHPAGE) == 0);
+                   NV_UNIQUE_NAME, KM_SLEEP) == 0);
                VERIFY(nvlist_add_uint64(newspa->spa_config_splitting,
                    ZPOOL_CONFIG_SPLIT_GUID, spa_guid(spa)) == 0);
                spa_config_set(newspa, spa_config_generate(newspa, NULL, -1ULL,
@@ -5093,9 +5492,11 @@ spa_vdev_split_mirror(spa_t *spa, char *newname, nvlist_t *config,
                        if (error == 0)
                                spa_history_log_internal(spa, "detach", tx,
                                    "vdev=%s", vml[c]->vdev_path);
+
                        vdev_free(vml[c]);
                }
        }
+       spa->spa_avz_action = AVZ_ACTION_REBUILD;
        vdev_config_dirty(spa->spa_root_vdev);
        spa->spa_config_splitting = NULL;
        nvlist_free(nvl);
@@ -5161,18 +5562,18 @@ spa_nvlist_lookup_by_guid(nvlist_t **nvpp, int count, uint64_t target_guid)
 
 static void
 spa_vdev_remove_aux(nvlist_t *config, char *name, nvlist_t **dev, int count,
-       nvlist_t *dev_to_remove)
+    nvlist_t *dev_to_remove)
 {
        nvlist_t **newdev = NULL;
        int i, j;
 
        if (count > 1)
-               newdev = kmem_alloc((count - 1) * sizeof (void *), KM_PUSHPAGE);
+               newdev = kmem_alloc((count - 1) * sizeof (void *), KM_SLEEP);
 
        for (i = 0, j = 0; i < count; i++) {
                if (dev[i] == dev_to_remove)
                        continue;
-               VERIFY(nvlist_dup(dev[i], &newdev[j++], KM_PUSHPAGE) == 0);
+               VERIFY(nvlist_dup(dev[i], &newdev[j++], KM_SLEEP) == 0);
        }
 
        VERIFY(nvlist_remove(config, name, DATA_TYPE_NVLIST_ARRAY) == 0);
@@ -5287,6 +5688,7 @@ int
 spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare)
 {
        vdev_t *vd;
+       sysevent_t *ev = NULL;
        metaslab_group_t *mg;
        nvlist_t **spares, **l2cache, *nv;
        uint64_t txg = 0;
@@ -5310,6 +5712,10 @@ spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare)
                 * in this pool.
                 */
                if (vd == NULL || unspare) {
+                       if (vd == NULL)
+                               vd = spa_lookup_by_guid(spa, guid, B_TRUE);
+                       ev = spa_event_create(spa, vd, NULL,
+                           ESC_ZFS_VDEV_REMOVE_AUX);
                        spa_vdev_remove_aux(spa->spa_spares.sav_config,
                            ZPOOL_CONFIG_SPARES, spares, nspares, nv);
                        spa_load_spares(spa);
@@ -5324,6 +5730,8 @@ spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare)
                /*
                 * Cache devices can always be removed.
                 */
+               vd = spa_lookup_by_guid(spa, guid, B_TRUE);
+               ev = spa_event_create(spa, vd, NULL, ESC_ZFS_VDEV_REMOVE_AUX);
                spa_vdev_remove_aux(spa->spa_l2cache.sav_config,
                    ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache, nv);
                spa_load_l2cache(spa);
@@ -5364,6 +5772,7 @@ spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare)
                /*
                 * Clean up the vdev namespace.
                 */
+               ev = spa_event_create(spa, vd, NULL, ESC_ZFS_VDEV_REMOVE_DEV);
                spa_vdev_remove_from_namespace(spa, vd);
 
        } else if (vd != NULL) {
@@ -5379,7 +5788,10 @@ spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare)
        }
 
        if (!locked)
-               return (spa_vdev_exit(spa, NULL, txg, error));
+               error = spa_vdev_exit(spa, NULL, txg, error);
+
+       if (ev)
+               spa_event_post(ev);
 
        return (error);
 }
@@ -5559,6 +5971,16 @@ spa_vdev_setfru(spa_t *spa, uint64_t guid, const char *newfru)
  * SPA Scanning
  * ==========================================================================
  */
+int
+spa_scrub_pause_resume(spa_t *spa, pool_scrub_cmd_t cmd)
+{
+       ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
+
+       if (dsl_scan_resilvering(spa->spa_dsl_pool))
+               return (SET_ERROR(EBUSY));
+
+       return (dsl_scrub_set_pause_resume(spa->spa_dsl_pool, cmd));
+}
 
 int
 spa_scan_stop(spa_t *spa)
@@ -5653,7 +6075,7 @@ spa_async_autoexpand(spa_t *spa, vdev_t *vd)
        if (!vd->vdev_ops->vdev_op_leaf || vd->vdev_physpath == NULL)
                return;
 
-       spa_event_notify(vd->vdev_spa, vd, FM_EREPORT_ZFS_DEVICE_AUTOEXPAND);
+       spa_event_notify(vd->vdev_spa, vd, NULL, ESC_ZFS_VDEV_AUTOEXPAND);
 }
 
 static void
@@ -5760,13 +6182,34 @@ spa_async_resume(spa_t *spa)
        mutex_exit(&spa->spa_async_lock);
 }
 
+static boolean_t
+spa_async_tasks_pending(spa_t *spa)
+{
+       uint_t non_config_tasks;
+       uint_t config_task;
+       boolean_t config_task_suspended;
+
+       non_config_tasks = spa->spa_async_tasks & ~SPA_ASYNC_CONFIG_UPDATE;
+       config_task = spa->spa_async_tasks & SPA_ASYNC_CONFIG_UPDATE;
+       if (spa->spa_ccw_fail_time == 0) {
+               config_task_suspended = B_FALSE;
+       } else {
+               config_task_suspended =
+                   (gethrtime() - spa->spa_ccw_fail_time) <
+                   ((hrtime_t)zfs_ccw_retry_interval * NANOSEC);
+       }
+
+       return (non_config_tasks || (config_task && !config_task_suspended));
+}
+
 static void
 spa_async_dispatch(spa_t *spa)
 {
        mutex_enter(&spa->spa_async_lock);
-       if (spa->spa_async_tasks && !spa->spa_async_suspended &&
+       if (spa_async_tasks_pending(spa) &&
+           !spa->spa_async_suspended &&
            spa->spa_async_thread == NULL &&
-           rootdir != NULL && !vn_is_readonly(rootdir))
+           rootdir != NULL)
                spa->spa_async_thread = thread_create(NULL, 0,
                    spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri);
        mutex_exit(&spa->spa_async_lock);
@@ -5846,10 +6289,10 @@ spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx)
         * saves us a pre-read to get data we don't actually care about.
         */
        bufsize = P2ROUNDUP((uint64_t)nvsize, SPA_CONFIG_BLOCKSIZE);
-       packed = vmem_alloc(bufsize, KM_PUSHPAGE);
+       packed = vmem_alloc(bufsize, KM_SLEEP);
 
        VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR,
-           KM_PUSHPAGE) == 0);
+           KM_SLEEP) == 0);
        bzero(packed + nvsize, bufsize - nvsize);
 
        dmu_write(spa->spa_meta_objset, obj, 0, bufsize, packed, tx);
@@ -5887,11 +6330,11 @@ spa_sync_aux_dev(spa_t *spa, spa_aux_vdev_t *sav, dmu_tx_t *tx,
                    &sav->sav_object, tx) == 0);
        }
 
-       VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_PUSHPAGE) == 0);
+       VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_SLEEP) == 0);
        if (sav->sav_count == 0) {
                VERIFY(nvlist_add_nvlist_array(nvroot, config, NULL, 0) == 0);
        } else {
-               list = kmem_alloc(sav->sav_count*sizeof (void *), KM_PUSHPAGE);
+               list = kmem_alloc(sav->sav_count*sizeof (void *), KM_SLEEP);
                for (i = 0; i < sav->sav_count; i++)
                        list[i] = vdev_config_generate(spa, sav->sav_vdevs[i],
                            B_FALSE, VDEV_CONFIG_L2CACHE);
@@ -5908,16 +6351,121 @@ spa_sync_aux_dev(spa_t *spa, spa_aux_vdev_t *sav, dmu_tx_t *tx,
        sav->sav_sync = B_FALSE;
 }
 
+/*
+ * Rebuild spa's all-vdev ZAP from the vdev ZAPs indicated in each vdev_t.
+ * The all-vdev ZAP must be empty.
+ */
+static void
+spa_avz_build(vdev_t *vd, uint64_t avz, dmu_tx_t *tx)
+{
+       spa_t *spa = vd->vdev_spa;
+       uint64_t i;
+
+       if (vd->vdev_top_zap != 0) {
+               VERIFY0(zap_add_int(spa->spa_meta_objset, avz,
+                   vd->vdev_top_zap, tx));
+       }
+       if (vd->vdev_leaf_zap != 0) {
+               VERIFY0(zap_add_int(spa->spa_meta_objset, avz,
+                   vd->vdev_leaf_zap, tx));
+       }
+       for (i = 0; i < vd->vdev_children; i++) {
+               spa_avz_build(vd->vdev_child[i], avz, tx);
+       }
+}
+
 static void
 spa_sync_config_object(spa_t *spa, dmu_tx_t *tx)
 {
        nvlist_t *config;
 
-       if (list_is_empty(&spa->spa_config_dirty_list))
+       /*
+        * If the pool is being imported from a pre-per-vdev-ZAP version of ZFS,
+        * its config may not be dirty but we still need to build per-vdev ZAPs.
+        * Similarly, if the pool is being assembled (e.g. after a split), we
+        * need to rebuild the AVZ although the config may not be dirty.
+        */
+       if (list_is_empty(&spa->spa_config_dirty_list) &&
+           spa->spa_avz_action == AVZ_ACTION_NONE)
                return;
 
        spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
 
+       ASSERT(spa->spa_avz_action == AVZ_ACTION_NONE ||
+           spa->spa_avz_action == AVZ_ACTION_INITIALIZE ||
+           spa->spa_all_vdev_zaps != 0);
+
+       if (spa->spa_avz_action == AVZ_ACTION_REBUILD) {
+               zap_cursor_t zc;
+               zap_attribute_t za;
+
+               /* Make and build the new AVZ */
+               uint64_t new_avz = zap_create(spa->spa_meta_objset,
+                   DMU_OTN_ZAP_METADATA, DMU_OT_NONE, 0, tx);
+               spa_avz_build(spa->spa_root_vdev, new_avz, tx);
+
+               /* Diff old AVZ with new one */
+               for (zap_cursor_init(&zc, spa->spa_meta_objset,
+                   spa->spa_all_vdev_zaps);
+                   zap_cursor_retrieve(&zc, &za) == 0;
+                   zap_cursor_advance(&zc)) {
+                       uint64_t vdzap = za.za_first_integer;
+                       if (zap_lookup_int(spa->spa_meta_objset, new_avz,
+                           vdzap) == ENOENT) {
+                               /*
+                                * ZAP is listed in old AVZ but not in new one;
+                                * destroy it
+                                */
+                               VERIFY0(zap_destroy(spa->spa_meta_objset, vdzap,
+                                   tx));
+                       }
+               }
+
+               zap_cursor_fini(&zc);
+
+               /* Destroy the old AVZ */
+               VERIFY0(zap_destroy(spa->spa_meta_objset,
+                   spa->spa_all_vdev_zaps, tx));
+
+               /* Replace the old AVZ in the dir obj with the new one */
+               VERIFY0(zap_update(spa->spa_meta_objset,
+                   DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_VDEV_ZAP_MAP,
+                   sizeof (new_avz), 1, &new_avz, tx));
+
+               spa->spa_all_vdev_zaps = new_avz;
+       } else if (spa->spa_avz_action == AVZ_ACTION_DESTROY) {
+               zap_cursor_t zc;
+               zap_attribute_t za;
+
+               /* Walk through the AVZ and destroy all listed ZAPs */
+               for (zap_cursor_init(&zc, spa->spa_meta_objset,
+                   spa->spa_all_vdev_zaps);
+                   zap_cursor_retrieve(&zc, &za) == 0;
+                   zap_cursor_advance(&zc)) {
+                       uint64_t zap = za.za_first_integer;
+                       VERIFY0(zap_destroy(spa->spa_meta_objset, zap, tx));
+               }
+
+               zap_cursor_fini(&zc);
+
+               /* Destroy and unlink the AVZ itself */
+               VERIFY0(zap_destroy(spa->spa_meta_objset,
+                   spa->spa_all_vdev_zaps, tx));
+               VERIFY0(zap_remove(spa->spa_meta_objset,
+                   DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_VDEV_ZAP_MAP, tx));
+               spa->spa_all_vdev_zaps = 0;
+       }
+
+       if (spa->spa_all_vdev_zaps == 0) {
+               spa->spa_all_vdev_zaps = zap_create_link(spa->spa_meta_objset,
+                   DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
+                   DMU_POOL_VDEV_ZAP_MAP, tx);
+       }
+       spa->spa_avz_action = AVZ_ACTION_NONE;
+
+       /* Create ZAPs for vdevs that don't have them. */
+       vdev_construct_zaps(spa->spa_root_vdev, tx);
+
        config = spa_config_generate(spa, spa->spa_root_vdev,
            dmu_tx_get_txg(tx), B_FALSE);
 
@@ -5931,8 +6479,7 @@ spa_sync_config_object(spa_t *spa, dmu_tx_t *tx)
 
        spa_config_exit(spa, SCL_STATE, FTAG);
 
-       if (spa->spa_config_syncing)
-               nvlist_free(spa->spa_config_syncing);
+       nvlist_free(spa->spa_config_syncing);
        spa->spa_config_syncing = config;
 
        spa_sync_nvlist(spa, spa->spa_config_object, config, tx);
@@ -5998,7 +6545,7 @@ spa_sync_props(void *arg, dmu_tx_t *tx)
                case ZPOOL_PROP_VERSION:
                        intval = fnvpair_value_uint64(elem);
                        /*
-                        * The version is synced seperatly before other
+                        * The version is synced separately before other
                         * properties and should be correct by now.
                         */
                        ASSERT3U(spa_version(spa), >=, intval);
@@ -6028,7 +6575,7 @@ spa_sync_props(void *arg, dmu_tx_t *tx)
                         * We need to dirty the configuration on all the vdevs
                         * so that their labels get updated.  It's unnecessary
                         * to do this for pool creation since the vdev's
-                        * configuratoin has already been dirtied.
+                        * configuration has already been dirtied.
                         */
                        if (tx->tx_txg != TXG_INITIAL)
                                vdev_config_dirty(spa->spa_root_vdev);
@@ -6091,6 +6638,9 @@ spa_sync_props(void *arg, dmu_tx_t *tx)
                                        spa_async_request(spa,
                                            SPA_ASYNC_AUTOEXPAND);
                                break;
+                       case ZPOOL_PROP_MULTIHOST:
+                               spa->spa_multihost = intval;
+                               break;
                        case ZPOOL_PROP_DEDUPDITTO:
                                spa->spa_dedup_ditto = intval;
                                break;
@@ -6145,6 +6695,36 @@ spa_sync_upgrades(spa_t *spa, dmu_tx_t *tx)
            spa->spa_uberblock.ub_version >= SPA_VERSION_FEATURES) {
                spa_feature_create_zap_objects(spa, tx);
        }
+
+       /*
+        * LZ4_COMPRESS feature's behaviour was changed to activate_on_enable
+        * when possibility to use lz4 compression for metadata was added
+        * Old pools that have this feature enabled must be upgraded to have
+        * this feature active
+        */
+       if (spa->spa_uberblock.ub_version >= SPA_VERSION_FEATURES) {
+               boolean_t lz4_en = spa_feature_is_enabled(spa,
+                   SPA_FEATURE_LZ4_COMPRESS);
+               boolean_t lz4_ac = spa_feature_is_active(spa,
+                   SPA_FEATURE_LZ4_COMPRESS);
+
+               if (lz4_en && !lz4_ac)
+                       spa_feature_incr(spa, SPA_FEATURE_LZ4_COMPRESS, tx);
+       }
+
+       /*
+        * If we haven't written the salt, do so now.  Note that the
+        * feature may not be activated yet, but that's fine since
+        * the presence of this ZAP entry is backwards compatible.
+        */
+       if (zap_contains(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+           DMU_POOL_CHECKSUM_SALT) == ENOENT) {
+               VERIFY0(zap_add(spa->spa_meta_objset,
+                   DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CHECKSUM_SALT, 1,
+                   sizeof (spa->spa_cksum_salt.zcs_bytes),
+                   spa->spa_cksum_salt.zcs_bytes, tx));
+       }
+
        rrw_exit(&dp->dp_config_rwlock, FTAG);
 }
 
@@ -6158,10 +6738,14 @@ spa_sync(spa_t *spa, uint64_t txg)
        dsl_pool_t *dp = spa->spa_dsl_pool;
        objset_t *mos = spa->spa_meta_objset;
        bplist_t *free_bpl = &spa->spa_free_bplist[txg & TXG_MASK];
+       metaslab_class_t *mc;
        vdev_t *rvd = spa->spa_root_vdev;
        vdev_t *vd;
        dmu_tx_t *tx;
        int error;
+       uint32_t max_queue_depth = zfs_vdev_async_write_max_active *
+           zfs_vdev_queue_depth_pct / 100;
+       uint64_t queue_depth_total;
        int c;
 
        VERIFY(spa_writeable(spa));
@@ -6174,6 +6758,10 @@ spa_sync(spa_t *spa, uint64_t txg)
        spa->spa_syncing_txg = txg;
        spa->spa_sync_pass = 0;
 
+       mutex_enter(&spa->spa_alloc_lock);
+       VERIFY0(avl_numnodes(&spa->spa_alloc_tree));
+       mutex_exit(&spa->spa_alloc_lock);
+
        /*
         * If there are any pending vdev state changes, convert them
         * into config changes that go out with this transaction group.
@@ -6201,9 +6789,9 @@ spa_sync(spa_t *spa, uint64_t txg)
        tx = dmu_tx_create_assigned(dp, txg);
 
        spa->spa_sync_starttime = gethrtime();
-       taskq_cancel_id(system_taskq, spa->spa_deadman_tqid);
-       spa->spa_deadman_tqid = taskq_dispatch_delay(system_taskq,
-           spa_deadman, spa, TQ_PUSHPAGE, ddi_get_lbolt() +
+       taskq_cancel_id(system_delay_taskq, spa->spa_deadman_tqid);
+       spa->spa_deadman_tqid = taskq_dispatch_delay(system_delay_taskq,
+           spa_deadman, spa, TQ_SLEEP, ddi_get_lbolt() +
            NSEC_TO_TICK(spa->spa_deadman_synctime));
 
        /*
@@ -6228,19 +6816,36 @@ spa_sync(spa_t *spa, uint64_t txg)
        }
 
        /*
-        * If anything has changed in this txg, or if someone is waiting
-        * for this txg to sync (eg, spa_vdev_remove()), push the
-        * deferred frees from the previous txg.  If not, leave them
-        * alone so that we don't generate work on an otherwise idle
-        * system.
+        * Set the top-level vdev's max queue depth. Evaluate each
+        * top-level's async write queue depth in case it changed.
+        * The max queue depth will not change in the middle of syncing
+        * out this txg.
         */
-       if (!txg_list_empty(&dp->dp_dirty_datasets, txg) ||
-           !txg_list_empty(&dp->dp_dirty_dirs, txg) ||
-           !txg_list_empty(&dp->dp_sync_tasks, txg) ||
-           ((dsl_scan_active(dp->dp_scan) ||
-           txg_sync_waiting(dp)) && !spa_shutting_down(spa))) {
-               spa_sync_deferred_frees(spa, tx);
+       queue_depth_total = 0;
+       for (c = 0; c < rvd->vdev_children; c++) {
+               vdev_t *tvd = rvd->vdev_child[c];
+               metaslab_group_t *mg = tvd->vdev_mg;
+
+               if (mg == NULL || mg->mg_class != spa_normal_class(spa) ||
+                   !metaslab_group_initialized(mg))
+                       continue;
+
+               /*
+                * It is safe to do a lock-free check here because only async
+                * allocations look at mg_max_alloc_queue_depth, and async
+                * allocations all happen from spa_sync().
+                */
+               ASSERT0(refcount_count(&mg->mg_alloc_queue_depth));
+               mg->mg_max_alloc_queue_depth = max_queue_depth;
+               queue_depth_total += mg->mg_max_alloc_queue_depth;
        }
+       mc = spa_normal_class(spa);
+       ASSERT0(refcount_count(&mc->mc_alloc_slots));
+       mc->mc_alloc_max_slots = queue_depth_total;
+       mc->mc_alloc_throttle_enabled = zio_dva_throttle_enabled;
+
+       ASSERT3U(mc->mc_alloc_max_slots, <=,
+           max_queue_depth * rvd->vdev_children);
 
        /*
         * Iterate to convergence.
@@ -6259,6 +6864,11 @@ spa_sync(spa_t *spa, uint64_t txg)
                if (pass < zfs_sync_pass_deferred_free) {
                        spa_sync_frees(spa, free_bpl, tx);
                } else {
+                       /*
+                        * We can not defer frees in pass 1, because
+                        * we sync the deferred frees later in pass 1.
+                        */
+                       ASSERT3U(pass, >, 1);
                        bplist_iterate(free_bpl, bpobj_enqueue_cb,
                            &spa->spa_deferred_bpobj, tx);
                }
@@ -6269,11 +6879,57 @@ spa_sync(spa_t *spa, uint64_t txg)
                while ((vd = txg_list_remove(&spa->spa_vdev_txg_list, txg)))
                        vdev_sync(vd, txg);
 
-               if (pass == 1)
+               if (pass == 1) {
                        spa_sync_upgrades(spa, tx);
+                       ASSERT3U(txg, >=,
+                           spa->spa_uberblock.ub_rootbp.blk_birth);
+                       /*
+                        * Note: We need to check if the MOS is dirty
+                        * because we could have marked the MOS dirty
+                        * without updating the uberblock (e.g. if we
+                        * have sync tasks but no dirty user data).  We
+                        * need to check the uberblock's rootbp because
+                        * it is updated if we have synced out dirty
+                        * data (though in this case the MOS will most
+                        * likely also be dirty due to second order
+                        * effects, we don't want to rely on that here).
+                        */
+                       if (spa->spa_uberblock.ub_rootbp.blk_birth < txg &&
+                           !dmu_objset_is_dirty(mos, txg)) {
+                               /*
+                                * Nothing changed on the first pass,
+                                * therefore this TXG is a no-op.  Avoid
+                                * syncing deferred frees, so that we
+                                * can keep this TXG as a no-op.
+                                */
+                               ASSERT(txg_list_empty(&dp->dp_dirty_datasets,
+                                   txg));
+                               ASSERT(txg_list_empty(&dp->dp_dirty_dirs, txg));
+                               ASSERT(txg_list_empty(&dp->dp_sync_tasks, txg));
+                               break;
+                       }
+                       spa_sync_deferred_frees(spa, tx);
+               }
 
        } while (dmu_objset_is_dirty(mos, txg));
 
+#ifdef ZFS_DEBUG
+       if (!list_is_empty(&spa->spa_config_dirty_list)) {
+               /*
+                * Make sure that the number of ZAPs for all the vdevs matches
+                * the number of ZAPs in the per-vdev ZAP list. This only gets
+                * called if the config is dirty; otherwise there may be
+                * outstanding AVZ operations that weren't completed in
+                * spa_sync_config_object.
+                */
+               uint64_t all_vdev_zap_entry_count;
+               ASSERT0(zap_count(spa->spa_meta_objset,
+                   spa->spa_all_vdev_zaps, &all_vdev_zap_entry_count));
+               ASSERT3U(vdev_count_verify_zaps(spa->spa_root_vdev), ==,
+                   all_vdev_zap_entry_count);
+       }
+#endif
+
        /*
         * Rewrite the vdev configuration (which includes the uberblock)
         * to commit the transaction group.
@@ -6304,16 +6960,10 @@ spa_sync(spa_t *spa, uint64_t txg)
                                if (svdcount == SPA_DVAS_PER_BP)
                                        break;
                        }
-                       error = vdev_config_sync(svd, svdcount, txg, B_FALSE);
-                       if (error != 0)
-                               error = vdev_config_sync(svd, svdcount, txg,
-                                   B_TRUE);
+                       error = vdev_config_sync(svd, svdcount, txg);
                } else {
                        error = vdev_config_sync(rvd->vdev_child,
-                           rvd->vdev_children, txg, B_FALSE);
-                       if (error != 0)
-                               error = vdev_config_sync(rvd->vdev_child,
-                                   rvd->vdev_children, txg, B_TRUE);
+                           rvd->vdev_children, txg);
                }
 
                if (error == 0)
@@ -6323,12 +6973,12 @@ spa_sync(spa_t *spa, uint64_t txg)
 
                if (error == 0)
                        break;
-               zio_suspend(spa, NULL);
+               zio_suspend(spa, NULL, ZIO_SUSPEND_IOERR);
                zio_resume_wait(spa);
        }
        dmu_tx_commit(tx);
 
-       taskq_cancel_id(system_taskq, spa->spa_deadman_tqid);
+       taskq_cancel_id(system_delay_taskq, spa->spa_deadman_tqid);
        spa->spa_deadman_tqid = 0;
 
        /*
@@ -6347,10 +6997,12 @@ spa_sync(spa_t *spa, uint64_t txg)
                spa->spa_config_syncing = NULL;
        }
 
-       spa->spa_ubsync = spa->spa_uberblock;
-
        dsl_pool_sync_done(dp, txg);
 
+       mutex_enter(&spa->spa_alloc_lock);
+       VERIFY0(avl_numnodes(&spa->spa_alloc_tree));
+       mutex_exit(&spa->spa_alloc_lock);
+
        /*
         * Update usable space statistics.
         */
@@ -6369,6 +7021,13 @@ spa_sync(spa_t *spa, uint64_t txg)
 
        spa->spa_sync_pass = 0;
 
+       /*
+        * Update the last synced uberblock here. We want to do this at
+        * the end of spa_sync() so that consumers of spa_last_synced_txg()
+        * will be guaranteed that all the processing associated with
+        * that txg has been completed.
+        */
+       spa->spa_ubsync = spa->spa_uberblock;
        spa_config_exit(spa, SCL_CONFIG, FTAG);
 
        spa_handle_ignored_writes(spa);
@@ -6532,18 +7191,44 @@ spa_has_active_shared_spare(spa_t *spa)
        return (B_FALSE);
 }
 
+static sysevent_t *
+spa_event_create(spa_t *spa, vdev_t *vd, nvlist_t *hist_nvl, const char *name)
+{
+       sysevent_t *ev = NULL;
+#ifdef _KERNEL
+       nvlist_t *resource;
+
+       resource = zfs_event_create(spa, vd, FM_SYSEVENT_CLASS, name, hist_nvl);
+       if (resource) {
+               ev = kmem_alloc(sizeof (sysevent_t), KM_SLEEP);
+               ev->resource = resource;
+       }
+#endif
+       return (ev);
+}
+
+static void
+spa_event_post(sysevent_t *ev)
+{
+#ifdef _KERNEL
+       if (ev) {
+               zfs_zevent_post(ev->resource, NULL, zfs_zevent_post_cb);
+               kmem_free(ev, sizeof (*ev));
+       }
+#endif
+}
+
 /*
- * Post a FM_EREPORT_ZFS_* event from sys/fm/fs/zfs.h.  The payload will be
+ * Post a zevent corresponding to the given sysevent.   The 'name' must be one
+ * of the event definitions in sys/sysevent/eventdefs.h.  The payload will be
  * filled in from the spa and (optionally) the vdev.  This doesn't do anything
  * in the userland libzpool, as we don't want consumers to misinterpret ztest
  * or zdb as real changes.
  */
 void
-spa_event_notify(spa_t *spa, vdev_t *vd, const char *name)
+spa_event_notify(spa_t *spa, vdev_t *vd, nvlist_t *hist_nvl, const char *name)
 {
-#ifdef _KERNEL
-       zfs_ereport_post(name, spa, vd, NULL, 0, 0);
-#endif
+       spa_event_post(spa_event_create(spa, vd, hist_nvl, name));
 }
 
 #if defined(_KERNEL) && defined(HAVE_SPL)
@@ -6552,7 +7237,6 @@ EXPORT_SYMBOL(spa_open);
 EXPORT_SYMBOL(spa_open_rewind);
 EXPORT_SYMBOL(spa_get_stats);
 EXPORT_SYMBOL(spa_create);
-EXPORT_SYMBOL(spa_import_rootpool);
 EXPORT_SYMBOL(spa_import);
 EXPORT_SYMBOL(spa_tryimport);
 EXPORT_SYMBOL(spa_destroy);
@@ -6604,3 +7288,23 @@ EXPORT_SYMBOL(spa_prop_clear_bootfs);
 /* asynchronous event notification */
 EXPORT_SYMBOL(spa_event_notify);
 #endif
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+module_param(spa_load_verify_maxinflight, int, 0644);
+MODULE_PARM_DESC(spa_load_verify_maxinflight,
+       "Max concurrent traversal I/Os while verifying pool during import -X");
+
+module_param(spa_load_verify_metadata, int, 0644);
+MODULE_PARM_DESC(spa_load_verify_metadata,
+       "Set to traverse metadata on pool import");
+
+module_param(spa_load_verify_data, int, 0644);
+MODULE_PARM_DESC(spa_load_verify_data,
+       "Set to traverse data on pool import");
+
+/* CSTYLED */
+module_param(zio_taskq_batch_pct, uint, 0444);
+MODULE_PARM_DESC(zio_taskq_batch_pct,
+       "Percentage of CPUs to run an IO worker thread");
+
+#endif