Print this page
4171 clean up spa_feature_*() interfaces
4172 implement extensible_dataset feature for use by other zpool features
Reviewed by: Max Grossman <max.grossman@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>

@@ -281,16 +281,17 @@
 
         spa_close(spa, FTAG);
 }
 
 static void
-feature_enable_sync(void *arg, dmu_tx_t *tx)
+zhack_feature_enable_sync(void *arg, dmu_tx_t *tx)
 {
         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
         zfeature_info_t *feature = arg;
 
-        spa_feature_enable(spa, feature, tx);
+        feature_enable_sync(spa, feature, tx);
+
         spa_history_log_internal(spa, "zhack enable feature", tx,
             "guid=%s can_readonly=%u",
             feature->fi_guid, feature->fi_can_readonly);
 }
 

@@ -300,11 +301,11 @@
         char c;
         char *desc, *target;
         spa_t *spa;
         objset_t *mos;
         zfeature_info_t feature;
-        zfeature_info_t *nodeps[] = { NULL };
+        spa_feature_t nodeps[] = { SPA_FEATURE_NONE };
 
         /*
          * Features are not added to the pool's label until their refcounts
          * are incremented, so fi_mos can just be left as false for now.
          */

@@ -347,18 +348,18 @@
                 fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid);
 
         zhack_spa_open(target, B_FALSE, FTAG, &spa);
         mos = spa->spa_meta_objset;
 
-        if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
+        if (zfeature_is_supported(feature.fi_guid))
                 fatal(spa, FTAG, "'%s' is a real feature, will not enable");
         if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
                 fatal(spa, FTAG, "feature already enabled: %s",
                     feature.fi_guid);
 
         VERIFY0(dsl_sync_task(spa_name(spa), NULL,
-            feature_enable_sync, &feature, 5));
+            zhack_feature_enable_sync, &feature, 5));
 
         spa_close(spa, FTAG);
 
         free(desc);
 }

@@ -366,23 +367,27 @@
 static void
 feature_incr_sync(void *arg, dmu_tx_t *tx)
 {
         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
         zfeature_info_t *feature = arg;
+        uint64_t refcount;
 
-        spa_feature_incr(spa, feature, tx);
+        VERIFY0(feature_get_refcount(spa, feature, &refcount));
+        feature_sync(spa, feature, refcount + 1, tx);
         spa_history_log_internal(spa, "zhack feature incr", tx,
             "guid=%s", feature->fi_guid);
 }
 
 static void
 feature_decr_sync(void *arg, dmu_tx_t *tx)
 {
         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
         zfeature_info_t *feature = arg;
+        uint64_t refcount;
 
-        spa_feature_decr(spa, feature, tx);
+        VERIFY0(feature_get_refcount(spa, feature, &refcount));
+        feature_sync(spa, feature, refcount - 1, tx);
         spa_history_log_internal(spa, "zhack feature decr", tx,
             "guid=%s", feature->fi_guid);
 }
 
 static void

@@ -392,11 +397,11 @@
         char *target;
         boolean_t decr = B_FALSE;
         spa_t *spa;
         objset_t *mos;
         zfeature_info_t feature;
-        zfeature_info_t *nodeps[] = { NULL };
+        spa_feature_t nodeps[] = { SPA_FEATURE_NONE };
 
         /*
          * fi_desc does not matter here because it was written to disk
          * when the feature was enabled, but we need to properly set the
          * feature for read or write based on the information we read off

@@ -435,13 +440,14 @@
                 fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid);
 
         zhack_spa_open(target, B_FALSE, FTAG, &spa);
         mos = spa->spa_meta_objset;
 
-        if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
-                fatal(spa, FTAG, "'%s' is a real feature, will not change "
-                    "refcount");
+        if (zfeature_is_supported(feature.fi_guid)) {
+                fatal(spa, FTAG,
+                    "'%s' is a real feature, will not change refcount");
+        }
 
         if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
             feature.fi_guid)) {
                 feature.fi_can_readonly = B_FALSE;
         } else if (0 == zap_contains(mos, spa->spa_feat_for_write_obj,

@@ -449,13 +455,18 @@
                 feature.fi_can_readonly = B_TRUE;
         } else {
                 fatal(spa, FTAG, "feature is not enabled: %s", feature.fi_guid);
         }
 
-        if (decr && !spa_feature_is_active(spa, &feature))
+        if (decr) {
+                uint64_t count;
+                if (feature_get_refcount(spa, &feature, &count) == 0 &&
+                    count != 0) {
                 fatal(spa, FTAG, "feature refcount already 0: %s",
                     feature.fi_guid);
+                }
+        }
 
         VERIFY0(dsl_sync_task(spa_name(spa), NULL,
             decr ? feature_decr_sync : feature_incr_sync, &feature, 5));
 
         spa_close(spa, FTAG);