Print this page
5269 zfs: zpool import slow
PORTING: this code relies on the property of taskq_wait to wait
until no more tasks are queued and no more tasks are active. As
we always queue new tasks from within other tasks, task_wait
reliably waits for the full recursion to finish, even though we
enqueue new tasks after taskq_wait has been called.
On platforms other than illumos, taskq_wait may not have this
property.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: George Wilson <george.wilson@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/dsl_pool.c
          +++ new/usr/src/uts/common/fs/zfs/dsl_pool.c
↓ open down ↓ 750 lines elided ↑ open up ↑
 751  751          return (0);
 752  752  }
 753  753  
 754  754  void
 755  755  dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx)
 756  756  {
 757  757          ASSERT(dmu_tx_is_syncing(tx));
 758  758          ASSERT(dp->dp_origin_snap != NULL);
 759  759  
 760  760          VERIFY0(dmu_objset_find_dp(dp, dp->dp_root_dir_obj, upgrade_clones_cb,
 761      -            tx, DS_FIND_CHILDREN));
      761 +            tx, DS_FIND_CHILDREN | DS_FIND_SERIALIZE));
 762  762  }
 763  763  
 764  764  /* ARGSUSED */
 765  765  static int
 766  766  upgrade_dir_clones_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
 767  767  {
 768  768          dmu_tx_t *tx = arg;
 769  769          objset_t *mos = dp->dp_meta_objset;
 770  770  
 771  771          if (dsl_dir_phys(ds->ds_dir)->dd_origin_obj != 0) {
↓ open down ↓ 33 lines elided ↑ open up ↑
 805  805           * returns the old version, and we need a new-version bpobj with
 806  806           * subobj support.  So call dmu_object_alloc() directly.
 807  807           */
 808  808          obj = dmu_object_alloc(dp->dp_meta_objset, DMU_OT_BPOBJ,
 809  809              SPA_OLD_MAXBLOCKSIZE, DMU_OT_BPOBJ_HDR, sizeof (bpobj_phys_t), tx);
 810  810          VERIFY0(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
 811  811              DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx));
 812  812          VERIFY0(bpobj_open(&dp->dp_free_bpobj, dp->dp_meta_objset, obj));
 813  813  
 814  814          VERIFY0(dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
 815      -            upgrade_dir_clones_cb, tx, DS_FIND_CHILDREN));
      815 +            upgrade_dir_clones_cb, tx, DS_FIND_CHILDREN | DS_FIND_SERIALIZE));
 816  816  }
 817  817  
 818  818  void
 819  819  dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx)
 820  820  {
 821  821          uint64_t dsobj;
 822  822          dsl_dataset_t *ds;
 823  823  
 824  824          ASSERT(dmu_tx_is_syncing(tx));
 825  825          ASSERT(dp->dp_origin_snap == NULL);
↓ open down ↓ 223 lines elided ↑ open up ↑
1049 1049  dsl_pool_config_exit(dsl_pool_t *dp, void *tag)
1050 1050  {
1051 1051          rrw_exit(&dp->dp_config_rwlock, tag);
1052 1052  }
1053 1053  
1054 1054  boolean_t
1055 1055  dsl_pool_config_held(dsl_pool_t *dp)
1056 1056  {
1057 1057          return (RRW_LOCK_HELD(&dp->dp_config_rwlock));
1058 1058  }
     1059 +
     1060 +boolean_t
     1061 +dsl_pool_config_held_writer(dsl_pool_t *dp)
     1062 +{
     1063 +        return (RRW_WRITE_HELD(&dp->dp_config_rwlock));
     1064 +}
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX