18 * |
18 * |
19 * CDDL HEADER END |
19 * CDDL HEADER END |
20 */ |
20 */ |
21 /* |
21 /* |
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
23 * Copyright (c) 2011 by Delphix. All rights reserved. |
23 * Copyright (c) 2012 by Delphix. All rights reserved. |
24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. |
24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. |
25 */ |
25 */ |
26 |
26 |
27 #include <sys/zfs_context.h> |
27 #include <sys/zfs_context.h> |
28 #include <sys/spa_impl.h> |
28 #include <sys/spa_impl.h> |
214 * |
215 * |
215 * vdev state is protected by spa_vdev_state_enter() / spa_vdev_state_exit(). |
216 * 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 * 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 * locking is, always, based on spa_namespace_lock and spa_config_lock[]. |
218 * |
219 * |
219 * spa_rename() is also implemented within this file since is requires |
220 * spa_rename() is also implemented within this file since it requires |
220 * manipulation of the namespace. |
221 * manipulation of the namespace. |
221 */ |
222 */ |
222 |
223 |
223 static avl_tree_t spa_namespace_avl; |
224 static avl_tree_t spa_namespace_avl; |
224 kmutex_t spa_namespace_lock; |
225 kmutex_t spa_namespace_lock; |
481 list_insert_head(&spa->spa_config_list, dp); |
482 list_insert_head(&spa->spa_config_list, dp); |
482 |
483 |
483 VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME, |
484 VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME, |
484 KM_SLEEP) == 0); |
485 KM_SLEEP) == 0); |
485 |
486 |
486 if (config != NULL) |
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 |
487 VERIFY(nvlist_dup(config, &spa->spa_config, 0) == 0); |
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 } |
488 |
503 |
489 return (spa); |
504 return (spa); |
490 } |
505 } |
491 |
506 |
492 /* |
507 /* |
519 kmem_free(dp, sizeof (spa_config_dirent_t)); |
534 kmem_free(dp, sizeof (spa_config_dirent_t)); |
520 } |
535 } |
521 |
536 |
522 list_destroy(&spa->spa_config_list); |
537 list_destroy(&spa->spa_config_list); |
523 |
538 |
|
539 nvlist_free(spa->spa_label_features); |
524 nvlist_free(spa->spa_load_info); |
540 nvlist_free(spa->spa_load_info); |
525 spa_config_set(spa, NULL); |
541 spa_config_set(spa, NULL); |
526 |
542 |
527 refcount_destroy(&spa->spa_refcount); |
543 refcount_destroy(&spa->spa_refcount); |
528 |
544 |
1027 * ========================================================================== |
1043 * ========================================================================== |
1028 * Miscellaneous functions |
1044 * Miscellaneous functions |
1029 * ========================================================================== |
1045 * ========================================================================== |
1030 */ |
1046 */ |
1031 |
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 |
1032 /* |
1062 /* |
1033 * Rename a spa_t. |
1063 * Rename a spa_t. |
1034 */ |
1064 */ |
1035 int |
1065 int |
1036 spa_rename(const char *name, const char *newname) |
1066 spa_rename(const char *name, const char *newname) |
1177 } |
1207 } |
1178 |
1208 |
1179 void |
1209 void |
1180 sprintf_blkptr(char *buf, const blkptr_t *bp) |
1210 sprintf_blkptr(char *buf, const blkptr_t *bp) |
1181 { |
1211 { |
1182 char *type = NULL; |
1212 char type[256]; |
1183 char *checksum = NULL; |
1213 char *checksum = NULL; |
1184 char *compress = NULL; |
1214 char *compress = NULL; |
1185 |
1215 |
1186 if (bp != NULL) { |
1216 if (bp != NULL) { |
1187 type = dmu_ot[BP_GET_TYPE(bp)].ot_name; |
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 } |
1188 checksum = zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name; |
1228 checksum = zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name; |
1189 compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name; |
1229 compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name; |
1190 } |
1230 } |
1191 |
1231 |
1192 SPRINTF_BLKPTR(snprintf, ' ', buf, bp, type, checksum, compress); |
1232 SPRINTF_BLKPTR(snprintf, ' ', buf, bp, type, checksum, compress); |