FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
/*
 * Create an uninitialized spa_t with the given name.  Requires
 * spa_namespace_lock.  The caller must ensure that the spa_t doesn't already
 * exist by calling spa_lookup() first.
 */
Create an uninitialized spa_t with the given name.
Create an uninitialized spa_t with the given name .
spa_t *
spa_add(const char *name, nvlist_t *config, const char *altroot)
{
	spa_t *spa;
	spa_config_dirent_t *dp;
#ifdef illumos
	cyc_handler_t hdlr;
	cyc_time_t when;
#endif
	ASSERT(MUTEX_HELD(&spa_namespace_lock));
	spa = kmem_zalloc(sizeof (spa_t), KM_SLEEP);
	mutex_init(&spa->spa_async_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_errlist_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_errlog_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_evicting_os_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_history_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_proc_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_props_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_cksum_tmpls_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_suspend_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&spa->spa_vdev_top_lock, NULL, MUTEX_DEFAULT, NULL);
	cv_init(&spa->spa_async_cv, NULL, CV_DEFAULT, NULL);
	cv_init(&spa->spa_evicting_os_cv, NULL, CV_DEFAULT, NULL);
	cv_init(&spa->spa_proc_cv, NULL, CV_DEFAULT, NULL);
	cv_init(&spa->spa_scrub_io_cv, NULL, CV_DEFAULT, NULL);
	cv_init(&spa->spa_suspend_cv, NULL, CV_DEFAULT, NULL);
	for (int t = 0; t < TXG_SIZE; t++)
		bplist_create(&spa->spa_free_bplist[t]);
	(void) strlcpy(spa->spa_name, name, sizeof (spa->spa_name));
	spa->spa_state = POOL_STATE_UNINITIALIZED;
	spa->spa_freeze_txg = UINT64_MAX;
	spa->spa_final_txg = UINT64_MAX;
	spa->spa_load_max_txg = UINT64_MAX;
	spa->spa_proc = &p0;
	spa->spa_proc_state = SPA_PROC_NONE;
#ifdef illumos
	hdlr.cyh_func = spa_deadman;
	hdlr.cyh_arg = spa;
	hdlr.cyh_level = CY_LOW_LEVEL;
#endif
	spa->spa_deadman_synctime = MSEC2NSEC(zfs_deadman_synctime_ms);
#ifdef illumos
	when.cyt_interval = MSEC2NSEC(zfs_deadman_checktime_ms);
	when.cyt_when = CY_INFINITY;
	mutex_enter(&cpu_lock);
	spa->spa_deadman_cycid = cyclic_add(&hdlr, &when);
	mutex_exit(&cpu_lock);
#else	
#ifdef _KERNEL
	callout_init(&spa->spa_deadman_cycid, 1);
#endif
#endif
	refcount_create(&spa->spa_refcount);
	spa_config_lock_init(spa);
	avl_add(&spa_namespace_avl, spa);
	if (altroot) {
		spa->spa_root = spa_strdup(altroot);
		spa_active_count++;
	}
	list_create(&spa->spa_config_list, sizeof (spa_config_dirent_t),
	    offsetof(spa_config_dirent_t, scd_link));
	dp = kmem_zalloc(sizeof (spa_config_dirent_t), KM_SLEEP);
	dp->scd_path = altroot ? NULL : spa_strdup(spa_config_path);
	list_insert_head(&spa->spa_config_list, dp);
	VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME,
	    KM_SLEEP) == 0);
	if (config != NULL) {
		nvlist_t *features;
		if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ,
		    &features) == 0) {
			VERIFY(nvlist_dup(features, &spa->spa_label_features,
			    0) == 0);
		}
		VERIFY(nvlist_dup(config, &spa->spa_config, 0) == 0);
	}
	if (spa->spa_label_features == NULL) {
		VERIFY(nvlist_alloc(&spa->spa_label_features, NV_UNIQUE_NAME,
		    KM_SLEEP) == 0);
	}
	spa->spa_debug = ((zfs_flags & ZFS_DEBUG_SPA) != 0);
	spa->spa_min_ashift = INT_MAX;
	spa->spa_max_ashift = 0;
	for (int i = 0; i < SPA_FEATURES; i++) {
		spa->spa_feat_refcount_cache[i] = SPA_FEATURE_DISABLED;
	}
	return (spa);
}
spa_t * spa_add ( const char * name , nvlist_t * config , const char * altroot ) { spa_t * spa ; spa_config_dirent_t * dp ; #ifdef illumos cyc_handler_t hdlr ; cyc_time_t when ; #endif ASSERT ( MUTEX_HELD ( & spa_namespace_lock ) ) ; spa = kmem_zalloc ( sizeof ( spa_t ) , KM_SLEEP ) ; mutex_init ( & spa -> spa_async_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_errlist_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_errlog_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_evicting_os_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_history_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_proc_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_props_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_cksum_tmpls_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_scrub_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_suspend_lock , NULL , MUTEX_DEFAULT , NULL ) ; mutex_init ( & spa -> spa_vdev_top_lock , NULL , MUTEX_DEFAULT , NULL ) ; cv_init ( & spa -> spa_async_cv , NULL , CV_DEFAULT , NULL ) ; cv_init ( & spa -> spa_evicting_os_cv , NULL , CV_DEFAULT , NULL ) ; cv_init ( & spa -> spa_proc_cv , NULL , CV_DEFAULT , NULL ) ; cv_init ( & spa -> spa_scrub_io_cv , NULL , CV_DEFAULT , NULL ) ; cv_init ( & spa -> spa_suspend_cv , NULL , CV_DEFAULT , NULL ) ; for ( int t = 0 ; t < TXG_SIZE ; t ++ ) bplist_create ( & spa -> spa_free_bplist [ t ] ) ; ( void ) strlcpy ( spa -> spa_name , name , sizeof ( spa -> spa_name ) ) ; spa -> spa_state = POOL_STATE_UNINITIALIZED ; spa -> spa_freeze_txg = UINT64_MAX ; spa -> spa_final_txg = UINT64_MAX ; spa -> spa_load_max_txg = UINT64_MAX ; spa -> spa_proc = & p0 ; spa -> spa_proc_state = SPA_PROC_NONE ; #ifdef illumos hdlr . cyh_func = spa_deadman ; hdlr . cyh_arg = spa ; hdlr . cyh_level = CY_LOW_LEVEL ; #endif spa -> spa_deadman_synctime = MSEC2NSEC ( zfs_deadman_synctime_ms ) ; #ifdef illumos when . cyt_interval = MSEC2NSEC ( zfs_deadman_checktime_ms ) ; when . cyt_when = CY_INFINITY ; mutex_enter ( & cpu_lock ) ; spa -> spa_deadman_cycid = cyclic_add ( & hdlr , & when ) ; mutex_exit ( & cpu_lock ) ; #else #ifdef _KERNEL callout_init ( & spa -> spa_deadman_cycid , 1 ) ; #endif #endif refcount_create ( & spa -> spa_refcount ) ; spa_config_lock_init ( spa ) ; avl_add ( & spa_namespace_avl , spa ) ; if ( altroot ) { spa -> spa_root = spa_strdup ( altroot ) ; spa_active_count ++ ; } list_create ( & spa -> spa_config_list , sizeof ( spa_config_dirent_t ) , offsetof ( spa_config_dirent_t , scd_link ) ) ; dp = kmem_zalloc ( sizeof ( spa_config_dirent_t ) , KM_SLEEP ) ; dp -> scd_path = altroot ? NULL : spa_strdup ( spa_config_path ) ; list_insert_head ( & spa -> spa_config_list , dp ) ; VERIFY ( nvlist_alloc ( & spa -> spa_load_info , NV_UNIQUE_NAME , KM_SLEEP ) == 0 ) ; if ( config != NULL ) { nvlist_t * features ; if ( nvlist_lookup_nvlist ( config , ZPOOL_CONFIG_FEATURES_FOR_READ , & features ) == 0 ) { VERIFY ( nvlist_dup ( features , & spa -> spa_label_features , 0 ) == 0 ) ; } VERIFY ( nvlist_dup ( config , & spa -> spa_config , 0 ) == 0 ) ; } if ( spa -> spa_label_features == NULL ) { VERIFY ( nvlist_alloc ( & spa -> spa_label_features , NV_UNIQUE_NAME , KM_SLEEP ) == 0 ) ; } spa -> spa_debug = ( ( zfs_flags & ZFS_DEBUG_SPA ) != 0 ) ; spa -> spa_min_ashift = INT_MAX ; spa -> spa_max_ashift = 0 ; for ( int i = 0 ; i < SPA_FEATURES ; i ++ ) { spa -> spa_feat_refcount_cache [ i ] = SPA_FEATURE_DISABLED ; } return ( spa ) ; }
Create an uninitialized spa_t with the given name.
Create an uninitialized spa_t with the given name .
/*
	 * This determines how often we need to check for hung I/Os after
	 * the cyclic has already fired. Since checking for hung I/Os is
	 * an expensive operation we don't want to check too frequently.
	 * Instead wait for 5 seconds before checking again.
	 */ /* !illumos */ /*
	 * Set the alternate root, if there is one.
	 */ /*
	 * Every pool starts with the default cachefile
	 */ /*
	 * As a pool is being created, treat all features as disabled by
	 * setting SPA_FEATURE_DISABLED for all entries in the feature
	 * refcount cache.
	 */