]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/spa_misc.c
Illumos #2619 and #2747
[mirror_zfs.git] / module / zfs / spa_misc.c
index 4a8e6adfd83c4389be33236a279b2a1077c9313c..440a6addb4d5e6b370f2d36679f7d54a98c9a3c5 100644 (file)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
@@ -49,6 +49,7 @@
 #include <sys/arc.h>
 #include <sys/ddt.h>
 #include "zfs_prop.h"
+#include "zfeature_common.h"
 
 /*
  * SPA locking
  * 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
+ * spa_rename() is also implemented within this file since it requires
  * manipulation of the namespace.
  */
 
@@ -479,8 +480,22 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
        VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME,
            KM_PUSHPAGE) == 0);
 
-       if (config != NULL)
+       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);
 }
@@ -518,6 +533,7 @@ spa_remove(spa_t *spa)
 
        list_destroy(&spa->spa_config_list);
 
+       nvlist_free(spa->spa_label_features);
        nvlist_free(spa->spa_load_info);
        spa_config_set(spa, NULL);
 
@@ -1025,6 +1041,20 @@ spa_vdev_state_exit(spa_t *spa, vdev_t *vd, int error)
  * ==========================================================================
  */
 
+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.
  */
@@ -1175,12 +1205,22 @@ spa_generate_guid(spa_t *spa)
 void
 sprintf_blkptr(char *buf, const blkptr_t *bp)
 {
-       char *type = NULL;
+       char type[256];
        char *checksum = NULL;
        char *compress = NULL;
 
        if (bp != NULL) {
-               type = dmu_ot[BP_GET_TYPE(bp)].ot_name;
+               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;
        }
@@ -1252,6 +1292,12 @@ 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)
 {
@@ -1532,6 +1578,7 @@ spa_init(int mode)
        vdev_cache_stat_init();
        zfs_prop_init();
        zpool_prop_init();
+       zpool_feature_init();
        spa_config_load();
        l2arc_start();
 }