Print this page
4185 New hash algorithm support
        
*** 20,29 ****
--- 20,30 ----
   */
  /*
   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
   * Copyright (c) 2013 by Delphix. All rights reserved.
   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+  * Copyright 2013 Saso Kiselkov. All rights reserved.
   */
  
  #include <sys/zfs_context.h>
  #include <sys/spa_impl.h>
  #include <sys/spa_boot.h>
*** 47,57 ****
  #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:
--- 48,58 ----
  #include <sys/fs/zfs.h>
  #include <sys/metaslab_impl.h>
  #include <sys/arc.h>
  #include <sys/ddt.h>
  #include "zfs_prop.h"
! #include <sys/zfeature.h>
  
  /*
   * SPA locking
   *
   * There are four basic locks for managing spa_t structures:
*** 493,502 ****
--- 494,504 ----
          mutex_init(&spa->spa_errlist_lock, NULL, MUTEX_DEFAULT, NULL);
          mutex_init(&spa->spa_errlog_lock, NULL, MUTEX_DEFAULT, NULL);
          mutex_init(&spa->spa_history_lock, NULL, MUTEX_DEFAULT, NULL);
          mutex_init(&spa->spa_proc_lock, NULL, MUTEX_DEFAULT, NULL);
          mutex_init(&spa->spa_props_lock, NULL, MUTEX_DEFAULT, NULL);
+         mutex_init(&spa->spa_cksum_tmpls_lock, NULL, MUTEX_DEFAULT, NULL);
          mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL);
          mutex_init(&spa->spa_suspend_lock, NULL, MUTEX_DEFAULT, NULL);
          mutex_init(&spa->spa_vdev_top_lock, NULL, MUTEX_DEFAULT, NULL);
          mutex_init(&spa->spa_iokstat_lock, NULL, MUTEX_DEFAULT, NULL);
  
*** 639,648 ****
--- 641,652 ----
          spa->spa_iokstat = NULL;
  
          for (int t = 0; t < TXG_SIZE; t++)
                  bplist_destroy(&spa->spa_free_bplist[t]);
  
+         zio_checksum_templates_free(spa);
+ 
          cv_destroy(&spa->spa_async_cv);
          cv_destroy(&spa->spa_proc_cv);
          cv_destroy(&spa->spa_scrub_io_cv);
          cv_destroy(&spa->spa_suspend_cv);
  
*** 650,659 ****
--- 654,664 ----
          mutex_destroy(&spa->spa_errlist_lock);
          mutex_destroy(&spa->spa_errlog_lock);
          mutex_destroy(&spa->spa_history_lock);
          mutex_destroy(&spa->spa_proc_lock);
          mutex_destroy(&spa->spa_props_lock);
+         mutex_destroy(&spa->spa_cksum_tmpls_lock);
          mutex_destroy(&spa->spa_scrub_lock);
          mutex_destroy(&spa->spa_suspend_lock);
          mutex_destroy(&spa->spa_vdev_top_lock);
          mutex_destroy(&spa->spa_iokstat_lock);
  
*** 1780,1789 ****
--- 1785,1851 ----
  spa_writeable(spa_t *spa)
  {
          return (!!(spa->spa_mode & FWRITE));
  }
  
+ static int
+ activate_salted_cksum_check(zfeature_info_t *feature, dmu_tx_t *tx)
+ {
+         spa_t   *spa = dmu_tx_pool(tx)->dp_spa;
+ 
+         if (!spa_feature_is_active(spa, feature))
+                 return (0);
+         else
+                 return (SET_ERROR(EBUSY));
+ }
+ 
+ static void
+ activate_salted_cksum_sync(zfeature_info_t *feature, dmu_tx_t *tx)
+ {
+         spa_t   *spa = dmu_tx_pool(tx)->dp_spa;
+ 
+         spa_feature_incr(spa, feature, tx);
+         /*
+          * This is the first salted checksum that's been activated, so
+          * create the persistent checksum salt object now.
+          */
+         if (spa->spa_cksum_salt_obj == 0) {
+                 spa->spa_cksum_salt_obj = zap_create_link(spa->spa_meta_objset,
+                     DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
+                     DMU_POOL_CHECKSUM_SALT, tx);
+                 VERIFY3U(zap_add(spa->spa_meta_objset,
+                     spa->spa_cksum_salt_obj, DMU_POOL_CHECKSUM_SALT, 1,
+                     sizeof (spa->spa_cksum_salt.zcs_bytes),
+                     spa->spa_cksum_salt.zcs_bytes, tx), ==, 0);
+         }
+ }
+ 
+ /*
+  * Activates a feature associated with a salted checksum. You must call this
+  * function instead of calling spa_feature_incr() directly, because we may
+  * also need to sync the MOS object holding the checksum salt.
+  * Arguments:
+  *      spa     Pool on which to activate the salted checksum feature.
+  *      feature Salted checksum algorithm feature to activate (see
+  *              spa_feature_table).
+  */
+ int
+ spa_activate_salted_cksum(spa_t *spa, struct zfeature_info *feature)
+ {
+         int err;
+ 
+         /* EBUSY here indicates that the feature is already active */
+         err = dsl_sync_task(spa_name(spa),
+             (dsl_checkfunc_t *)activate_salted_cksum_check,
+             (dsl_syncfunc_t *)activate_salted_cksum_sync, feature, 2);
+ 
+         if (err != 0 && err != EBUSY)
+                 return (err);
+         else
+                 return (0);
+ }
+ 
  int
  spa_mode(spa_t *spa)
  {
          return (spa->spa_mode);
  }