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,296 ****
spa_close(spa, FTAG);
}
static void
! 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);
spa_history_log_internal(spa, "zhack enable feature", tx,
"guid=%s can_readonly=%u",
feature->fi_guid, feature->fi_can_readonly);
}
--- 281,297 ----
spa_close(spa, FTAG);
}
static void
! zhack_feature_enable_sync(void *arg, dmu_tx_t *tx)
{
spa_t *spa = dmu_tx_pool(tx)->dp_spa;
zfeature_info_t *feature = arg;
! 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,310 ****
char c;
char *desc, *target;
spa_t *spa;
objset_t *mos;
zfeature_info_t feature;
! zfeature_info_t *nodeps[] = { NULL };
/*
* 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.
*/
--- 301,311 ----
char c;
char *desc, *target;
spa_t *spa;
objset_t *mos;
zfeature_info_t feature;
! 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,364 ****
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 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));
spa_close(spa, FTAG);
free(desc);
}
--- 348,365 ----
fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid);
zhack_spa_open(target, B_FALSE, FTAG, &spa);
mos = spa->spa_meta_objset;
! 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,
! zhack_feature_enable_sync, &feature, 5));
spa_close(spa, FTAG);
free(desc);
}
*** 366,388 ****
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;
! spa_feature_incr(spa, feature, 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;
! spa_feature_decr(spa, feature, tx);
spa_history_log_internal(spa, "zhack feature decr", tx,
"guid=%s", feature->fi_guid);
}
static void
--- 367,393 ----
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;
! 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;
! 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,402 ****
char *target;
boolean_t decr = B_FALSE;
spa_t *spa;
objset_t *mos;
zfeature_info_t feature;
! zfeature_info_t *nodeps[] = { NULL };
/*
* 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
--- 397,407 ----
char *target;
boolean_t decr = B_FALSE;
spa_t *spa;
objset_t *mos;
zfeature_info_t feature;
! 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,447 ****
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 (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,
--- 440,453 ----
fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid);
zhack_spa_open(target, B_FALSE, FTAG, &spa);
mos = spa->spa_meta_objset;
! 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,461 ****
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))
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);
--- 455,472 ----
feature.fi_can_readonly = B_TRUE;
} else {
fatal(spa, FTAG, "feature is not enabled: %s", feature.fi_guid);
}
! 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);