Illumos #3329, #3330, #3331, #3335
[zfs.git] / module / zfs / spa.c
index 59c43f4..22fa787 100644 (file)
@@ -110,7 +110,7 @@ const zio_taskq_info_t zio_taskqs[ZIO_TYPES][ZIO_TASKQ_TYPES] = {
        { ZTI_ONE,      ZTI_NULL,       ZTI_ONE,        ZTI_NULL },
        { ZTI_FIX(8),   ZTI_NULL,       ZTI_BATCH,      ZTI_NULL },
        { ZTI_BATCH,    ZTI_FIX(5),     ZTI_FIX(16),    ZTI_FIX(5) },
-       { ZTI_PCT(100), ZTI_NULL,       ZTI_ONE,        ZTI_NULL },
+       { ZTI_FIX(8),   ZTI_NULL,       ZTI_ONE,        ZTI_NULL },
        { ZTI_ONE,      ZTI_NULL,       ZTI_ONE,        ZTI_NULL },
        { ZTI_ONE,      ZTI_NULL,       ZTI_ONE,        ZTI_NULL },
 };
@@ -1013,6 +1013,8 @@ spa_deactivate(spa_t *spa)
        list_destroy(&spa->spa_config_dirty_list);
        list_destroy(&spa->spa_state_dirty_list);
 
+       taskq_cancel_id(system_taskq, spa->spa_deadman_tqid);
+
        for (t = 0; t < ZIO_TYPES; t++) {
                for (q = 0; q < ZIO_TASKQ_TYPES; q++) {
                        if (spa->spa_zio_taskq[t][q] != NULL)
@@ -2209,7 +2211,7 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
 
        if (spa_version(spa) >= SPA_VERSION_FEATURES) {
                boolean_t missing_feat_read = B_FALSE;
-               nvlist_t *unsup_feat;
+               nvlist_t *unsup_feat, *enabled_feat;
 
                if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_READ,
                    &spa->spa_feat_for_read_obj) != 0) {
@@ -2226,27 +2228,32 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                        return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
                }
 
-               VERIFY(nvlist_alloc(&unsup_feat, NV_UNIQUE_NAME, KM_SLEEP) ==
-                   0);
+               enabled_feat = fnvlist_alloc();
+               unsup_feat = fnvlist_alloc();
 
                if (!feature_is_supported(spa->spa_meta_objset,
                    spa->spa_feat_for_read_obj, spa->spa_feat_desc_obj,
-                   unsup_feat))
+                   unsup_feat, enabled_feat))
                        missing_feat_read = B_TRUE;
 
                if (spa_writeable(spa) || state == SPA_LOAD_TRYIMPORT) {
                        if (!feature_is_supported(spa->spa_meta_objset,
                            spa->spa_feat_for_write_obj, spa->spa_feat_desc_obj,
-                           unsup_feat))
+                           unsup_feat, enabled_feat)) {
                                missing_feat_write = B_TRUE;
+                       }
                }
 
+               fnvlist_add_nvlist(spa->spa_load_info,
+                   ZPOOL_CONFIG_ENABLED_FEAT, enabled_feat);
+
                if (!nvlist_empty(unsup_feat)) {
-                       VERIFY(nvlist_add_nvlist(spa->spa_load_info,
-                           ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat) == 0);
+                       fnvlist_add_nvlist(spa->spa_load_info,
+                           ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat);
                }
 
-               nvlist_free(unsup_feat);
+               fnvlist_free(enabled_feat);
+               fnvlist_free(unsup_feat);
 
                if (!missing_feat_read) {
                        fnvlist_add_boolean(spa->spa_load_info,
@@ -5737,6 +5744,14 @@ spa_sync_config_object(spa_t *spa, dmu_tx_t *tx)
        config = spa_config_generate(spa, spa->spa_root_vdev,
            dmu_tx_get_txg(tx), B_FALSE);
 
+       /*
+        * If we're upgrading the spa version then make sure that
+        * the config object gets updated with the correct version.
+        */
+       if (spa->spa_ubsync.ub_version < spa->spa_uberblock.ub_version)
+               fnvlist_add_uint64(config, ZPOOL_CONFIG_VERSION,
+                   spa->spa_uberblock.ub_version);
+
        spa_config_exit(spa, SCL_STATE, FTAG);
 
        if (spa->spa_config_syncing)
@@ -5757,7 +5772,7 @@ spa_sync_version(void *arg1, void *arg2, dmu_tx_t *tx)
         */
        ASSERT(tx->tx_txg != TXG_INITIAL);
 
-       ASSERT(version <= SPA_VERSION);
+       ASSERT(SPA_VERSION_IS_SUPPORTED(version));
        ASSERT(version >= spa_version(spa));
 
        spa->spa_uberblock.ub_version = version;
@@ -6004,6 +6019,12 @@ 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_SLEEP, ddi_get_lbolt() +
+           NSEC_TO_TICK(spa->spa_deadman_synctime));
+
        /*
         * If we are upgrading to SPA_VERSION_RAIDZ_DEFLATE this txg,
         * set spa_deflate if we have no raid-z vdevs.
@@ -6057,7 +6078,7 @@ spa_sync(spa_t *spa, uint64_t txg)
                spa_errlog_sync(spa, txg);
                dsl_pool_sync(dp, txg);
 
-               if (pass <= SYNC_PASS_DEFERRED_FREE) {
+               if (pass < zfs_sync_pass_deferred_free) {
                        zio_t *zio = zio_root(spa, NULL, NULL, 0);
                        bplist_iterate(free_bpl, spa_free_sync_cb,
                            zio, tx);
@@ -6132,6 +6153,9 @@ spa_sync(spa_t *spa, uint64_t txg)
        }
        dmu_tx_commit(tx);
 
+       taskq_cancel_id(system_taskq, spa->spa_deadman_tqid);
+       spa->spa_deadman_tqid = 0;
+
        /*
         * Clear the dirty config list.
         */
@@ -6281,7 +6305,7 @@ spa_upgrade(spa_t *spa, uint64_t version)
         * future version would result in an unopenable pool, this shouldn't be
         * possible.
         */
-       ASSERT(spa->spa_uberblock.ub_version <= SPA_VERSION);
+       ASSERT(SPA_VERSION_IS_SUPPORTED(spa->spa_uberblock.ub_version));
        ASSERT(version >= spa->spa_uberblock.ub_version);
 
        spa->spa_uberblock.ub_version = version;