stand/zfs: Refactor zfs_get_bootenv

Create a new interface to zfs_get_bootenv called zfs_get_bootenv_spa
which takes a spa instead of a void * (effectively a devdesc *). Use
that in zfs_get_bootenv.

Sponsored by:		Netflix
Reviewed by:		tsoome, kevans
Differential Revision:	https://reviews.freebsd.org/D39409
This commit is contained in:
Warner Losh 2023-05-01 09:26:51 -06:00
parent 439a9766ad
commit 6479bd1b7d
2 changed files with 32 additions and 25 deletions

View File

@ -798,35 +798,12 @@ zfs_probe_partition(void *arg, const char *partname,
int
zfs_get_bootenv(void *vdev, nvlist_t **benvp)
{
struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
nvlist_t *benv = NULL;
vdev_t *vd;
spa_t *spa;
if (dev->dd.d_dev->dv_type != DEVT_ZFS)
return (ENOTSUP);
if ((spa = spa_find_by_dev(dev)) == NULL)
if ((spa = spa_find_by_dev((struct zfs_devdesc *)vdev)) == NULL)
return (ENXIO);
if (spa->spa_bootenv == NULL) {
STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children,
v_childlink) {
benv = vdev_read_bootenv(vd);
if (benv != NULL)
break;
}
spa->spa_bootenv = benv;
} else {
benv = spa->spa_bootenv;
}
if (benv == NULL)
return (ENOENT);
*benvp = benv;
return (0);
return (zfs_get_bootenv_spa(spa, benvp));
}
/*

View File

@ -3853,3 +3853,33 @@ zfs_lookup(const struct zfsmount *mount, const char *upath, dnode_phys_t *dnode)
free(entry);
return (rc);
}
/*
* Return either a cached copy of the bootenv, or read each of the vdev children
* looking for the bootenv. Cache what's found and return the results. Returns 0
* when benvp is filled in, and some errno when not.
*/
static int
zfs_get_bootenv_spa(spa_t *spa, nvlist_t **benvp)
{
vdev_t *vd;
nvlist_t *benv = NULL;
if (spa->spa_bootenv == NULL) {
STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children,
v_childlink) {
benv = vdev_read_bootenv(vd);
if (benv != NULL)
break;
}
spa->spa_bootenv = benv;
}
benv = spa->spa_bootenv;
if (benv == NULL)
return (ENOENT);
*benvp = benv;
return (0);
}