zfs: replace uu_avl with sys/avl

Lets just use the AVL implementation we use everywhere else.

Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #17934
This commit is contained in:
Rob Norris
2025-11-13 09:51:39 +11:00
committed by Brian Behlendorf
parent e63d026b91
commit b593748287
7 changed files with 205 additions and 442 deletions
-2
View File
@@ -5,14 +5,12 @@ CPPCHECKTARGETS += libuutil.la
libuutil_la_SOURCES = \
%D%/uu_alloc.c \
%D%/uu_avl.c \
%D%/uu_ident.c \
%D%/uu_list.c \
%D%/uu_misc.c \
%D%/uu_string.c
libuutil_la_LIBADD = \
libavl.la \
libspl.la
libuutil_la_LIBADD += $(LTLIBINTL)
+35 -94
View File
@@ -31,12 +31,12 @@
*/
#include <libintl.h>
#include <libuutil.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zone.h>
#include <sys/avl.h>
#include <libzfs.h>
@@ -70,15 +70,14 @@ typedef struct prop_changenode {
int cn_mounted;
int cn_zoned;
boolean_t cn_needpost; /* is postfix() needed? */
uu_avl_node_t cn_treenode;
avl_node_t cn_treenode;
} prop_changenode_t;
struct prop_changelist {
zfs_prop_t cl_prop;
zfs_prop_t cl_realprop;
zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */
uu_avl_pool_t *cl_pool;
uu_avl_t *cl_tree;
avl_tree_t cl_tree;
boolean_t cl_waslegacy;
boolean_t cl_allchildren;
boolean_t cl_alldependents;
@@ -97,7 +96,6 @@ int
changelist_prefix(prop_changelist_t *clp)
{
prop_changenode_t *cn;
uu_avl_walk_t *walk;
int ret = 0;
const enum sa_protocol smb[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL};
boolean_t commit_smb_shares = B_FALSE;
@@ -115,10 +113,8 @@ changelist_prefix(prop_changelist_t *clp)
if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
return (0);
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
return (-1);
while ((cn = uu_avl_walk_next(walk)) != NULL) {
for (cn = avl_first(&clp->cl_tree); cn != NULL;
cn = AVL_NEXT(&clp->cl_tree, cn)) {
/* if a previous loop failed, set the remaining to false */
if (ret == -1) {
@@ -159,7 +155,6 @@ changelist_prefix(prop_changelist_t *clp)
if (commit_smb_shares)
zfs_commit_shares(smb);
uu_avl_walk_end(walk);
if (ret == -1)
(void) changelist_postfix(clp);
@@ -179,7 +174,6 @@ int
changelist_postfix(prop_changelist_t *clp)
{
prop_changenode_t *cn;
uu_avl_walk_t *walk;
char shareopts[ZFS_MAXPROPLEN];
boolean_t commit_smb_shares = B_FALSE;
boolean_t commit_nfs_shares = B_FALSE;
@@ -199,7 +193,7 @@ changelist_postfix(prop_changelist_t *clp)
* location), or have explicit mountpoints set (in which case they won't
* be in the changelist).
*/
if ((cn = uu_avl_last(clp->cl_tree)) == NULL)
if ((cn = avl_last(&clp->cl_tree)) == NULL)
return (0);
if (clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
@@ -211,11 +205,8 @@ changelist_postfix(prop_changelist_t *clp)
* datasets before mounting the children. We walk all datasets even if
* there are errors.
*/
if ((walk = uu_avl_walk_start(clp->cl_tree,
UU_WALK_REVERSE | UU_WALK_ROBUST)) == NULL)
return (-1);
while ((cn = uu_avl_walk_next(walk)) != NULL) {
for (cn = avl_last(&clp->cl_tree); cn != NULL;
cn = AVL_PREV(&clp->cl_tree, cn)) {
boolean_t sharenfs;
boolean_t sharesmb;
@@ -299,7 +290,6 @@ changelist_postfix(prop_changelist_t *clp)
*p++ = SA_PROTOCOL_SMB;
*p++ = SA_NO_PROTOCOL;
zfs_commit_shares(proto);
uu_avl_walk_end(walk);
return (0);
}
@@ -334,13 +324,10 @@ void
changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
{
prop_changenode_t *cn;
uu_avl_walk_t *walk;
char newname[ZFS_MAX_DATASET_NAME_LEN];
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
return;
while ((cn = uu_avl_walk_next(walk)) != NULL) {
for (cn = avl_first(&clp->cl_tree); cn != NULL;
cn = AVL_NEXT(&clp->cl_tree, cn)) {
/*
* Do not rename a clone that's not in the source hierarchy.
*/
@@ -359,8 +346,6 @@ changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
(void) strlcpy(cn->cn_handle->zfs_name, newname,
sizeof (cn->cn_handle->zfs_name));
}
uu_avl_walk_end(walk);
}
/*
@@ -371,24 +356,20 @@ int
changelist_unshare(prop_changelist_t *clp, const enum sa_protocol *proto)
{
prop_changenode_t *cn;
uu_avl_walk_t *walk;
int ret = 0;
if (clp->cl_prop != ZFS_PROP_SHARENFS &&
clp->cl_prop != ZFS_PROP_SHARESMB)
return (0);
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
return (-1);
while ((cn = uu_avl_walk_next(walk)) != NULL) {
for (cn = avl_first(&clp->cl_tree); cn != NULL;
cn = AVL_NEXT(&clp->cl_tree, cn)) {
if (zfs_unshare(cn->cn_handle, NULL, proto) != 0)
ret = -1;
}
for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
sa_commit_shares(*p);
uu_avl_walk_end(walk);
return (ret);
}
@@ -411,22 +392,16 @@ void
changelist_remove(prop_changelist_t *clp, const char *name)
{
prop_changenode_t *cn;
uu_avl_walk_t *walk;
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
return;
while ((cn = uu_avl_walk_next(walk)) != NULL) {
for (cn = avl_first(&clp->cl_tree); cn != NULL;
cn = AVL_NEXT(&clp->cl_tree, cn)) {
if (strcmp(cn->cn_handle->zfs_name, name) == 0) {
uu_avl_remove(clp->cl_tree, cn);
avl_remove(&clp->cl_tree, cn);
zfs_close(cn->cn_handle);
free(cn);
uu_avl_walk_end(walk);
return;
}
}
uu_avl_walk_end(walk);
}
/*
@@ -436,26 +411,14 @@ void
changelist_free(prop_changelist_t *clp)
{
prop_changenode_t *cn;
void *cookie = NULL;
if (clp->cl_tree) {
uu_avl_walk_t *walk;
if ((walk = uu_avl_walk_start(clp->cl_tree,
UU_WALK_ROBUST)) == NULL)
return;
while ((cn = uu_avl_walk_next(walk)) != NULL) {
uu_avl_remove(clp->cl_tree, cn);
zfs_close(cn->cn_handle);
free(cn);
}
uu_avl_walk_end(walk);
uu_avl_destroy(clp->cl_tree);
while ((cn = avl_destroy_nodes(&clp->cl_tree, &cookie)) != NULL) {
zfs_close(cn->cn_handle);
free(cn);
}
if (clp->cl_pool)
uu_avl_pool_destroy(clp->cl_pool);
avl_destroy(&clp->cl_tree);
free(clp);
}
@@ -467,7 +430,7 @@ changelist_add_mounted(zfs_handle_t *zhp, void *data)
{
prop_changelist_t *clp = data;
prop_changenode_t *cn;
uu_avl_index_t idx;
avl_index_t idx;
ASSERT3U(clp->cl_prop, ==, ZFS_PROP_MOUNTPOINT);
@@ -483,10 +446,8 @@ changelist_add_mounted(zfs_handle_t *zhp, void *data)
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
clp->cl_haszonedchild = B_TRUE;
uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
uu_avl_insert(clp->cl_tree, cn, idx);
if (avl_find(&clp->cl_tree, cn, &idx) == NULL) {
avl_insert(&clp->cl_tree, cn, idx);
} else {
free(cn);
zfs_close(zhp);
@@ -553,12 +514,9 @@ change_one(zfs_handle_t *zhp, void *data)
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
clp->cl_haszonedchild = B_TRUE;
uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
uu_avl_index_t idx;
if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
uu_avl_insert(clp->cl_tree, cn, idx);
avl_index_t idx;
if (avl_find(&clp->cl_tree, cn, &idx) == NULL) {
avl_insert(&clp->cl_tree, cn, idx);
} else {
free(cn);
cn = NULL;
@@ -610,11 +568,11 @@ compare_props(const void *a, const void *b, zfs_prop_t prop)
else if (!haspropa && !haspropb)
return (0);
else
return (strcmp(propb, propa));
return (TREE_ISIGN(strcmp(propb, propa)));
}
static int
compare_mountpoints(const void *a, const void *b, void *unused)
compare_mountpoints(const void *a, const void *b)
{
/*
* When unsharing or unmounting filesystems, we need to do it in
@@ -622,14 +580,12 @@ compare_mountpoints(const void *a, const void *b, void *unused)
* hierarchy that is different from the dataset hierarchy, and still
* allow it to be changed.
*/
(void) unused;
return (compare_props(a, b, ZFS_PROP_MOUNTPOINT));
}
static int
compare_dataset_names(const void *a, const void *b, void *unused)
compare_dataset_names(const void *a, const void *b)
{
(void) unused;
return (compare_props(a, b, ZFS_PROP_NAME));
}
@@ -671,28 +627,14 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
}
}
clp->cl_pool = uu_avl_pool_create("changelist_pool",
avl_create(&clp->cl_tree,
legacy ? compare_dataset_names : compare_mountpoints,
sizeof (prop_changenode_t),
offsetof(prop_changenode_t, cn_treenode),
legacy ? compare_dataset_names : compare_mountpoints, 0);
if (clp->cl_pool == NULL) {
assert(uu_error() == UU_ERROR_NO_MEMORY);
(void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error");
changelist_free(clp);
return (NULL);
}
offsetof(prop_changenode_t, cn_treenode));
clp->cl_tree = uu_avl_create(clp->cl_pool, NULL, UU_DEFAULT);
clp->cl_gflags = gather_flags;
clp->cl_mflags = mnt_flags;
if (clp->cl_tree == NULL) {
assert(uu_error() == UU_ERROR_NO_MEMORY);
(void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error");
changelist_free(clp);
return (NULL);
}
/*
* If this is a rename or the 'zoned' property, we pretend we're
* changing the mountpoint and flag it so we can catch all children in
@@ -778,10 +720,9 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
cn->cn_needpost = B_TRUE;
uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
uu_avl_index_t idx;
if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
uu_avl_insert(clp->cl_tree, cn, idx);
avl_index_t idx;
if (avl_find(&clp->cl_tree, cn, &idx) == NULL) {
avl_insert(&clp->cl_tree, cn, idx);
} else {
free(cn);
zfs_close(temp);
+20 -51
View File
@@ -47,55 +47,37 @@
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include <libuutil.h>
#include "libzfs_impl.h"
typedef struct config_node {
char *cn_name;
nvlist_t *cn_config;
uu_avl_node_t cn_avl;
avl_node_t cn_avl;
} config_node_t;
static int
config_node_compare(const void *a, const void *b, void *unused)
config_node_compare(const void *a, const void *b)
{
(void) unused;
const config_node_t *ca = (config_node_t *)a;
const config_node_t *cb = (config_node_t *)b;
int ret = strcmp(ca->cn_name, cb->cn_name);
if (ret < 0)
return (-1);
else if (ret > 0)
return (1);
else
return (0);
return (TREE_ISIGN(strcmp(ca->cn_name, cb->cn_name)));
}
void
namespace_clear(libzfs_handle_t *hdl)
{
if (hdl->libzfs_ns_avl) {
config_node_t *cn;
void *cookie = NULL;
config_node_t *cn;
void *cookie = NULL;
while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl,
&cookie)) != NULL) {
nvlist_free(cn->cn_config);
free(cn->cn_name);
free(cn);
}
uu_avl_destroy(hdl->libzfs_ns_avl);
hdl->libzfs_ns_avl = NULL;
while ((cn = avl_destroy_nodes(&hdl->libzfs_ns_avl, &cookie)) != NULL) {
nvlist_free(cn->cn_config);
free(cn->cn_name);
free(cn);
}
if (hdl->libzfs_ns_avlpool) {
uu_avl_pool_destroy(hdl->libzfs_ns_avlpool);
hdl->libzfs_ns_avlpool = NULL;
}
avl_destroy(&hdl->libzfs_ns_avl);
}
/*
@@ -111,20 +93,8 @@ namespace_reload(libzfs_handle_t *hdl)
void *cookie;
if (hdl->libzfs_ns_gen == 0) {
/*
* This is the first time we've accessed the configuration
* cache. Initialize the AVL tree and then fall through to the
* common code.
*/
if ((hdl->libzfs_ns_avlpool = uu_avl_pool_create("config_pool",
sizeof (config_node_t),
offsetof(config_node_t, cn_avl),
config_node_compare, UU_DEFAULT)) == NULL)
return (no_memory(hdl));
if ((hdl->libzfs_ns_avl = uu_avl_create(hdl->libzfs_ns_avlpool,
NULL, UU_DEFAULT)) == NULL)
return (no_memory(hdl));
avl_create(&hdl->libzfs_ns_avl, config_node_compare,
sizeof (config_node_t), offsetof(config_node_t, cn_avl));
}
zcmd_alloc_dst_nvlist(hdl, &zc, 0);
@@ -167,7 +137,7 @@ namespace_reload(libzfs_handle_t *hdl)
* Clear out any existing configuration information.
*/
cookie = NULL;
while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, &cookie)) != NULL) {
while ((cn = avl_destroy_nodes(&hdl->libzfs_ns_avl, &cookie)) != NULL) {
nvlist_free(cn->cn_config);
free(cn->cn_name);
free(cn);
@@ -176,7 +146,7 @@ namespace_reload(libzfs_handle_t *hdl)
elem = NULL;
while ((elem = nvlist_next_nvpair(config, elem)) != NULL) {
nvlist_t *child;
uu_avl_index_t where;
avl_index_t where;
cn = zfs_alloc(hdl, sizeof (config_node_t));
cn->cn_name = zfs_strdup(hdl, nvpair_name(elem));
@@ -187,10 +157,9 @@ namespace_reload(libzfs_handle_t *hdl)
nvlist_free(config);
return (no_memory(hdl));
}
verify(uu_avl_find(hdl->libzfs_ns_avl, cn, NULL, &where)
== NULL);
verify(avl_find(&hdl->libzfs_ns_avl, cn, &where) == NULL);
uu_avl_insert(hdl->libzfs_ns_avl, cn, where);
avl_insert(&hdl->libzfs_ns_avl, cn, where);
}
nvlist_free(config);
@@ -400,8 +369,8 @@ zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data)
return (-1);
hdl->libzfs_pool_iter++;
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
for (cn = avl_first(&hdl->libzfs_ns_avl); cn != NULL;
cn = AVL_NEXT(&hdl->libzfs_ns_avl, cn)) {
if (zpool_skip_pool(cn->cn_name))
continue;
@@ -438,8 +407,8 @@ zfs_iter_root(libzfs_handle_t *hdl, zfs_iter_f func, void *data)
if (namespace_reload(hdl) != 0)
return (-1);
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
for (cn = avl_first(&hdl->libzfs_ns_avl); cn != NULL;
cn = AVL_NEXT(&hdl->libzfs_ns_avl, cn)) {
if (zpool_skip_pool(cn->cn_name))
continue;
+1 -3
View File
@@ -36,7 +36,6 @@
#include <sys/zfs_ioctl.h>
#include <regex.h>
#include <libuutil.h>
#include <libzfs.h>
#include <libshare.h>
#include <libzfs_core.h>
@@ -51,8 +50,7 @@ struct libzfs_handle {
int libzfs_error;
int libzfs_fd;
zpool_handle_t *libzfs_pool_handles;
uu_avl_pool_t *libzfs_ns_avlpool;
uu_avl_t *libzfs_ns_avl;
avl_tree_t libzfs_ns_avl;
uint64_t libzfs_ns_gen;
int libzfs_desc_active;
char libzfs_action[1024];