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