Print this page
5269 zfs: zpool import slow
While importing a pool all objsets are enumerated twice, once to check
the zil log chains and once to claim them. On pools with many datasets
this process might take a substantial amount of time.
Speed up the process by parallelizing it utilizing a taskq. The number
of parallel tasks is limited to 4 times the number of leaf vdevs.

@@ -1710,17 +1710,18 @@
  */
 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) {
         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;
         }
         return (rv);

@@ -2090,11 +2091,10 @@
         uint64_t children, config_cache_txg = spa->spa_config_txg;
         int orig_mode = spa->spa_mode;
         int parse;
         uint64_t obj;
         boolean_t missing_feat_write = B_FALSE;
-
         /*
          * If this is an untrusted config, access the pool in read-only mode.
          * This prevents things like resilvering recently removed devices.
          */
         if (!mosconfig)

@@ -2644,10 +2644,11 @@
 
         if (spa_writeable(spa) && (state == SPA_LOAD_RECOVER ||
             spa->spa_load_max_txg == UINT64_MAX)) {
                 dmu_tx_t *tx;
                 int need_update = B_FALSE;
+                dsl_pool_t *dp = spa_get_dsl(spa);
 
                 ASSERT(state != SPA_LOAD_TRYIMPORT);
 
                 /*
                  * Claim log blocks that haven't been committed yet.

@@ -2656,13 +2657,12 @@
                  * invoked from zil_claim_log_block()'s i/o done callback.
                  * Price of rollback is that we abandon the log.
                  */
                 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);
 
                 spa->spa_claiming = B_FALSE;