4566 }
4567
4568 /*
4569 * Pool Creation
4570 */
4571 int
4572 spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
4573 nvlist_t *zplprops)
4574 {
4575 spa_t *spa;
4576 char *altroot = NULL;
4577 vdev_t *rvd;
4578 dsl_pool_t *dp;
4579 dmu_tx_t *tx;
4580 int error = 0;
4581 uint64_t txg = TXG_INITIAL;
4582 nvlist_t **spares, **l2cache;
4583 uint_t nspares, nl2cache;
4584 uint64_t version, obj;
4585 boolean_t has_features;
4586
4587 /*
4588 * If this pool already exists, return failure.
4589 */
4590 mutex_enter(&spa_namespace_lock);
4591 if (spa_lookup(pool) != NULL) {
4592 mutex_exit(&spa_namespace_lock);
4593 return (SET_ERROR(EEXIST));
4594 }
4595
4596 /*
4597 * Allocate a new spa_t structure.
4598 */
4599 (void) nvlist_lookup_string(props,
4600 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
4601 spa = spa_add(pool, NULL, altroot);
4602 spa_activate(spa, spa_mode_global);
4603
4604 if (props && (error = spa_prop_validate(spa, props))) {
4605 spa_deactivate(spa);
4606 spa_remove(spa);
4607 mutex_exit(&spa_namespace_lock);
4608 return (error);
4609 }
4610
4611 has_features = B_FALSE;
4612 for (nvpair_t *elem = nvlist_next_nvpair(props, NULL);
4613 elem != NULL; elem = nvlist_next_nvpair(props, elem)) {
4614 if (zpool_prop_feature(nvpair_name(elem)))
4615 has_features = B_TRUE;
4616 }
4617
4618 if (has_features || nvlist_lookup_uint64(props,
4619 zpool_prop_to_name(ZPOOL_PROP_VERSION), &version) != 0) {
4620 version = SPA_VERSION;
4621 }
4622 ASSERT(SPA_VERSION_IS_SUPPORTED(version));
4623
4624 spa->spa_first_txg = txg;
4625 spa->spa_uberblock.ub_txg = txg - 1;
4626 spa->spa_uberblock.ub_version = version;
4627 spa->spa_ubsync = spa->spa_uberblock;
4628 spa->spa_load_state = SPA_LOAD_CREATE;
4629 spa->spa_removing_phys.sr_state = DSS_NONE;
4630 spa->spa_removing_phys.sr_removing_vdev = -1;
|
4566 }
4567
4568 /*
4569 * Pool Creation
4570 */
4571 int
4572 spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
4573 nvlist_t *zplprops)
4574 {
4575 spa_t *spa;
4576 char *altroot = NULL;
4577 vdev_t *rvd;
4578 dsl_pool_t *dp;
4579 dmu_tx_t *tx;
4580 int error = 0;
4581 uint64_t txg = TXG_INITIAL;
4582 nvlist_t **spares, **l2cache;
4583 uint_t nspares, nl2cache;
4584 uint64_t version, obj;
4585 boolean_t has_features;
4586 char *poolname;
4587 nvlist_t *nvl;
4588
4589 if (nvlist_lookup_string(props,
4590 zpool_prop_to_name(ZPOOL_PROP_TNAME), &poolname) != 0)
4591 poolname = (char *)pool;
4592
4593 /*
4594 * If this pool already exists, return failure.
4595 */
4596 mutex_enter(&spa_namespace_lock);
4597 if (spa_lookup(poolname) != NULL) {
4598 mutex_exit(&spa_namespace_lock);
4599 return (SET_ERROR(EEXIST));
4600 }
4601
4602 /*
4603 * Allocate a new spa_t structure.
4604 */
4605 nvl = fnvlist_alloc();
4606 fnvlist_add_string(nvl, ZPOOL_CONFIG_POOL_NAME, pool);
4607 (void) nvlist_lookup_string(props,
4608 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
4609 spa = spa_add(poolname, nvl, altroot);
4610 fnvlist_free(nvl);
4611 spa_activate(spa, spa_mode_global);
4612
4613 if (props && (error = spa_prop_validate(spa, props))) {
4614 spa_deactivate(spa);
4615 spa_remove(spa);
4616 mutex_exit(&spa_namespace_lock);
4617 return (error);
4618 }
4619
4620 /*
4621 * Temporary pool names should never be written to disk.
4622 */
4623 if (poolname != pool)
4624 spa->spa_import_flags |= ZFS_IMPORT_TEMP_NAME;
4625
4626 has_features = B_FALSE;
4627 for (nvpair_t *elem = nvlist_next_nvpair(props, NULL);
4628 elem != NULL; elem = nvlist_next_nvpair(props, elem)) {
4629 if (zpool_prop_feature(nvpair_name(elem)))
4630 has_features = B_TRUE;
4631 }
4632
4633 if (has_features || nvlist_lookup_uint64(props,
4634 zpool_prop_to_name(ZPOOL_PROP_VERSION), &version) != 0) {
4635 version = SPA_VERSION;
4636 }
4637 ASSERT(SPA_VERSION_IS_SUPPORTED(version));
4638
4639 spa->spa_first_txg = txg;
4640 spa->spa_uberblock.ub_txg = txg - 1;
4641 spa->spa_uberblock.ub_version = version;
4642 spa->spa_ubsync = spa->spa_uberblock;
4643 spa->spa_load_state = SPA_LOAD_CREATE;
4644 spa->spa_removing_phys.sr_state = DSS_NONE;
4645 spa->spa_removing_phys.sr_removing_vdev = -1;
|