diff options
author | rob-wing <[email protected]> | 2023-04-20 09:07:56 -0800 |
---|---|---|
committer | GitHub <[email protected]> | 2023-04-20 10:07:56 -0700 |
commit | 3e4ed4213d7b4e8892e9def8b06363391d8dbd60 (patch) | |
tree | a2036792648169eb26a80579016900a06dca5bcd /module | |
parent | 71d191ef25d1c60e6725c07b6b94a0184f7db2eb (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.c | 6 | ||||
-rw-r--r-- | module/zfs/spa.c | 11 | ||||
-rw-r--r-- | module/zfs/vdev.c | 31 | ||||
-rw-r--r-- | module/zfs/vdev_label.c | 6 |
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); |