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);