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.

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/spa.c
          +++ new/usr/src/uts/common/fs/zfs/spa.c
↓ open down ↓ 1704 lines elided ↑ open up ↑
1705 1705          return (rvd->vdev_guid_sum == spa->spa_uberblock.ub_guid_sum);
1706 1706  }
1707 1707  
1708 1708  /*
1709 1709   * Check for missing log devices
1710 1710   */
1711 1711  static boolean_t
1712 1712  spa_check_logs(spa_t *spa)
1713 1713  {
1714 1714          boolean_t rv = B_FALSE;
     1715 +        dsl_pool_t *dp = spa_get_dsl(spa);
1715 1716  
1716 1717          switch (spa->spa_log_state) {
1717 1718          case SPA_LOG_MISSING:
1718 1719                  /* need to recheck in case slog has been restored */
1719 1720          case SPA_LOG_UNKNOWN:
1720      -                rv = (dmu_objset_find(spa->spa_name, zil_check_log_chain,
1721      -                    NULL, DS_FIND_CHILDREN) != 0);
     1721 +                rv = (dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
     1722 +                    zil_check_log_chain, NULL, DS_FIND_CHILDREN) != 0);
1722 1723                  if (rv)
1723 1724                          spa_set_log_state(spa, SPA_LOG_MISSING);
1724 1725                  break;
1725 1726          }
1726 1727          return (rv);
1727 1728  }
1728 1729  
1729 1730  static boolean_t
1730 1731  spa_passivate_log(spa_t *spa)
1731 1732  {
↓ open down ↓ 353 lines elided ↑ open up ↑
2085 2086          int error = 0;
2086 2087          nvlist_t *nvroot = NULL;
2087 2088          nvlist_t *label;
2088 2089          vdev_t *rvd;
2089 2090          uberblock_t *ub = &spa->spa_uberblock;
2090 2091          uint64_t children, config_cache_txg = spa->spa_config_txg;
2091 2092          int orig_mode = spa->spa_mode;
2092 2093          int parse;
2093 2094          uint64_t obj;
2094 2095          boolean_t missing_feat_write = B_FALSE;
2095      -
2096 2096          /*
2097 2097           * If this is an untrusted config, access the pool in read-only mode.
2098 2098           * This prevents things like resilvering recently removed devices.
2099 2099           */
2100 2100          if (!mosconfig)
2101 2101                  spa->spa_mode = FREAD;
2102 2102  
2103 2103          ASSERT(MUTEX_HELD(&spa_namespace_lock));
2104 2104  
2105 2105          spa->spa_load_state = state;
↓ open down ↓ 533 lines elided ↑ open up ↑
2639 2639          if (state != SPA_LOAD_TRYIMPORT) {
2640 2640                  if (error = spa_load_verify(spa))
2641 2641                          return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA,
2642 2642                              error));
2643 2643          }
2644 2644  
2645 2645          if (spa_writeable(spa) && (state == SPA_LOAD_RECOVER ||
2646 2646              spa->spa_load_max_txg == UINT64_MAX)) {
2647 2647                  dmu_tx_t *tx;
2648 2648                  int need_update = B_FALSE;
     2649 +                dsl_pool_t *dp = spa_get_dsl(spa);
2649 2650  
2650 2651                  ASSERT(state != SPA_LOAD_TRYIMPORT);
2651 2652  
2652 2653                  /*
2653 2654                   * Claim log blocks that haven't been committed yet.
2654 2655                   * This must all happen in a single txg.
2655 2656                   * Note: spa_claim_max_txg is updated by spa_claim_notify(),
2656 2657                   * invoked from zil_claim_log_block()'s i/o done callback.
2657 2658                   * Price of rollback is that we abandon the log.
2658 2659                   */
2659 2660                  spa->spa_claiming = B_TRUE;
2660 2661  
2661      -                tx = dmu_tx_create_assigned(spa_get_dsl(spa),
2662      -                    spa_first_txg(spa));
2663      -                (void) dmu_objset_find(spa_name(spa),
     2662 +                tx = dmu_tx_create_assigned(dp, spa_first_txg(spa));
     2663 +                (void) dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
2664 2664                      zil_claim, tx, DS_FIND_CHILDREN);
2665 2665                  dmu_tx_commit(tx);
2666 2666  
2667 2667                  spa->spa_claiming = B_FALSE;
2668 2668  
2669 2669                  spa_set_log_state(spa, SPA_LOG_GOOD);
2670 2670                  spa->spa_sync_on = B_TRUE;
2671 2671                  txg_sync_start(spa->spa_dsl_pool);
2672 2672  
2673 2673                  /*
↓ open down ↓ 3875 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX