aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorrob-wing <[email protected]>2023-04-20 09:07:56 -0800
committerGitHub <[email protected]>2023-04-20 10:07:56 -0700
commit3e4ed4213d7b4e8892e9def8b06363391d8dbd60 (patch)
treea2036792648169eb26a80579016900a06dca5bcd /module
parent71d191ef25d1c60e6725c07b6b94a0184f7db2eb (diff)
Create zap for root vdev
And add it to the AVZ, this is not backwards compatible with older pools due to an assertion in spa_sync() that verifies the number of ZAPs of all vdevs matches the number of ZAPs in the AVZ. Granted, the assertion only applies to #DEBUG builds - still, a feature flag is introduced to avoid the assertion, com.klarasystems:vdev_zaps_v2 Notably, this allows to get/set properties on the root vdev: % zpool set user:prop=value <pool> root-0 Before this commit, it was already possible to get/set properties on top-level vdevs with the syntax <type>-<vdev_id> (e.g. mirror-0): % zpool set user:prop=value <pool> mirror-0 This syntax also applies to the root vdev as it is is of type 'root' with a vdev_id of 0, root-0. The keyword 'root' as an alias for 'root-0'. The following tests have been added: - zpool get all properties from root vdev - zpool set a property on root vdev - verify root vdev ZAP is created Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Rob Wing <[email protected]> Sponsored-by: Seagate Technology Submitted-by: Klara, Inc. Closes #14405
Diffstat (limited to 'module')
-rw-r--r--module/zcommon/zfeature_common.c6
-rw-r--r--module/zfs/spa.c11
-rw-r--r--module/zfs/vdev.c31
-rw-r--r--module/zfs/vdev_label.c6
4 files changed, 50 insertions, 4 deletions
diff --git a/module/zcommon/zfeature_common.c b/module/zcommon/zfeature_common.c
index 6fe1da8ed..4c9b7ed72 100644
--- a/module/zcommon/zfeature_common.c
+++ b/module/zcommon/zfeature_common.c
@@ -731,6 +731,12 @@ zpool_feature_init(void)
ZFEATURE_FLAG_READONLY_COMPAT, ZFEATURE_TYPE_BOOLEAN, NULL,
sfeatures);
+ zfeature_register(SPA_FEATURE_AVZ_V2,
+ "com.klarasystems:vdev_zaps_v2", "vdev_zaps_v2",
+ "Support for root vdev ZAP.",
+ ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL,
+ sfeatures);
+
zfs_mod_list_supported_free(sfeatures);
}
diff --git a/module/zfs/spa.c b/module/zfs/spa.c
index e76700a9c..67601211d 100644
--- a/module/zfs/spa.c
+++ b/module/zfs/spa.c
@@ -3044,6 +3044,12 @@ vdev_count_verify_zaps(vdev_t *vd)
spa_t *spa = vd->vdev_spa;
uint64_t total = 0;
+ if (spa_feature_is_active(vd->vdev_spa, SPA_FEATURE_AVZ_V2) &&
+ vd->vdev_root_zap != 0) {
+ total++;
+ ASSERT0(zap_lookup_int(spa->spa_meta_objset,
+ spa->spa_all_vdev_zaps, vd->vdev_root_zap));
+ }
if (vd->vdev_top_zap != 0) {
total++;
ASSERT0(zap_lookup_int(spa->spa_meta_objset,
@@ -8626,6 +8632,11 @@ spa_avz_build(vdev_t *vd, uint64_t avz, dmu_tx_t *tx)
{
spa_t *spa = vd->vdev_spa;
+ if (vd->vdev_root_zap != 0 &&
+ spa_feature_is_active(spa, SPA_FEATURE_AVZ_V2)) {
+ VERIFY0(zap_add_int(spa->spa_meta_objset, avz,
+ vd->vdev_root_zap, tx));
+ }
if (vd->vdev_top_zap != 0) {
VERIFY0(zap_add_int(spa->spa_meta_objset, avz,
vd->vdev_top_zap, tx));
diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c
index 241be8fd8..4bfd95861 100644
--- a/module/zfs/vdev.c
+++ b/module/zfs/vdev.c
@@ -397,7 +397,9 @@ vdev_prop_get_int(vdev_t *vd, vdev_prop_t prop, uint64_t *value)
uint64_t objid;
int err;
- if (vd->vdev_top_zap != 0) {
+ if (vd->vdev_root_zap != 0) {
+ objid = vd->vdev_root_zap;
+ } else if (vd->vdev_top_zap != 0) {
objid = vd->vdev_top_zap;
} else if (vd->vdev_leaf_zap != 0) {
objid = vd->vdev_leaf_zap;
@@ -898,6 +900,14 @@ vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id,
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_CREATE_TXG,
&vd->vdev_crtxg);
+ if (vd->vdev_ops == &vdev_root_ops &&
+ (alloctype == VDEV_ALLOC_LOAD ||
+ alloctype == VDEV_ALLOC_SPLIT ||
+ alloctype == VDEV_ALLOC_ROOTPOOL)) {
+ (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_VDEV_ROOT_ZAP,
+ &vd->vdev_root_zap);
+ }
+
/*
* If we're a top-level vdev, try to load the allocation parameters.
*/
@@ -3347,6 +3357,12 @@ vdev_construct_zaps(vdev_t *vd, dmu_tx_t *tx)
vdev_zap_allocation_data(vd, tx);
}
}
+ if (vd->vdev_ops == &vdev_root_ops && vd->vdev_root_zap == 0 &&
+ spa_feature_is_enabled(vd->vdev_spa, SPA_FEATURE_AVZ_V2)) {
+ if (!spa_feature_is_active(vd->vdev_spa, SPA_FEATURE_AVZ_V2))
+ spa_feature_incr(vd->vdev_spa, SPA_FEATURE_AVZ_V2, tx);
+ vd->vdev_root_zap = vdev_create_link_zap(vd, tx);
+ }
for (uint64_t i = 0; i < vd->vdev_children; i++) {
vdev_construct_zaps(vd->vdev_child[i], tx);
@@ -5683,12 +5699,17 @@ vdev_props_set_sync(void *arg, dmu_tx_t *tx)
/*
* Set vdev property values in the vdev props mos object.
*/
- if (vd->vdev_top_zap != 0) {
+ if (vd->vdev_root_zap != 0) {
+ objid = vd->vdev_root_zap;
+ } else if (vd->vdev_top_zap != 0) {
objid = vd->vdev_top_zap;
} else if (vd->vdev_leaf_zap != 0) {
objid = vd->vdev_leaf_zap;
} else {
- panic("vdev not top or leaf");
+ /*
+ * XXX: implement vdev_props_set_check()
+ */
+ panic("vdev not root/top/leaf");
}
switch (prop = vdev_name_to_prop(propname)) {
@@ -5891,7 +5912,9 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
nvlist_lookup_nvlist(innvl, ZPOOL_VDEV_PROPS_GET_PROPS, &nvprops);
- if (vd->vdev_top_zap != 0) {
+ if (vd->vdev_root_zap != 0) {
+ objid = vd->vdev_root_zap;
+ } else if (vd->vdev_top_zap != 0) {
objid = vd->vdev_top_zap;
} else if (vd->vdev_leaf_zap != 0) {
objid = vd->vdev_leaf_zap;
diff --git a/module/zfs/vdev_label.c b/module/zfs/vdev_label.c
index f61be65a2..85c7134ca 100644
--- a/module/zfs/vdev_label.c
+++ b/module/zfs/vdev_label.c
@@ -573,6 +573,12 @@ vdev_config_generate(spa_t *spa, vdev_t *vd, boolean_t getstats,
vd->vdev_top_zap);
}
+ if (vd->vdev_ops == &vdev_root_ops && vd->vdev_root_zap != 0 &&
+ spa_feature_is_active(vd->vdev_spa, SPA_FEATURE_AVZ_V2)) {
+ fnvlist_add_uint64(nv, ZPOOL_CONFIG_VDEV_ROOT_ZAP,
+ vd->vdev_root_zap);
+ }
+
if (vd->vdev_resilver_deferred) {
ASSERT(vd->vdev_ops->vdev_op_leaf);
ASSERT(spa->spa_resilver_deferred);