Illumos #2762: zpool command should have better support for feature flags
[zfs.git] / module / zfs / dsl_dir.c
index 224cc0a..377df40 100644 (file)
@@ -96,7 +96,7 @@ dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj,
        if (dd == NULL) {
                dsl_dir_t *winner;
 
-               dd = kmem_zalloc(sizeof (dsl_dir_t), KM_SLEEP);
+               dd = kmem_zalloc(sizeof (dsl_dir_t), KM_PUSHPAGE);
                dd->dd_object = ddobj;
                dd->dd_dbuf = dbuf;
                dd->dd_pool = dp;
@@ -460,12 +460,14 @@ dsl_dir_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx)
        /*
         * There should be exactly two holds, both from
         * dsl_dataset_destroy: one on the dd directory, and one on its
-        * head ds.  Otherwise, someone is trying to lookup something
-        * inside this dir while we want to destroy it.  The
-        * config_rwlock ensures that nobody else opens it after we
-        * check.
+        * head ds.  If there are more holds, then a concurrent thread is
+        * performing a lookup inside this dir while we're trying to destroy
+        * it.  To minimize this possibility, we perform this check only
+        * in syncing context and fail the operation if we encounter
+        * additional holds.  The dp_config_rwlock ensures that nobody else
+        * opens it after we check.
         */
-       if (dmu_buf_refcount(dd->dd_dbuf) > 2)
+       if (dmu_tx_is_syncing(tx) && dmu_buf_refcount(dd->dd_dbuf) > 2)
                return (EBUSY);
 
        err = zap_count(mos, dd->dd_phys->dd_child_dir_zapobj, &count);
@@ -791,7 +793,7 @@ dsl_dir_tempreserve_impl(dsl_dir_t *dd, uint64_t asize, boolean_t netfree,
            asize - ref_rsrv);
        mutex_exit(&dd->dd_lock);
 
-       tr = kmem_zalloc(sizeof (struct tempreserve), KM_SLEEP);
+       tr = kmem_zalloc(sizeof (struct tempreserve), KM_PUSHPAGE);
        tr->tr_ds = dd;
        tr->tr_size = asize;
        list_insert_tail(tr_list, tr);
@@ -825,7 +827,7 @@ dsl_dir_tempreserve_space(dsl_dir_t *dd, uint64_t lsize, uint64_t asize,
                return (0);
        }
 
-       tr_list = kmem_alloc(sizeof (list_t), KM_SLEEP);
+       tr_list = kmem_alloc(sizeof (list_t), KM_PUSHPAGE);
        list_create(tr_list, sizeof (struct tempreserve),
            offsetof(struct tempreserve, tr_node));
        ASSERT3S(asize, >, 0);
@@ -835,7 +837,7 @@ dsl_dir_tempreserve_space(dsl_dir_t *dd, uint64_t lsize, uint64_t asize,
        if (err == 0) {
                struct tempreserve *tr;
 
-               tr = kmem_zalloc(sizeof (struct tempreserve), KM_SLEEP);
+               tr = kmem_zalloc(sizeof (struct tempreserve), KM_PUSHPAGE);
                tr->tr_size = lsize;
                list_insert_tail(tr_list, tr);
 
@@ -851,7 +853,7 @@ dsl_dir_tempreserve_space(dsl_dir_t *dd, uint64_t lsize, uint64_t asize,
        if (err == 0) {
                struct tempreserve *tr;
 
-               tr = kmem_zalloc(sizeof (struct tempreserve), KM_SLEEP);
+               tr = kmem_zalloc(sizeof (struct tempreserve), KM_PUSHPAGE);
                tr->tr_dp = dd->dd_pool;
                tr->tr_size = asize;
                list_insert_tail(tr_list, tr);
@@ -1064,10 +1066,6 @@ dsl_dir_set_quota_sync(void *arg1, void *arg2, dmu_tx_t *tx)
        mutex_enter(&dd->dd_lock);
        dd->dd_phys->dd_quota = effective_value;
        mutex_exit(&dd->dd_lock);
-
-       spa_history_log_internal(LOG_DS_QUOTA, dd->dd_pool->dp_spa,
-           tx, "%lld dataset = %llu ",
-           (longlong_t)effective_value, dd->dd_phys->dd_head_dataset_obj);
 }
 
 int
@@ -1180,10 +1178,6 @@ dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
                    delta, 0, 0, tx);
        }
        mutex_exit(&dd->dd_lock);
-
-       spa_history_log_internal(LOG_DS_RESERVATION, dd->dd_pool->dp_spa,
-           tx, "%lld dataset = %llu",
-           (longlong_t)effective_value, dd->dd_phys->dd_head_dataset_obj);
 }
 
 int