mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 02:44:41 +03:00
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 <behlendorf1@llnl.gov>
Signed-off-by: Rob Wing <rob.wing@klarasystems.com>
Sponsored-by: Seagate Technology
Submitted-by: Klara, Inc.
Closes #14405
This commit is contained in:
@@ -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));
|
||||
|
||||
+27
-4
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user