3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2011 by Delphix. All rights reserved.
24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 #include <sys/zfs_context.h>
28 #include <sys/spa_impl.h>
29 #include <sys/zio.h>
30 #include <sys/zio_checksum.h>
31 #include <sys/zio_compress.h>
32 #include <sys/dmu.h>
33 #include <sys/dmu_tx.h>
34 #include <sys/zap.h>
35 #include <sys/zil.h>
36 #include <sys/vdev_impl.h>
37 #include <sys/metaslab.h>
38 #include <sys/uberblock_impl.h>
39 #include <sys/txg.h>
40 #include <sys/avl.h>
41 #include <sys/unique.h>
42 #include <sys/dsl_pool.h>
43 #include <sys/dsl_dir.h>
44 #include <sys/dsl_prop.h>
45 #include <sys/dsl_scan.h>
46 #include <sys/fs/zfs.h>
47 #include <sys/metaslab_impl.h>
48 #include <sys/arc.h>
49 #include <sys/ddt.h>
50 #include "zfs_prop.h"
51
52 /*
53 * SPA locking
54 *
55 * There are four basic locks for managing spa_t structures:
56 *
57 * spa_namespace_lock (global mutex)
58 *
59 * This lock must be acquired to do any of the following:
60 *
61 * - Lookup a spa_t by name
62 * - Add or remove a spa_t from the namespace
63 * - Increase spa_refcount from non-zero
64 * - Check if spa_refcount is zero
65 * - Rename a spa_t
66 * - add/remove/attach/detach devices
67 * - Held for the duration of create/destroy/import/export
68 *
69 * It does not need to handle recursion. A create or destroy may
70 * reference objects (files or zvols) in other pools, but by
199 *
200 * (b) I/O operations on leaf vdevs. For any zio operation that takes
201 * an explicit vdev_t argument -- such as zio_ioctl(), zio_read_phys(),
202 * or zio_write_phys() -- the caller must ensure that the config cannot
203 * cannot change in the interim, and that the vdev cannot be reopened.
204 * SCL_STATE as reader suffices for both.
205 *
206 * The vdev configuration is protected by spa_vdev_enter() / spa_vdev_exit().
207 *
208 * spa_vdev_enter() Acquire the namespace lock and the config lock
209 * for writing.
210 *
211 * spa_vdev_exit() Release the config lock, wait for all I/O
212 * to complete, sync the updated configs to the
213 * cache, and release the namespace lock.
214 *
215 * vdev state is protected by spa_vdev_state_enter() / spa_vdev_state_exit().
216 * Like spa_vdev_enter/exit, these are convenience wrappers -- the actual
217 * locking is, always, based on spa_namespace_lock and spa_config_lock[].
218 *
219 * spa_rename() is also implemented within this file since is requires
220 * manipulation of the namespace.
221 */
222
223 static avl_tree_t spa_namespace_avl;
224 kmutex_t spa_namespace_lock;
225 static kcondvar_t spa_namespace_cv;
226 static int spa_active_count;
227 int spa_max_replication_override = SPA_DVAS_PER_BP;
228
229 static kmutex_t spa_spare_lock;
230 static avl_tree_t spa_spare_avl;
231 static kmutex_t spa_l2cache_lock;
232 static avl_tree_t spa_l2cache_avl;
233
234 kmem_cache_t *spa_buffer_pool;
235 int spa_mode_global;
236
237 #ifdef ZFS_DEBUG
238 /* Everything except dprintf is on by default in debug builds */
239 int zfs_flags = ~ZFS_DEBUG_DPRINTF;
466 * Set the alternate root, if there is one.
467 */
468 if (altroot) {
469 spa->spa_root = spa_strdup(altroot);
470 spa_active_count++;
471 }
472
473 /*
474 * Every pool starts with the default cachefile
475 */
476 list_create(&spa->spa_config_list, sizeof (spa_config_dirent_t),
477 offsetof(spa_config_dirent_t, scd_link));
478
479 dp = kmem_zalloc(sizeof (spa_config_dirent_t), KM_SLEEP);
480 dp->scd_path = altroot ? NULL : spa_strdup(spa_config_path);
481 list_insert_head(&spa->spa_config_list, dp);
482
483 VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME,
484 KM_SLEEP) == 0);
485
486 if (config != NULL)
487 VERIFY(nvlist_dup(config, &spa->spa_config, 0) == 0);
488
489 return (spa);
490 }
491
492 /*
493 * Removes a spa_t from the namespace, freeing up any memory used. Requires
494 * spa_namespace_lock. This is called only after the spa_t has been closed and
495 * deactivated.
496 */
497 void
498 spa_remove(spa_t *spa)
499 {
500 spa_config_dirent_t *dp;
501
502 ASSERT(MUTEX_HELD(&spa_namespace_lock));
503 ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
504
505 nvlist_free(spa->spa_config_splitting);
506
507 avl_remove(&spa_namespace_avl, spa);
508 cv_broadcast(&spa_namespace_cv);
509
510 if (spa->spa_root) {
511 spa_strfree(spa->spa_root);
512 spa_active_count--;
513 }
514
515 while ((dp = list_head(&spa->spa_config_list)) != NULL) {
516 list_remove(&spa->spa_config_list, dp);
517 if (dp->scd_path != NULL)
518 spa_strfree(dp->scd_path);
519 kmem_free(dp, sizeof (spa_config_dirent_t));
520 }
521
522 list_destroy(&spa->spa_config_list);
523
524 nvlist_free(spa->spa_load_info);
525 spa_config_set(spa, NULL);
526
527 refcount_destroy(&spa->spa_refcount);
528
529 spa_config_lock_destroy(spa);
530
531 for (int t = 0; t < TXG_SIZE; t++)
532 bplist_destroy(&spa->spa_free_bplist[t]);
533
534 cv_destroy(&spa->spa_async_cv);
535 cv_destroy(&spa->spa_proc_cv);
536 cv_destroy(&spa->spa_scrub_io_cv);
537 cv_destroy(&spa->spa_suspend_cv);
538
539 mutex_destroy(&spa->spa_async_lock);
540 mutex_destroy(&spa->spa_errlist_lock);
541 mutex_destroy(&spa->spa_errlog_lock);
542 mutex_destroy(&spa->spa_history_lock);
543 mutex_destroy(&spa->spa_proc_lock);
1012 txg_wait_synced(spa->spa_dsl_pool, 0);
1013
1014 /*
1015 * If the config changed, update the config cache.
1016 */
1017 if (config_changed) {
1018 mutex_enter(&spa_namespace_lock);
1019 spa_config_sync(spa, B_FALSE, B_TRUE);
1020 mutex_exit(&spa_namespace_lock);
1021 }
1022
1023 return (error);
1024 }
1025
1026 /*
1027 * ==========================================================================
1028 * Miscellaneous functions
1029 * ==========================================================================
1030 */
1031
1032 /*
1033 * Rename a spa_t.
1034 */
1035 int
1036 spa_rename(const char *name, const char *newname)
1037 {
1038 spa_t *spa;
1039 int err;
1040
1041 /*
1042 * Lookup the spa_t and grab the config lock for writing. We need to
1043 * actually open the pool so that we can sync out the necessary labels.
1044 * It's OK to call spa_open() with the namespace lock held because we
1045 * allow recursive calls for other reasons.
1046 */
1047 mutex_enter(&spa_namespace_lock);
1048 if ((err = spa_open(name, &spa, FTAG)) != 0) {
1049 mutex_exit(&spa_namespace_lock);
1050 return (err);
1051 }
1162
1163 uint64_t
1164 spa_generate_guid(spa_t *spa)
1165 {
1166 uint64_t guid = spa_get_random(-1ULL);
1167
1168 if (spa != NULL) {
1169 while (guid == 0 || spa_guid_exists(spa_guid(spa), guid))
1170 guid = spa_get_random(-1ULL);
1171 } else {
1172 while (guid == 0 || spa_guid_exists(guid, 0))
1173 guid = spa_get_random(-1ULL);
1174 }
1175
1176 return (guid);
1177 }
1178
1179 void
1180 sprintf_blkptr(char *buf, const blkptr_t *bp)
1181 {
1182 char *type = NULL;
1183 char *checksum = NULL;
1184 char *compress = NULL;
1185
1186 if (bp != NULL) {
1187 type = dmu_ot[BP_GET_TYPE(bp)].ot_name;
1188 checksum = zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name;
1189 compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name;
1190 }
1191
1192 SPRINTF_BLKPTR(snprintf, ' ', buf, bp, type, checksum, compress);
1193 }
1194
1195 void
1196 spa_freeze(spa_t *spa)
1197 {
1198 uint64_t freeze_txg = 0;
1199
1200 spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
1201 if (spa->spa_freeze_txg == UINT64_MAX) {
1202 freeze_txg = spa_last_synced_txg(spa) + TXG_SIZE;
1203 spa->spa_freeze_txg = freeze_txg;
1204 }
1205 spa_config_exit(spa, SCL_ALL, FTAG);
1206 if (freeze_txg != 0)
1207 txg_wait_synced(spa_get_dsl(spa), freeze_txg);
1249 }
1250
1251 /*
1252 * ==========================================================================
1253 * Accessor functions
1254 * ==========================================================================
1255 */
1256
1257 boolean_t
1258 spa_shutting_down(spa_t *spa)
1259 {
1260 return (spa->spa_async_suspended);
1261 }
1262
1263 dsl_pool_t *
1264 spa_get_dsl(spa_t *spa)
1265 {
1266 return (spa->spa_dsl_pool);
1267 }
1268
1269 blkptr_t *
1270 spa_get_rootblkptr(spa_t *spa)
1271 {
1272 return (&spa->spa_ubsync.ub_rootbp);
1273 }
1274
1275 void
1276 spa_set_rootblkptr(spa_t *spa, const blkptr_t *bp)
1277 {
1278 spa->spa_uberblock.ub_rootbp = *bp;
1279 }
1280
1281 void
1282 spa_altroot(spa_t *spa, char *buf, size_t buflen)
1283 {
1284 if (spa->spa_root == NULL)
1285 buf[0] = '\0';
1286 else
1287 (void) strncpy(buf, spa->spa_root, buflen);
1288 }
1532
1533 avl_create(&spa_namespace_avl, spa_name_compare, sizeof (spa_t),
1534 offsetof(spa_t, spa_avl));
1535
1536 avl_create(&spa_spare_avl, spa_spare_compare, sizeof (spa_aux_t),
1537 offsetof(spa_aux_t, aux_avl));
1538
1539 avl_create(&spa_l2cache_avl, spa_l2cache_compare, sizeof (spa_aux_t),
1540 offsetof(spa_aux_t, aux_avl));
1541
1542 spa_mode_global = mode;
1543
1544 refcount_init();
1545 unique_init();
1546 zio_init();
1547 dmu_init();
1548 zil_init();
1549 vdev_cache_stat_init();
1550 zfs_prop_init();
1551 zpool_prop_init();
1552 spa_config_load();
1553 l2arc_start();
1554 }
1555
1556 void
1557 spa_fini(void)
1558 {
1559 l2arc_stop();
1560
1561 spa_evict_all();
1562
1563 vdev_cache_stat_fini();
1564 zil_fini();
1565 dmu_fini();
1566 zio_fini();
1567 unique_fini();
1568 refcount_fini();
1569
1570 avl_destroy(&spa_namespace_avl);
1571 avl_destroy(&spa_spare_avl);
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012 by Delphix. All rights reserved.
24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 #include <sys/zfs_context.h>
28 #include <sys/spa_impl.h>
29 #include <sys/zio.h>
30 #include <sys/zio_checksum.h>
31 #include <sys/zio_compress.h>
32 #include <sys/dmu.h>
33 #include <sys/dmu_tx.h>
34 #include <sys/zap.h>
35 #include <sys/zil.h>
36 #include <sys/vdev_impl.h>
37 #include <sys/metaslab.h>
38 #include <sys/uberblock_impl.h>
39 #include <sys/txg.h>
40 #include <sys/avl.h>
41 #include <sys/unique.h>
42 #include <sys/dsl_pool.h>
43 #include <sys/dsl_dir.h>
44 #include <sys/dsl_prop.h>
45 #include <sys/dsl_scan.h>
46 #include <sys/fs/zfs.h>
47 #include <sys/metaslab_impl.h>
48 #include <sys/arc.h>
49 #include <sys/ddt.h>
50 #include "zfs_prop.h"
51 #include "zfeature_common.h"
52
53 /*
54 * SPA locking
55 *
56 * There are four basic locks for managing spa_t structures:
57 *
58 * spa_namespace_lock (global mutex)
59 *
60 * This lock must be acquired to do any of the following:
61 *
62 * - Lookup a spa_t by name
63 * - Add or remove a spa_t from the namespace
64 * - Increase spa_refcount from non-zero
65 * - Check if spa_refcount is zero
66 * - Rename a spa_t
67 * - add/remove/attach/detach devices
68 * - Held for the duration of create/destroy/import/export
69 *
70 * It does not need to handle recursion. A create or destroy may
71 * reference objects (files or zvols) in other pools, but by
200 *
201 * (b) I/O operations on leaf vdevs. For any zio operation that takes
202 * an explicit vdev_t argument -- such as zio_ioctl(), zio_read_phys(),
203 * or zio_write_phys() -- the caller must ensure that the config cannot
204 * cannot change in the interim, and that the vdev cannot be reopened.
205 * SCL_STATE as reader suffices for both.
206 *
207 * The vdev configuration is protected by spa_vdev_enter() / spa_vdev_exit().
208 *
209 * spa_vdev_enter() Acquire the namespace lock and the config lock
210 * for writing.
211 *
212 * spa_vdev_exit() Release the config lock, wait for all I/O
213 * to complete, sync the updated configs to the
214 * cache, and release the namespace lock.
215 *
216 * vdev state is protected by spa_vdev_state_enter() / spa_vdev_state_exit().
217 * Like spa_vdev_enter/exit, these are convenience wrappers -- the actual
218 * locking is, always, based on spa_namespace_lock and spa_config_lock[].
219 *
220 * spa_rename() is also implemented within this file since it requires
221 * manipulation of the namespace.
222 */
223
224 static avl_tree_t spa_namespace_avl;
225 kmutex_t spa_namespace_lock;
226 static kcondvar_t spa_namespace_cv;
227 static int spa_active_count;
228 int spa_max_replication_override = SPA_DVAS_PER_BP;
229
230 static kmutex_t spa_spare_lock;
231 static avl_tree_t spa_spare_avl;
232 static kmutex_t spa_l2cache_lock;
233 static avl_tree_t spa_l2cache_avl;
234
235 kmem_cache_t *spa_buffer_pool;
236 int spa_mode_global;
237
238 #ifdef ZFS_DEBUG
239 /* Everything except dprintf is on by default in debug builds */
240 int zfs_flags = ~ZFS_DEBUG_DPRINTF;
467 * Set the alternate root, if there is one.
468 */
469 if (altroot) {
470 spa->spa_root = spa_strdup(altroot);
471 spa_active_count++;
472 }
473
474 /*
475 * Every pool starts with the default cachefile
476 */
477 list_create(&spa->spa_config_list, sizeof (spa_config_dirent_t),
478 offsetof(spa_config_dirent_t, scd_link));
479
480 dp = kmem_zalloc(sizeof (spa_config_dirent_t), KM_SLEEP);
481 dp->scd_path = altroot ? NULL : spa_strdup(spa_config_path);
482 list_insert_head(&spa->spa_config_list, dp);
483
484 VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME,
485 KM_SLEEP) == 0);
486
487 if (config != NULL) {
488 nvlist_t *features;
489
490 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ,
491 &features) == 0) {
492 VERIFY(nvlist_dup(features, &spa->spa_label_features,
493 0) == 0);
494 }
495
496 VERIFY(nvlist_dup(config, &spa->spa_config, 0) == 0);
497 }
498
499 if (spa->spa_label_features == NULL) {
500 VERIFY(nvlist_alloc(&spa->spa_label_features, NV_UNIQUE_NAME,
501 KM_SLEEP) == 0);
502 }
503
504 return (spa);
505 }
506
507 /*
508 * Removes a spa_t from the namespace, freeing up any memory used. Requires
509 * spa_namespace_lock. This is called only after the spa_t has been closed and
510 * deactivated.
511 */
512 void
513 spa_remove(spa_t *spa)
514 {
515 spa_config_dirent_t *dp;
516
517 ASSERT(MUTEX_HELD(&spa_namespace_lock));
518 ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
519
520 nvlist_free(spa->spa_config_splitting);
521
522 avl_remove(&spa_namespace_avl, spa);
523 cv_broadcast(&spa_namespace_cv);
524
525 if (spa->spa_root) {
526 spa_strfree(spa->spa_root);
527 spa_active_count--;
528 }
529
530 while ((dp = list_head(&spa->spa_config_list)) != NULL) {
531 list_remove(&spa->spa_config_list, dp);
532 if (dp->scd_path != NULL)
533 spa_strfree(dp->scd_path);
534 kmem_free(dp, sizeof (spa_config_dirent_t));
535 }
536
537 list_destroy(&spa->spa_config_list);
538
539 nvlist_free(spa->spa_label_features);
540 nvlist_free(spa->spa_load_info);
541 spa_config_set(spa, NULL);
542
543 refcount_destroy(&spa->spa_refcount);
544
545 spa_config_lock_destroy(spa);
546
547 for (int t = 0; t < TXG_SIZE; t++)
548 bplist_destroy(&spa->spa_free_bplist[t]);
549
550 cv_destroy(&spa->spa_async_cv);
551 cv_destroy(&spa->spa_proc_cv);
552 cv_destroy(&spa->spa_scrub_io_cv);
553 cv_destroy(&spa->spa_suspend_cv);
554
555 mutex_destroy(&spa->spa_async_lock);
556 mutex_destroy(&spa->spa_errlist_lock);
557 mutex_destroy(&spa->spa_errlog_lock);
558 mutex_destroy(&spa->spa_history_lock);
559 mutex_destroy(&spa->spa_proc_lock);
1028 txg_wait_synced(spa->spa_dsl_pool, 0);
1029
1030 /*
1031 * If the config changed, update the config cache.
1032 */
1033 if (config_changed) {
1034 mutex_enter(&spa_namespace_lock);
1035 spa_config_sync(spa, B_FALSE, B_TRUE);
1036 mutex_exit(&spa_namespace_lock);
1037 }
1038
1039 return (error);
1040 }
1041
1042 /*
1043 * ==========================================================================
1044 * Miscellaneous functions
1045 * ==========================================================================
1046 */
1047
1048 void
1049 spa_activate_mos_feature(spa_t *spa, const char *feature)
1050 {
1051 (void) nvlist_add_boolean(spa->spa_label_features, feature);
1052 vdev_config_dirty(spa->spa_root_vdev);
1053 }
1054
1055 void
1056 spa_deactivate_mos_feature(spa_t *spa, const char *feature)
1057 {
1058 (void) nvlist_remove_all(spa->spa_label_features, feature);
1059 vdev_config_dirty(spa->spa_root_vdev);
1060 }
1061
1062 /*
1063 * Rename a spa_t.
1064 */
1065 int
1066 spa_rename(const char *name, const char *newname)
1067 {
1068 spa_t *spa;
1069 int err;
1070
1071 /*
1072 * Lookup the spa_t and grab the config lock for writing. We need to
1073 * actually open the pool so that we can sync out the necessary labels.
1074 * It's OK to call spa_open() with the namespace lock held because we
1075 * allow recursive calls for other reasons.
1076 */
1077 mutex_enter(&spa_namespace_lock);
1078 if ((err = spa_open(name, &spa, FTAG)) != 0) {
1079 mutex_exit(&spa_namespace_lock);
1080 return (err);
1081 }
1192
1193 uint64_t
1194 spa_generate_guid(spa_t *spa)
1195 {
1196 uint64_t guid = spa_get_random(-1ULL);
1197
1198 if (spa != NULL) {
1199 while (guid == 0 || spa_guid_exists(spa_guid(spa), guid))
1200 guid = spa_get_random(-1ULL);
1201 } else {
1202 while (guid == 0 || spa_guid_exists(guid, 0))
1203 guid = spa_get_random(-1ULL);
1204 }
1205
1206 return (guid);
1207 }
1208
1209 void
1210 sprintf_blkptr(char *buf, const blkptr_t *bp)
1211 {
1212 char type[256];
1213 char *checksum = NULL;
1214 char *compress = NULL;
1215
1216 if (bp != NULL) {
1217 if (BP_GET_TYPE(bp) & DMU_OT_NEWTYPE) {
1218 dmu_object_byteswap_t bswap =
1219 DMU_OT_BYTESWAP(BP_GET_TYPE(bp));
1220 (void) snprintf(type, sizeof (type), "bswap %s %s",
1221 DMU_OT_IS_METADATA(BP_GET_TYPE(bp)) ?
1222 "metadata" : "data",
1223 dmu_ot_byteswap[bswap].ob_name);
1224 } else {
1225 (void) strlcpy(type, dmu_ot[BP_GET_TYPE(bp)].ot_name,
1226 sizeof (type));
1227 }
1228 checksum = zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name;
1229 compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name;
1230 }
1231
1232 SPRINTF_BLKPTR(snprintf, ' ', buf, bp, type, checksum, compress);
1233 }
1234
1235 void
1236 spa_freeze(spa_t *spa)
1237 {
1238 uint64_t freeze_txg = 0;
1239
1240 spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
1241 if (spa->spa_freeze_txg == UINT64_MAX) {
1242 freeze_txg = spa_last_synced_txg(spa) + TXG_SIZE;
1243 spa->spa_freeze_txg = freeze_txg;
1244 }
1245 spa_config_exit(spa, SCL_ALL, FTAG);
1246 if (freeze_txg != 0)
1247 txg_wait_synced(spa_get_dsl(spa), freeze_txg);
1289 }
1290
1291 /*
1292 * ==========================================================================
1293 * Accessor functions
1294 * ==========================================================================
1295 */
1296
1297 boolean_t
1298 spa_shutting_down(spa_t *spa)
1299 {
1300 return (spa->spa_async_suspended);
1301 }
1302
1303 dsl_pool_t *
1304 spa_get_dsl(spa_t *spa)
1305 {
1306 return (spa->spa_dsl_pool);
1307 }
1308
1309 boolean_t
1310 spa_is_initializing(spa_t *spa)
1311 {
1312 return (spa->spa_is_initializing);
1313 }
1314
1315 blkptr_t *
1316 spa_get_rootblkptr(spa_t *spa)
1317 {
1318 return (&spa->spa_ubsync.ub_rootbp);
1319 }
1320
1321 void
1322 spa_set_rootblkptr(spa_t *spa, const blkptr_t *bp)
1323 {
1324 spa->spa_uberblock.ub_rootbp = *bp;
1325 }
1326
1327 void
1328 spa_altroot(spa_t *spa, char *buf, size_t buflen)
1329 {
1330 if (spa->spa_root == NULL)
1331 buf[0] = '\0';
1332 else
1333 (void) strncpy(buf, spa->spa_root, buflen);
1334 }
1578
1579 avl_create(&spa_namespace_avl, spa_name_compare, sizeof (spa_t),
1580 offsetof(spa_t, spa_avl));
1581
1582 avl_create(&spa_spare_avl, spa_spare_compare, sizeof (spa_aux_t),
1583 offsetof(spa_aux_t, aux_avl));
1584
1585 avl_create(&spa_l2cache_avl, spa_l2cache_compare, sizeof (spa_aux_t),
1586 offsetof(spa_aux_t, aux_avl));
1587
1588 spa_mode_global = mode;
1589
1590 refcount_init();
1591 unique_init();
1592 zio_init();
1593 dmu_init();
1594 zil_init();
1595 vdev_cache_stat_init();
1596 zfs_prop_init();
1597 zpool_prop_init();
1598 zpool_feature_init();
1599 spa_config_load();
1600 l2arc_start();
1601 }
1602
1603 void
1604 spa_fini(void)
1605 {
1606 l2arc_stop();
1607
1608 spa_evict_all();
1609
1610 vdev_cache_stat_fini();
1611 zil_fini();
1612 dmu_fini();
1613 zio_fini();
1614 unique_fini();
1615 refcount_fini();
1616
1617 avl_destroy(&spa_namespace_avl);
1618 avl_destroy(&spa_spare_avl);
|