/*
* 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);
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
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