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>

@@ -756,11 +756,11 @@
 {
         ASSERT(dmu_tx_is_syncing(tx));
         ASSERT(dp->dp_origin_snap != NULL);
 
         VERIFY0(dmu_objset_find_dp(dp, dp->dp_root_dir_obj, upgrade_clones_cb,
-            tx, DS_FIND_CHILDREN));
+            tx, DS_FIND_CHILDREN | DS_FIND_SERIALIZE));
 }
 
 /* ARGSUSED */
 static int
 upgrade_dir_clones_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)

@@ -810,11 +810,11 @@
         VERIFY0(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
             DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx));
         VERIFY0(bpobj_open(&dp->dp_free_bpobj, dp->dp_meta_objset, obj));
 
         VERIFY0(dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
-            upgrade_dir_clones_cb, tx, DS_FIND_CHILDREN));
+            upgrade_dir_clones_cb, tx, DS_FIND_CHILDREN | DS_FIND_SERIALIZE));
 }
 
 void
 dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx)
 {

@@ -1054,5 +1054,11 @@
 boolean_t
 dsl_pool_config_held(dsl_pool_t *dp)
 {
         return (RRW_LOCK_HELD(&dp->dp_config_rwlock));
 }
+
+boolean_t
+dsl_pool_config_held_writer(dsl_pool_t *dp)
+{
+        return (RRW_WRITE_HELD(&dp->dp_config_rwlock));
+}