spa.c revision 2f8aaab38e6371ad39ed90a1211ba8921acbb4d5
1fa9e406ahrens/* 2fa9e406ahrens * CDDL HEADER START 3fa9e406ahrens * 4fa9e406ahrens * The contents of this file are subject to the terms of the 5ea8dc4beschrock * Common Development and Distribution License (the "License"). 6ea8dc4beschrock * You may not use this file except in compliance with the License. 7fa9e406ahrens * 8fa9e406ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fa9e406ahrens * or http://www.opensolaris.org/os/licensing. 10fa9e406ahrens * See the License for the specific language governing permissions 11fa9e406ahrens * and limitations under the License. 12fa9e406ahrens * 13fa9e406ahrens * When distributing Covered Code, include this CDDL HEADER in each 14fa9e406ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fa9e406ahrens * If applicable, add the following below this CDDL HEADER, with the 16fa9e406ahrens * fields enclosed by brackets "[]" replaced with your own identifying 17fa9e406ahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18fa9e406ahrens * 19fa9e406ahrens * CDDL HEADER END 20fa9e406ahrens */ 2199653d4eschrock 22fa9e406ahrens/* 2339c2341eschrock * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24fa9e406ahrens * Use is subject to license terms. 25fa9e406ahrens */ 26fa9e406ahrens 27fa9e406ahrens#pragma ident "%Z%%M% %I% %E% SMI" 28fa9e406ahrens 29fa9e406ahrens/* 30fa9e406ahrens * This file contains all the routines used when modifying on-disk SPA state. 31fa9e406ahrens * This includes opening, importing, destroying, exporting a pool, and syncing a 32fa9e406ahrens * pool. 33fa9e406ahrens */ 34fa9e406ahrens 35fa9e406ahrens#include <sys/zfs_context.h> 36ea8dc4beschrock#include <sys/fm/fs/zfs.h> 37fa9e406ahrens#include <sys/spa_impl.h> 38fa9e406ahrens#include <sys/zio.h> 39fa9e406ahrens#include <sys/zio_checksum.h> 40fa9e406ahrens#include <sys/zio_compress.h> 41fa9e406ahrens#include <sys/dmu.h> 42fa9e406ahrens#include <sys/dmu_tx.h> 43fa9e406ahrens#include <sys/zap.h> 44fa9e406ahrens#include <sys/zil.h> 45fa9e406ahrens#include <sys/vdev_impl.h> 46fa9e406ahrens#include <sys/metaslab.h> 47fa9e406ahrens#include <sys/uberblock_impl.h> 48fa9e406ahrens#include <sys/txg.h> 49fa9e406ahrens#include <sys/avl.h> 50fa9e406ahrens#include <sys/dmu_traverse.h> 51b1b8ab3lling#include <sys/dmu_objset.h> 52fa9e406ahrens#include <sys/unique.h> 53fa9e406ahrens#include <sys/dsl_pool.h> 54b1b8ab3lling#include <sys/dsl_dataset.h> 55fa9e406ahrens#include <sys/dsl_dir.h> 56fa9e406ahrens#include <sys/dsl_prop.h> 57b1b8ab3lling#include <sys/dsl_synctask.h> 58fa9e406ahrens#include <sys/fs/zfs.h> 59fa9e406ahrens#include <sys/callb.h> 609517395ek#include <sys/systeminfo.h> 619517395ek#include <sys/sunddi.h> 62fa9e406ahrens 63990b485lling#include "zfs_prop.h" 64990b485lling 65416e0cdekint zio_taskq_threads = 8; 66416e0cdek 67990b485llingstatic void spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx); 68990b485lling 69990b485lling/* 70990b485lling * ========================================================================== 71990b485lling * SPA properties routines 72990b485lling * ========================================================================== 73990b485lling */ 74990b485lling 75990b485lling/* 76990b485lling * Add a (source=src, propname=propval) list to an nvlist. 77990b485lling */ 78990b485llingstatic int 79990b485llingspa_prop_add_list(nvlist_t *nvl, zpool_prop_t prop, char *strval, 80990b485lling uint64_t intval, zprop_source_t src) 81990b485lling{ 82990b485lling const char *propname = zpool_prop_to_name(prop); 83990b485lling nvlist_t *propval; 84990b485lling int err = 0; 85990b485lling 86990b485lling if (err = nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP)) 87990b485lling return (err); 88990b485lling 89990b485lling if (err = nvlist_add_uint64(propval, ZPROP_SOURCE, src)) 90990b485lling goto out; 91990b485lling 92990b485lling if (strval != NULL) { 93990b485lling if (err = nvlist_add_string(propval, ZPROP_VALUE, strval)) 94990b485lling goto out; 95990b485lling } else { 96990b485lling if (err = nvlist_add_uint64(propval, ZPROP_VALUE, intval)) 97990b485lling goto out; 98990b485lling } 99990b485lling 100990b485lling err = nvlist_add_nvlist(nvl, propname, propval); 101990b485llingout: 102990b485lling nvlist_free(propval); 103990b485lling return (err); 104990b485lling} 105990b485lling 106990b485lling/* 107990b485lling * Get property values from the spa configuration. 108990b485lling */ 109990b485llingstatic int 110990b485llingspa_prop_get_config(spa_t *spa, nvlist_t **nvp) 111990b485lling{ 112990b485lling uint64_t size = spa_get_space(spa); 113990b485lling uint64_t used = spa_get_alloc(spa); 114990b485lling uint64_t cap, version; 115990b485lling zprop_source_t src = ZPROP_SRC_NONE; 116990b485lling int err; 1172f8aaabeschrock char *cachefile; 1182f8aaabeschrock size_t len; 119990b485lling 120990b485lling /* 121990b485lling * readonly properties 122990b485lling */ 123990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa->spa_name, 124990b485lling 0, src)) 125990b485lling return (err); 126990b485lling 127990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src)) 128990b485lling return (err); 129990b485lling 130990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_USED, NULL, used, src)) 131990b485lling return (err); 132990b485lling 133990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_AVAILABLE, NULL, 134990b485lling size - used, src)) 135990b485lling return (err); 136990b485lling 137990b485lling cap = (size == 0) ? 0 : (used * 100 / size); 138990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_CAPACITY, NULL, cap, src)) 139990b485lling return (err); 140990b485lling 141990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, 142990b485lling spa_guid(spa), src)) 143990b485lling return (err); 144990b485lling 145990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL, 146990b485lling spa->spa_root_vdev->vdev_state, src)) 147990b485lling return (err); 148990b485lling 149990b485lling /* 150990b485lling * settable properties that are not stored in the pool property object. 151990b485lling */ 152990b485lling version = spa_version(spa); 153990b485lling if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION)) 154990b485lling src = ZPROP_SRC_DEFAULT; 155990b485lling else 156990b485lling src = ZPROP_SRC_LOCAL; 157990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, 158990b485lling version, src)) 159990b485lling return (err); 160990b485lling 161990b485lling if (spa->spa_root != NULL) { 162990b485lling src = ZPROP_SRC_LOCAL; 163990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, 164990b485lling spa->spa_root, 0, src)) 165990b485lling return (err); 166990b485lling } 167990b485lling 1682f8aaabeschrock if (spa->spa_config_dir != NULL) { 1692f8aaabeschrock if (strcmp(spa->spa_config_dir, "none") == 0) { 1702f8aaabeschrock err = spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE, 1712f8aaabeschrock spa->spa_config_dir, 0, ZPROP_SRC_LOCAL); 1722f8aaabeschrock } else { 1732f8aaabeschrock len = strlen(spa->spa_config_dir) + 1742f8aaabeschrock strlen(spa->spa_config_file) + 2; 1752f8aaabeschrock cachefile = kmem_alloc(len, KM_SLEEP); 1762f8aaabeschrock (void) snprintf(cachefile, len, "%s/%s", 1772f8aaabeschrock spa->spa_config_dir, spa->spa_config_file); 1782f8aaabeschrock err = spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE, 1792f8aaabeschrock cachefile, 0, ZPROP_SRC_LOCAL); 1802f8aaabeschrock kmem_free(cachefile, len); 1812f8aaabeschrock } 1822f8aaabeschrock 1832f8aaabeschrock if (err) 1842f8aaabeschrock return (err); 1852f8aaabeschrock } 186990b485lling 187990b485lling return (0); 188990b485lling} 189990b485lling 190990b485lling/* 191990b485lling * Get zpool property values. 192990b485lling */ 193990b485llingint 194990b485llingspa_prop_get(spa_t *spa, nvlist_t **nvp) 195990b485lling{ 196990b485lling zap_cursor_t zc; 197990b485lling zap_attribute_t za; 198990b485lling objset_t *mos = spa->spa_meta_objset; 199990b485lling int err; 200990b485lling 201990b485lling if (err = nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP)) 202990b485lling return (err); 203990b485lling 204990b485lling /* 205990b485lling * Get properties from the spa config. 206990b485lling */ 207990b485lling if (err = spa_prop_get_config(spa, nvp)) 208990b485lling goto out; 209990b485lling 210990b485lling mutex_enter(&spa->spa_props_lock); 211990b485lling /* If no pool property object, no more prop to get. */ 212990b485lling if (spa->spa_pool_props_object == 0) { 213990b485lling mutex_exit(&spa->spa_props_lock); 214990b485lling return (0); 215990b485lling } 216990b485lling 217990b485lling /* 218990b485lling * Get properties from the MOS pool property object. 219990b485lling */ 220990b485lling for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object); 221990b485lling (err = zap_cursor_retrieve(&zc, &za)) == 0; 222990b485lling zap_cursor_advance(&zc)) { 223990b485lling uint64_t intval = 0; 224990b485lling char *strval = NULL; 225990b485lling zprop_source_t src = ZPROP_SRC_DEFAULT; 226990b485lling zpool_prop_t prop; 227990b485lling 228990b485lling if ((prop = zpool_name_to_prop(za.za_name)) == ZPROP_INVAL) 229990b485lling continue; 230990b485lling 231990b485lling switch (za.za_integer_length) { 232990b485lling case 8: 233990b485lling /* integer property */ 234990b485lling if (za.za_first_integer != 235990b485lling zpool_prop_default_numeric(prop)) 236990b485lling src = ZPROP_SRC_LOCAL; 237990b485lling 238990b485lling if (prop == ZPOOL_PROP_BOOTFS) { 239990b485lling dsl_pool_t *dp; 240990b485lling dsl_dataset_t *ds = NULL; 241990b485lling 242990b485lling dp = spa_get_dsl(spa); 243990b485lling rw_enter(&dp->dp_config_rwlock, RW_READER); 244990b485lling if (err = dsl_dataset_open_obj(dp, 245990b485lling za.za_first_integer, NULL, DS_MODE_NONE, 246990b485lling FTAG, &ds)) { 247990b485lling rw_exit(&dp->dp_config_rwlock); 248990b485lling break; 249990b485lling } 250990b485lling 251990b485lling strval = kmem_alloc( 252990b485lling MAXNAMELEN + strlen(MOS_DIR_NAME) + 1, 253990b485lling KM_SLEEP); 254990b485lling dsl_dataset_name(ds, strval); 255990b485lling dsl_dataset_close(ds, DS_MODE_NONE, FTAG); 256990b485lling rw_exit(&dp->dp_config_rwlock); 257990b485lling } else { 258990b485lling strval = NULL; 259990b485lling intval = za.za_first_integer; 260990b485lling } 261990b485lling 262990b485lling err = spa_prop_add_list(*nvp, prop, strval, 263990b485lling intval, src); 264990b485lling 265990b485lling if (strval != NULL) 266990b485lling kmem_free(strval, 267990b485lling MAXNAMELEN + strlen(MOS_DIR_NAME) + 1); 268990b485lling 269990b485lling break; 270990b485lling 271990b485lling case 1: 272990b485lling /* string property */ 273990b485lling strval = kmem_alloc(za.za_num_integers, KM_SLEEP); 274990b485lling err = zap_lookup(mos, spa->spa_pool_props_object, 275990b485lling za.za_name, 1, za.za_num_integers, strval); 276990b485lling if (err) { 277990b485lling kmem_free(strval, za.za_num_integers); 278990b485lling break; 279990b485lling } 280990b485lling err = spa_prop_add_list(*nvp, prop, strval, 0, src); 281990b485lling kmem_free(strval, za.za_num_integers); 282990b485lling break; 283990b485lling 284990b485lling default: 285990b485lling break; 286990b485lling } 287990b485lling } 288990b485lling zap_cursor_fini(&zc); 289990b485lling mutex_exit(&spa->spa_props_lock); 290990b485llingout: 291990b485lling if (err && err != ENOENT) { 292990b485lling nvlist_free(*nvp); 293990b485lling return (err); 294990b485lling } 295990b485lling 296990b485lling return (0); 297990b485lling} 298990b485lling 299990b485lling/* 300990b485lling * Validate the given pool properties nvlist and modify the list 301990b485lling * for the property values to be set. 302990b485lling */ 303990b485llingstatic int 304990b485llingspa_prop_validate(spa_t *spa, nvlist_t *props) 305990b485lling{ 306990b485lling nvpair_t *elem; 307990b485lling int error = 0, reset_bootfs = 0; 308990b485lling uint64_t objnum; 309990b485lling 310990b485lling elem = NULL; 311990b485lling while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { 312990b485lling zpool_prop_t prop; 313990b485lling char *propname, *strval; 314990b485lling uint64_t intval; 315990b485lling vdev_t *rvdev; 316990b485lling char *vdev_type; 317990b485lling objset_t *os; 3182f8aaabeschrock char *slash; 319990b485lling 320990b485lling propname = nvpair_name(elem); 321990b485lling 322990b485lling if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) 323990b485lling return (EINVAL); 324990b485lling 325990b485lling switch (prop) { 326990b485lling case ZPOOL_PROP_VERSION: 327990b485lling error = nvpair_value_uint64(elem, &intval); 328990b485lling if (!error && 329990b485lling (intval < spa_version(spa) || intval > SPA_VERSION)) 330990b485lling error = EINVAL; 331990b485lling break; 332990b485lling 333990b485lling case ZPOOL_PROP_DELEGATION: 334990b485lling case ZPOOL_PROP_AUTOREPLACE: 335990b485lling error = nvpair_value_uint64(elem, &intval); 336990b485lling if (!error && intval > 1) 337990b485lling error = EINVAL; 338990b485lling break; 339990b485lling 340990b485lling case ZPOOL_PROP_BOOTFS: 341990b485lling if (spa_version(spa) < SPA_VERSION_BOOTFS) { 342990b485lling error = ENOTSUP; 343990b485lling break; 344990b485lling } 345990b485lling 346990b485lling /* 347990b485lling * A bootable filesystem can not be on a RAIDZ pool 348990b485lling * nor a striped pool with more than 1 device. 349990b485lling */ 350990b485lling rvdev = spa->spa_root_vdev; 351990b485lling vdev_type = 352990b485lling rvdev->vdev_child[0]->vdev_ops->vdev_op_type; 353990b485lling if (rvdev->vdev_children > 1 || 354990b485lling strcmp(vdev_type, VDEV_TYPE_RAIDZ) == 0 || 355990b485lling strcmp(vdev_type, VDEV_TYPE_MISSING) == 0) { 356990b485lling error = ENOTSUP; 357990b485lling break; 358990b485lling } 359990b485lling 360990b485lling reset_bootfs = 1; 361990b485lling 362990b485lling error = nvpair_value_string(elem, &strval); 363990b485lling 364990b485lling if (!error) { 365990b485lling if (strval == NULL || strval[0] == '\0') { 366990b485lling objnum = zpool_prop_default_numeric( 367990b485lling ZPOOL_PROP_BOOTFS); 368990b485lling break; 369990b485lling } 370990b485lling 371990b485lling if (error = dmu_objset_open(strval, DMU_OST_ZFS, 372990b485lling DS_MODE_STANDARD | DS_MODE_READONLY, &os)) 373990b485lling break; 374990b485lling objnum = dmu_objset_id(os); 375990b485lling dmu_objset_close(os); 376990b485lling } 377990b485lling break; 3780a4e951gw case ZPOOL_PROP_FAILUREMODE: 3790a4e951gw error = nvpair_value_uint64(elem, &intval); 3800a4e951gw if (!error && (intval < ZIO_FAILURE_MODE_WAIT || 3810a4e951gw intval > ZIO_FAILURE_MODE_PANIC)) 3820a4e951gw error = EINVAL; 3830a4e951gw 3840a4e951gw /* 3850a4e951gw * This is a special case which only occurs when 3860a4e951gw * the pool has completely failed. This allows 3870a4e951gw * the user to change the in-core failmode property 3880a4e951gw * without syncing it out to disk (I/Os might 3890a4e951gw * currently be blocked). We do this by returning 3900a4e951gw * EIO to the caller (spa_prop_set) to trick it 3910a4e951gw * into thinking we encountered a property validation 3920a4e951gw * error. 3930a4e951gw */ 3940a4e951gw if (!error && spa_state(spa) == POOL_STATE_IO_FAILURE) { 3950a4e951gw spa->spa_failmode = intval; 3960a4e951gw error = EIO; 3970a4e951gw } 3980a4e951gw break; 3992f8aaabeschrock 4002f8aaabeschrock case ZPOOL_PROP_CACHEFILE: 4012f8aaabeschrock if ((error = nvpair_value_string(elem, &strval)) != 0) 4022f8aaabeschrock break; 4032f8aaabeschrock 4042f8aaabeschrock if (strval[0] == '\0') 4052f8aaabeschrock break; 4062f8aaabeschrock 4072f8aaabeschrock if (strcmp(strval, "none") == 0) 4082f8aaabeschrock break; 4092f8aaabeschrock 4102f8aaabeschrock if (strval[0] != '/') { 4112f8aaabeschrock error = EINVAL; 4122f8aaabeschrock break; 4132f8aaabeschrock } 4142f8aaabeschrock 4152f8aaabeschrock slash = strrchr(strval, '/'); 4162f8aaabeschrock ASSERT(slash != NULL); 4172f8aaabeschrock 4182f8aaabeschrock if (slash[1] == '\0' || strcmp(slash, "/.") == 0 || 4192f8aaabeschrock strcmp(slash, "/..") == 0) 4202f8aaabeschrock error = EINVAL; 4212f8aaabeschrock break; 422990b485lling } 423990b485lling 424990b485lling if (error) 425990b485lling break; 426990b485lling } 427990b485lling 428990b485lling if (!error && reset_bootfs) { 429990b485lling error = nvlist_remove(props, 430990b485lling zpool_prop_to_name(ZPOOL_PROP_BOOTFS), DATA_TYPE_STRING); 431990b485lling 432990b485lling if (!error) { 433990b485lling error = nvlist_add_uint64(props, 434990b485lling zpool_prop_to_name(ZPOOL_PROP_BOOTFS), objnum); 435990b485lling } 436990b485lling } 437990b485lling 438990b485lling return (error); 439990b485lling} 440990b485lling 441990b485llingint 442990b485llingspa_prop_set(spa_t *spa, nvlist_t *nvp) 443990b485lling{ 444990b485lling int error; 445990b485lling 446990b485lling if ((error = spa_prop_validate(spa, nvp)) != 0) 447990b485lling return (error); 448990b485lling 449990b485lling return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props, 450990b485lling spa, nvp, 3)); 451990b485lling} 452990b485lling 453990b485lling/* 454990b485lling * If the bootfs property value is dsobj, clear it. 455990b485lling */ 456990b485llingvoid 457990b485llingspa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx) 458990b485lling{ 459990b485lling if (spa->spa_bootfs == dsobj && spa->spa_pool_props_object != 0) { 460990b485lling VERIFY(zap_remove(spa->spa_meta_objset, 461990b485lling spa->spa_pool_props_object, 462990b485lling zpool_prop_to_name(ZPOOL_PROP_BOOTFS), tx) == 0); 463990b485lling spa->spa_bootfs = 0; 464990b485lling } 465990b485lling} 466990b485lling 467fa9e406ahrens/* 468fa9e406ahrens * ========================================================================== 469fa9e406ahrens * SPA state manipulation (open/create/destroy/import/export) 470fa9e406ahrens * ========================================================================== 471fa9e406ahrens */ 472fa9e406ahrens 473ea8dc4beschrockstatic int 474ea8dc4beschrockspa_error_entry_compare(const void *a, const void *b) 475ea8dc4beschrock{ 476ea8dc4beschrock spa_error_entry_t *sa = (spa_error_entry_t *)a; 477ea8dc4beschrock spa_error_entry_t *sb = (spa_error_entry_t *)b; 478ea8dc4beschrock int ret; 479ea8dc4beschrock 480ea8dc4beschrock ret = bcmp(&sa->se_bookmark, &sb->se_bookmark, 481ea8dc4beschrock sizeof (zbookmark_t)); 482ea8dc4beschrock 483ea8dc4beschrock if (ret < 0) 484ea8dc4beschrock return (-1); 485ea8dc4beschrock else if (ret > 0) 486ea8dc4beschrock return (1); 487ea8dc4beschrock else 488ea8dc4beschrock return (0); 489ea8dc4beschrock} 490ea8dc4beschrock 491ea8dc4beschrock/* 492ea8dc4beschrock * Utility function which retrieves copies of the current logs and 493ea8dc4beschrock * re-initializes them in the process. 494ea8dc4beschrock */ 495ea8dc4beschrockvoid 496ea8dc4beschrockspa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub) 497ea8dc4beschrock{ 498ea8dc4beschrock ASSERT(MUTEX_HELD(&spa->spa_errlist_lock)); 499ea8dc4beschrock 500ea8dc4beschrock bcopy(&spa->spa_errlist_last, last, sizeof (avl_tree_t)); 501ea8dc4beschrock bcopy(&spa->spa_errlist_scrub, scrub, sizeof (avl_tree_t)); 502ea8dc4beschrock 503ea8dc4beschrock avl_create(&spa->spa_errlist_scrub, 504ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 505ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 506ea8dc4beschrock avl_create(&spa->spa_errlist_last, 507ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 508ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 509ea8dc4beschrock} 510ea8dc4beschrock 511fa9e406ahrens/* 512fa9e406ahrens * Activate an uninitialized pool. 513fa9e406ahrens */ 514fa9e406ahrensstatic void 515fa9e406ahrensspa_activate(spa_t *spa) 516fa9e406ahrens{ 517fa9e406ahrens int t; 518fa9e406ahrens 519fa9e406ahrens ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED); 520fa9e406ahrens 521fa9e406ahrens spa->spa_state = POOL_STATE_ACTIVE; 522fa9e406ahrens 523fa9e406ahrens spa->spa_normal_class = metaslab_class_create(); 5248654d02perrin spa->spa_log_class = metaslab_class_create(); 525fa9e406ahrens 526fa9e406ahrens for (t = 0; t < ZIO_TYPES; t++) { 527fa9e406ahrens spa->spa_zio_issue_taskq[t] = taskq_create("spa_zio_issue", 528416e0cdek zio_taskq_threads, maxclsyspri, 50, INT_MAX, 529fa9e406ahrens TASKQ_PREPOPULATE); 530fa9e406ahrens spa->spa_zio_intr_taskq[t] = taskq_create("spa_zio_intr", 531416e0cdek zio_taskq_threads, maxclsyspri, 50, INT_MAX, 532fa9e406ahrens TASKQ_PREPOPULATE); 533fa9e406ahrens } 534fa9e406ahrens 535fa9e406ahrens list_create(&spa->spa_dirty_list, sizeof (vdev_t), 536fa9e406ahrens offsetof(vdev_t, vdev_dirty_node)); 5370a4e951gw list_create(&spa->spa_zio_list, sizeof (zio_t), 5380a4e951gw offsetof(zio_t, zio_link_node)); 539fa9e406ahrens 540fa9e406ahrens txg_list_create(&spa->spa_vdev_txg_list, 541fa9e406ahrens offsetof(struct vdev, vdev_txg_node)); 542ea8dc4beschrock 543ea8dc4beschrock avl_create(&spa->spa_errlist_scrub, 544ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 545ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 546ea8dc4beschrock avl_create(&spa->spa_errlist_last, 547ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 548ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 549fa9e406ahrens} 550fa9e406ahrens 551fa9e406ahrens/* 552fa9e406ahrens * Opposite of spa_activate(). 553fa9e406ahrens */ 554fa9e406ahrensstatic void 555fa9e406ahrensspa_deactivate(spa_t *spa) 556fa9e406ahrens{ 557fa9e406ahrens int t; 558fa9e406ahrens 559fa9e406ahrens ASSERT(spa->spa_sync_on == B_FALSE); 560fa9e406ahrens ASSERT(spa->spa_dsl_pool == NULL); 561fa9e406ahrens ASSERT(spa->spa_root_vdev == NULL); 562fa9e406ahrens 563fa9e406ahrens ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED); 564fa9e406ahrens 565fa9e406ahrens txg_list_destroy(&spa->spa_vdev_txg_list); 566fa9e406ahrens 567fa9e406ahrens list_destroy(&spa->spa_dirty_list); 5680a4e951gw list_destroy(&spa->spa_zio_list); 569fa9e406ahrens 570fa9e406ahrens for (t = 0; t < ZIO_TYPES; t++) { 571fa9e406ahrens taskq_destroy(spa->spa_zio_issue_taskq[t]); 572fa9e406ahrens taskq_destroy(spa->spa_zio_intr_taskq[t]); 573fa9e406ahrens spa->spa_zio_issue_taskq[t] = NULL; 574fa9e406ahrens spa->spa_zio_intr_taskq[t] = NULL; 575fa9e406ahrens } 576fa9e406ahrens 577fa9e406ahrens metaslab_class_destroy(spa->spa_normal_class); 578fa9e406ahrens spa->spa_normal_class = NULL; 579fa9e406ahrens 5808654d02perrin metaslab_class_destroy(spa->spa_log_class); 5818654d02perrin spa->spa_log_class = NULL; 5828654d02perrin 583ea8dc4beschrock /* 584ea8dc4beschrock * If this was part of an import or the open otherwise failed, we may 585ea8dc4beschrock * still have errors left in the queues. Empty them just in case. 586ea8dc4beschrock */ 587ea8dc4beschrock spa_errlog_drain(spa); 588ea8dc4beschrock 589ea8dc4beschrock avl_destroy(&spa->spa_errlist_scrub); 590ea8dc4beschrock avl_destroy(&spa->spa_errlist_last); 591ea8dc4beschrock 592fa9e406ahrens spa->spa_state = POOL_STATE_UNINITIALIZED; 593fa9e406ahrens} 594fa9e406ahrens 595fa9e406ahrens/* 596fa9e406ahrens * Verify a pool configuration, and construct the vdev tree appropriately. This 597fa9e406ahrens * will create all the necessary vdevs in the appropriate layout, with each vdev 598