Print this page
2619 asynchronous destruction of ZFS file systems
2747 SPA versioning with zfs feature flags
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <gwilson@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Approved by: Dan McDonald <danmcd@nexenta.com>
*** 18,28 ****
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/zfs_context.h>
#include <sys/spa_impl.h>
--- 18,28 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/zfs_context.h>
#include <sys/spa_impl.h>
*** 46,55 ****
--- 46,56 ----
#include <sys/fs/zfs.h>
#include <sys/metaslab_impl.h>
#include <sys/arc.h>
#include <sys/ddt.h>
#include "zfs_prop.h"
+ #include "zfeature_common.h"
/*
* SPA locking
*
* There are four basic locks for managing spa_t structures:
*** 214,224 ****
*
* vdev state is protected by spa_vdev_state_enter() / spa_vdev_state_exit().
* Like spa_vdev_enter/exit, these are convenience wrappers -- the actual
* locking is, always, based on spa_namespace_lock and spa_config_lock[].
*
! * spa_rename() is also implemented within this file since is requires
* manipulation of the namespace.
*/
static avl_tree_t spa_namespace_avl;
kmutex_t spa_namespace_lock;
--- 215,225 ----
*
* vdev state is protected by spa_vdev_state_enter() / spa_vdev_state_exit().
* Like spa_vdev_enter/exit, these are convenience wrappers -- the actual
* locking is, always, based on spa_namespace_lock and spa_config_lock[].
*
! * spa_rename() is also implemented within this file since it requires
* manipulation of the namespace.
*/
static avl_tree_t spa_namespace_avl;
kmutex_t spa_namespace_lock;
*** 481,493 ****
list_insert_head(&spa->spa_config_list, dp);
VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME,
KM_SLEEP) == 0);
! if (config != NULL)
VERIFY(nvlist_dup(config, &spa->spa_config, 0) == 0);
return (spa);
}
/*
* Removes a spa_t from the namespace, freeing up any memory used. Requires
--- 482,508 ----
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);
+ }
+
return (spa);
}
/*
* Removes a spa_t from the namespace, freeing up any memory used. Requires
*** 519,528 ****
--- 534,544 ----
kmem_free(dp, sizeof (spa_config_dirent_t));
}
list_destroy(&spa->spa_config_list);
+ nvlist_free(spa->spa_label_features);
nvlist_free(spa->spa_load_info);
spa_config_set(spa, NULL);
refcount_destroy(&spa->spa_refcount);
*** 1027,1036 ****
--- 1043,1066 ----
* ==========================================================================
* Miscellaneous functions
* ==========================================================================
*/
+ void
+ spa_activate_mos_feature(spa_t *spa, const char *feature)
+ {
+ (void) nvlist_add_boolean(spa->spa_label_features, feature);
+ vdev_config_dirty(spa->spa_root_vdev);
+ }
+
+ void
+ spa_deactivate_mos_feature(spa_t *spa, const char *feature)
+ {
+ (void) nvlist_remove_all(spa->spa_label_features, feature);
+ vdev_config_dirty(spa->spa_root_vdev);
+ }
+
/*
* Rename a spa_t.
*/
int
spa_rename(const char *name, const char *newname)
*** 1177,1192 ****
}
void
sprintf_blkptr(char *buf, const blkptr_t *bp)
{
! char *type = NULL;
char *checksum = NULL;
char *compress = NULL;
if (bp != NULL) {
! type = dmu_ot[BP_GET_TYPE(bp)].ot_name;
checksum = zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name;
compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name;
}
SPRINTF_BLKPTR(snprintf, ' ', buf, bp, type, checksum, compress);
--- 1207,1232 ----
}
void
sprintf_blkptr(char *buf, const blkptr_t *bp)
{
! char type[256];
char *checksum = NULL;
char *compress = NULL;
if (bp != NULL) {
! if (BP_GET_TYPE(bp) & DMU_OT_NEWTYPE) {
! dmu_object_byteswap_t bswap =
! DMU_OT_BYTESWAP(BP_GET_TYPE(bp));
! (void) snprintf(type, sizeof (type), "bswap %s %s",
! DMU_OT_IS_METADATA(BP_GET_TYPE(bp)) ?
! "metadata" : "data",
! dmu_ot_byteswap[bswap].ob_name);
! } else {
! (void) strlcpy(type, dmu_ot[BP_GET_TYPE(bp)].ot_name,
! sizeof (type));
! }
checksum = zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name;
compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name;
}
SPRINTF_BLKPTR(snprintf, ' ', buf, bp, type, checksum, compress);
*** 1264,1273 ****
--- 1304,1319 ----
spa_get_dsl(spa_t *spa)
{
return (spa->spa_dsl_pool);
}
+ boolean_t
+ spa_is_initializing(spa_t *spa)
+ {
+ return (spa->spa_is_initializing);
+ }
+
blkptr_t *
spa_get_rootblkptr(spa_t *spa)
{
return (&spa->spa_ubsync.ub_rootbp);
}
*** 1547,1556 ****
--- 1593,1603 ----
dmu_init();
zil_init();
vdev_cache_stat_init();
zfs_prop_init();
zpool_prop_init();
+ zpool_feature_init();
spa_config_load();
l2arc_start();
}
void