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
+21 -35
View File
@@ -28,7 +28,6 @@
*/
#include <libintl.h>
#include <libuutil.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -50,14 +49,16 @@
* When finished, we have an AVL tree of ZFS handles. We go through and execute
* the provided callback for each one, passing whatever data the user supplied.
*/
typedef struct callback_data callback_data_t;
typedef struct zfs_node {
zfs_handle_t *zn_handle;
uu_avl_node_t zn_avlnode;
callback_data_t *zn_callback;
avl_node_t zn_avlnode;
} zfs_node_t;
typedef struct callback_data {
uu_avl_t *cb_avl;
struct callback_data {
avl_tree_t cb_avl;
int cb_flags;
zfs_type_t cb_types;
zfs_sort_column_t *cb_sortcol;
@@ -65,9 +66,7 @@ typedef struct callback_data {
int cb_depth_limit;
int cb_depth;
uint8_t cb_props_table[ZFS_NUM_PROPS];
} callback_data_t;
uu_avl_pool_t *avl_pool;
};
/*
* Include snaps if they were requested or if this a zfs list where types
@@ -99,13 +98,12 @@ zfs_callback(zfs_handle_t *zhp, void *data)
if ((zfs_get_type(zhp) & cb->cb_types) ||
((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
uu_avl_index_t idx;
avl_index_t idx;
zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
node->zn_handle = zhp;
uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
&idx) == NULL) {
node->zn_callback = cb;
if (avl_find(&cb->cb_avl, node, &idx) == NULL) {
if (cb->cb_proplist) {
if ((*cb->cb_proplist) &&
!(*cb->cb_proplist)->pl_all)
@@ -120,7 +118,7 @@ zfs_callback(zfs_handle_t *zhp, void *data)
return (-1);
}
}
uu_avl_insert(cb->cb_avl, node, idx);
avl_insert(&cb->cb_avl, node, idx);
should_close = B_FALSE;
} else {
free(node);
@@ -286,7 +284,7 @@ zfs_compare(const void *larg, const void *rarg)
if (rat != NULL)
*rat = '\0';
ret = strcmp(lname, rname);
ret = TREE_ISIGN(strcmp(lname, rname));
if (ret == 0 && (lat != NULL || rat != NULL)) {
/*
* If we're comparing a dataset to one of its snapshots, we
@@ -340,11 +338,11 @@ zfs_compare(const void *larg, const void *rarg)
* with snapshots grouped under their parents.
*/
static int
zfs_sort(const void *larg, const void *rarg, void *data)
zfs_sort(const void *larg, const void *rarg)
{
zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
zfs_sort_column_t *sc = (zfs_sort_column_t *)data;
zfs_sort_column_t *sc = ((zfs_node_t *)larg)->zn_callback->cb_sortcol;
zfs_sort_column_t *psc;
for (psc = sc; psc != NULL; psc = psc->sc_next) {
@@ -414,7 +412,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
return (-1);
if (lstr)
ret = strcmp(lstr, rstr);
ret = TREE_ISIGN(strcmp(lstr, rstr));
else if (lnum < rnum)
ret = -1;
else if (lnum > rnum)
@@ -438,13 +436,6 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
callback_data_t cb = {0};
int ret = 0;
zfs_node_t *node;
uu_avl_walk_t *walk;
avl_pool = uu_avl_pool_create("zfs_pool", sizeof (zfs_node_t),
offsetof(zfs_node_t, zn_avlnode), zfs_sort, UU_DEFAULT);
if (avl_pool == NULL)
nomem();
cb.cb_sortcol = sortcol;
cb.cb_flags = flags;
@@ -489,8 +480,8 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
sizeof (cb.cb_props_table));
}
if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL)
nomem();
avl_create(&cb.cb_avl, zfs_sort,
sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
if (argc == 0) {
/*
@@ -531,25 +522,20 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
* At this point we've got our AVL tree full of zfs handles, so iterate
* over each one and execute the real user callback.
*/
for (node = uu_avl_first(cb.cb_avl); node != NULL;
node = uu_avl_next(cb.cb_avl, node))
for (node = avl_first(&cb.cb_avl); node != NULL;
node = AVL_NEXT(&cb.cb_avl, node))
ret |= callback(node->zn_handle, data);
/*
* Finally, clean up the AVL tree.
*/
if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL)
nomem();
while ((node = uu_avl_walk_next(walk)) != NULL) {
uu_avl_remove(cb.cb_avl, node);
void *cookie = NULL;
while ((node = avl_destroy_nodes(&cb.cb_avl, &cookie)) != NULL) {
zfs_close(node->zn_handle);
free(node);
}
uu_avl_walk_end(walk);
uu_avl_destroy(cb.cb_avl);
uu_avl_pool_destroy(avl_pool);
avl_destroy(&cb.cb_avl);
return (ret);
}
+107 -215
View File
@@ -2846,31 +2846,27 @@ static int us_type_bits[] = {
static const char *const us_type_names[] = { "posixgroup", "posixuser",
"smbgroup", "smbuser", "all" };
typedef struct us_cbdata us_cbdata_t;
typedef struct us_node {
nvlist_t *usn_nvl;
uu_avl_node_t usn_avlnode;
us_cbdata_t *usn_cbdata;
avl_node_t usn_avlnode;
uu_list_node_t usn_listnode;
} us_node_t;
typedef struct us_cbdata {
struct us_cbdata {
nvlist_t **cb_nvlp;
uu_avl_pool_t *cb_avl_pool;
uu_avl_t *cb_avl;
avl_tree_t cb_avl;
boolean_t cb_numname;
boolean_t cb_nicenum;
boolean_t cb_sid2posix;
zfs_userquota_prop_t cb_prop;
zfs_sort_column_t *cb_sortcol;
size_t cb_width[USFIELD_LAST];
} us_cbdata_t;
};
static boolean_t us_populated = B_FALSE;
typedef struct {
zfs_sort_column_t *si_sortcol;
boolean_t si_numname;
} us_sort_info_t;
static int
us_field_index(const char *field)
{
@@ -2883,13 +2879,12 @@ us_field_index(const char *field)
}
static int
us_compare(const void *larg, const void *rarg, void *unused)
us_compare(const void *larg, const void *rarg)
{
const us_node_t *l = larg;
const us_node_t *r = rarg;
us_sort_info_t *si = (us_sort_info_t *)unused;
zfs_sort_column_t *sortcol = si->si_sortcol;
boolean_t numname = si->si_numname;
zfs_sort_column_t *sortcol = l->usn_cbdata->cb_sortcol;
boolean_t numname = l->usn_cbdata->cb_numname;
nvlist_t *lnvl = l->usn_nvl;
nvlist_t *rnvl = r->usn_nvl;
int rc = 0;
@@ -3023,25 +3018,22 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space,
const char *propname;
char sizebuf[32];
us_node_t *node;
uu_avl_pool_t *avl_pool = cb->cb_avl_pool;
uu_avl_t *avl = cb->cb_avl;
uu_avl_index_t idx;
avl_tree_t *avl = &cb->cb_avl;
avl_index_t idx;
nvlist_t *props;
us_node_t *n;
zfs_sort_column_t *sortcol = cb->cb_sortcol;
unsigned type = 0;
const char *typestr;
size_t namelen;
size_t typelen;
size_t sizelen;
int typeidx, nameidx, sizeidx;
us_sort_info_t sortinfo = { sortcol, cb->cb_numname };
boolean_t smbentity = B_FALSE;
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
nomem();
node = safe_malloc(sizeof (us_node_t));
uu_avl_node_init(node, &node->usn_avlnode, avl_pool);
node->usn_cbdata = cb;
node->usn_nvl = props;
if (domain != NULL && domain[0] != '\0') {
@@ -3143,8 +3135,8 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space,
* Check if this type/name combination is in the list and update it;
* otherwise add new node to the list.
*/
if ((n = uu_avl_find(avl, node, &sortinfo, &idx)) == NULL) {
uu_avl_insert(avl, node, idx);
if ((n = avl_find(avl, node, &idx)) == NULL) {
avl_insert(avl, node, idx);
} else {
nvlist_free(props);
free(node);
@@ -3318,7 +3310,7 @@ print_us_node(boolean_t scripted, boolean_t parsable, int *fields, int types,
static void
print_us(boolean_t scripted, boolean_t parsable, int *fields, int types,
size_t *width, boolean_t rmnode, uu_avl_t *avl)
size_t *width, boolean_t rmnode, avl_tree_t *avl)
{
us_node_t *node;
const char *col;
@@ -3343,7 +3335,7 @@ print_us(boolean_t scripted, boolean_t parsable, int *fields, int types,
(void) printf("\n");
}
for (node = uu_avl_first(avl); node; node = uu_avl_next(avl, node)) {
for (node = avl_first(avl); node; node = AVL_NEXT(avl, node)) {
print_us_node(scripted, parsable, fields, types, width, node);
if (rmnode)
nvlist_free(node->usn_nvl);
@@ -3355,9 +3347,6 @@ zfs_do_userspace(int argc, char **argv)
{
zfs_handle_t *zhp;
zfs_userquota_prop_t p;
uu_avl_pool_t *avl_pool;
uu_avl_t *avl_tree;
uu_avl_walk_t *walk;
char *delim;
char deffields[] = "type,name,used,quota,objused,objquota";
char *ofield = NULL;
@@ -3378,7 +3367,7 @@ zfs_do_userspace(int argc, char **argv)
us_node_t *rmnode;
uu_list_pool_t *listpool;
uu_list_t *list;
uu_avl_index_t idx = 0;
avl_index_t idx = 0;
uu_list_index_t idx2 = 0;
if (argc < 2)
@@ -3513,12 +3502,6 @@ zfs_do_userspace(int argc, char **argv)
return (1);
}
if ((avl_pool = uu_avl_pool_create("us_avl_pool", sizeof (us_node_t),
offsetof(us_node_t, usn_avlnode), us_compare, UU_DEFAULT)) == NULL)
nomem();
if ((avl_tree = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL)
nomem();
/* Always add default sorting columns */
(void) zfs_add_sort_column(&sortcol, "type", B_FALSE);
(void) zfs_add_sort_column(&sortcol, "name", B_FALSE);
@@ -3526,10 +3509,12 @@ zfs_do_userspace(int argc, char **argv)
cb.cb_sortcol = sortcol;
cb.cb_numname = prtnum;
cb.cb_nicenum = !parsable;
cb.cb_avl_pool = avl_pool;
cb.cb_avl = avl_tree;
cb.cb_sid2posix = sid2posix;
avl_create(&cb.cb_avl, us_compare,
sizeof (us_node_t), offsetof(us_node_t, usn_avlnode));
for (i = 0; i < USFIELD_LAST; i++)
cb.cb_width[i] = strlen(gettext(us_field_hdr[i]));
@@ -3544,14 +3529,17 @@ zfs_do_userspace(int argc, char **argv)
cb.cb_prop = p;
if ((ret = zfs_userspace(zhp, p, userspace_cb, &cb)) != 0) {
zfs_close(zhp);
avl_destroy(&cb.cb_avl);
return (ret);
}
}
zfs_close(zhp);
/* Sort the list */
if ((node = uu_avl_first(avl_tree)) == NULL)
if ((node = avl_first(&cb.cb_avl)) == NULL) {
avl_destroy(&cb.cb_avl);
return (0);
}
us_populated = B_TRUE;
@@ -3562,18 +3550,17 @@ zfs_do_userspace(int argc, char **argv)
while (node != NULL) {
rmnode = node;
node = uu_avl_next(avl_tree, node);
uu_avl_remove(avl_tree, rmnode);
node = AVL_NEXT(&cb.cb_avl, node);
avl_remove(&cb.cb_avl, rmnode);
if (uu_list_find(list, rmnode, NULL, &idx2) == NULL)
uu_list_insert(list, rmnode, idx2);
}
for (node = uu_list_first(list); node != NULL;
node = uu_list_next(list, node)) {
us_sort_info_t sortinfo = { sortcol, cb.cb_numname };
if (uu_avl_find(avl_tree, node, &sortinfo, &idx) == NULL)
uu_avl_insert(avl_tree, node, idx);
if (avl_find(&cb.cb_avl, node, &idx) == NULL)
avl_insert(&cb.cb_avl, node, idx);
}
uu_list_destroy(list);
@@ -3581,22 +3568,16 @@ zfs_do_userspace(int argc, char **argv)
/* Print and free node nvlist memory */
print_us(scripted, parsable, fields, types, cb.cb_width, B_TRUE,
cb.cb_avl);
&cb.cb_avl);
zfs_free_sort_columns(sortcol);
/* Clean up the AVL tree */
if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL)
nomem();
while ((node = uu_avl_walk_next(walk)) != NULL) {
uu_avl_remove(cb.cb_avl, node);
void *cookie = NULL;
while ((node = avl_destroy_nodes(&cb.cb_avl, &cookie)) != NULL) {
free(node);
}
uu_avl_walk_end(walk);
uu_avl_destroy(avl_tree);
uu_avl_pool_destroy(avl_pool);
avl_destroy(&cb.cb_avl);
return (ret);
}
@@ -5401,7 +5382,7 @@ typedef struct deleg_perm {
typedef struct deleg_perm_node {
deleg_perm_t dpn_perm;
uu_avl_node_t dpn_avl_node;
avl_node_t dpn_avl_node;
} deleg_perm_node_t;
typedef struct fs_perm fs_perm_t;
@@ -5413,13 +5394,13 @@ typedef struct who_perm {
char who_ug_name[256]; /* user/group name */
fs_perm_t *who_fsperm; /* uplink */
uu_avl_t *who_deleg_perm_avl; /* permissions */
avl_tree_t who_deleg_perm_avl; /* permissions */
} who_perm_t;
/* */
typedef struct who_perm_node {
who_perm_t who_perm;
uu_avl_node_t who_avl_node;
avl_node_t who_avl_node;
} who_perm_node_t;
typedef struct fs_perm_set fs_perm_set_t;
@@ -5427,8 +5408,8 @@ typedef struct fs_perm_set fs_perm_set_t;
struct fs_perm {
const char *fsp_name;
uu_avl_t *fsp_sc_avl; /* sets,create */
uu_avl_t *fsp_uge_avl; /* user,group,everyone */
avl_tree_t fsp_sc_avl; /* sets,create */
avl_tree_t fsp_uge_avl; /* user,group,everyone */
fs_perm_set_t *fsp_set; /* uplink */
};
@@ -5436,7 +5417,7 @@ struct fs_perm {
/* */
typedef struct fs_perm_node {
fs_perm_t fspn_fsperm;
uu_avl_t *fspn_avl;
avl_tree_t fspn_avl;
uu_list_node_t fspn_list_node;
} fs_perm_node_t;
@@ -5445,10 +5426,6 @@ typedef struct fs_perm_node {
struct fs_perm_set {
uu_list_pool_t *fsps_list_pool;
uu_list_t *fsps_list; /* list of fs_perms */
uu_avl_pool_t *fsps_named_set_avl_pool;
uu_avl_pool_t *fsps_who_perm_avl_pool;
uu_avl_pool_t *fsps_deleg_perm_avl_pool;
};
static inline const char *
@@ -5511,9 +5488,8 @@ who_type2weight(zfs_deleg_who_type_t who_type)
}
static int
who_perm_compare(const void *larg, const void *rarg, void *unused)
who_perm_compare(const void *larg, const void *rarg)
{
(void) unused;
const who_perm_node_t *l = larg;
const who_perm_node_t *r = rarg;
zfs_deleg_who_type_t ltype = l->who_perm.who_type;
@@ -5524,31 +5500,16 @@ who_perm_compare(const void *larg, const void *rarg, void *unused)
if (res == 0)
res = strncmp(l->who_perm.who_name, r->who_perm.who_name,
ZFS_MAX_DELEG_NAME-1);
if (res == 0)
return (0);
if (res > 0)
return (1);
else
return (-1);
return (TREE_ISIGN(res));
}
static int
deleg_perm_compare(const void *larg, const void *rarg, void *unused)
deleg_perm_compare(const void *larg, const void *rarg)
{
(void) unused;
const deleg_perm_node_t *l = larg;
const deleg_perm_node_t *r = rarg;
int res = strncmp(l->dpn_perm.dp_name, r->dpn_perm.dp_name,
ZFS_MAX_DELEG_NAME-1);
if (res == 0)
return (0);
if (res > 0)
return (1);
else
return (-1);
return (TREE_ISIGN(strncmp(l->dpn_perm.dp_name, r->dpn_perm.dp_name,
ZFS_MAX_DELEG_NAME-1)));
}
static inline void
@@ -5563,24 +5524,6 @@ fs_perm_set_init(fs_perm_set_t *fspset)
if ((fspset->fsps_list = uu_list_create(fspset->fsps_list_pool, NULL,
UU_DEFAULT)) == NULL)
nomem();
if ((fspset->fsps_named_set_avl_pool = uu_avl_pool_create(
"named_set_avl_pool", sizeof (who_perm_node_t), offsetof(
who_perm_node_t, who_avl_node), who_perm_compare,
UU_DEFAULT)) == NULL)
nomem();
if ((fspset->fsps_who_perm_avl_pool = uu_avl_pool_create(
"who_perm_avl_pool", sizeof (who_perm_node_t), offsetof(
who_perm_node_t, who_avl_node), who_perm_compare,
UU_DEFAULT)) == NULL)
nomem();
if ((fspset->fsps_deleg_perm_avl_pool = uu_avl_pool_create(
"deleg_perm_avl_pool", sizeof (deleg_perm_node_t), offsetof(
deleg_perm_node_t, dpn_avl_node), deleg_perm_compare, UU_DEFAULT))
== NULL)
nomem();
}
static inline void fs_perm_fini(fs_perm_t *);
@@ -5600,10 +5543,6 @@ fs_perm_set_fini(fs_perm_set_t *fspset)
free(node);
node = next_node;
}
uu_avl_pool_destroy(fspset->fsps_named_set_avl_pool);
uu_avl_pool_destroy(fspset->fsps_who_perm_avl_pool);
uu_avl_pool_destroy(fspset->fsps_deleg_perm_avl_pool);
}
static inline void
@@ -5618,14 +5557,11 @@ static inline void
who_perm_init(who_perm_t *who_perm, fs_perm_t *fsperm,
zfs_deleg_who_type_t type, const char *name)
{
uu_avl_pool_t *pool;
pool = fsperm->fsp_set->fsps_deleg_perm_avl_pool;
memset(who_perm, 0, sizeof (who_perm_t));
if ((who_perm->who_deleg_perm_avl = uu_avl_create(pool, NULL,
UU_DEFAULT)) == NULL)
nomem();
avl_create(&who_perm->who_deleg_perm_avl, deleg_perm_compare,
sizeof (deleg_perm_node_t),
offsetof(deleg_perm_node_t, dpn_avl_node));
who_perm->who_type = type;
who_perm->who_name = name;
@@ -5635,35 +5571,26 @@ who_perm_init(who_perm_t *who_perm, fs_perm_t *fsperm,
static inline void
who_perm_fini(who_perm_t *who_perm)
{
deleg_perm_node_t *node = uu_avl_first(who_perm->who_deleg_perm_avl);
deleg_perm_node_t *node;
void *cookie = NULL;
while (node != NULL) {
deleg_perm_node_t *next_node =
uu_avl_next(who_perm->who_deleg_perm_avl, node);
uu_avl_remove(who_perm->who_deleg_perm_avl, node);
while ((node = avl_destroy_nodes(&who_perm->who_deleg_perm_avl,
&cookie)) != NULL) {
free(node);
node = next_node;
}
uu_avl_destroy(who_perm->who_deleg_perm_avl);
avl_destroy(&who_perm->who_deleg_perm_avl);
}
static inline void
fs_perm_init(fs_perm_t *fsperm, fs_perm_set_t *fspset, const char *fsname)
{
uu_avl_pool_t *nset_pool = fspset->fsps_named_set_avl_pool;
uu_avl_pool_t *who_pool = fspset->fsps_who_perm_avl_pool;
memset(fsperm, 0, sizeof (fs_perm_t));
if ((fsperm->fsp_sc_avl = uu_avl_create(nset_pool, NULL, UU_DEFAULT))
== NULL)
nomem();
if ((fsperm->fsp_uge_avl = uu_avl_create(who_pool, NULL, UU_DEFAULT))
== NULL)
nomem();
avl_create(&fsperm->fsp_sc_avl, who_perm_compare,
sizeof (who_perm_node_t), offsetof(who_perm_node_t, who_avl_node));
avl_create(&fsperm->fsp_uge_avl, who_perm_compare,
sizeof (who_perm_node_t), offsetof(who_perm_node_t, who_avl_node));
fsperm->fsp_set = fspset;
fsperm->fsp_name = fsname;
@@ -5672,46 +5599,41 @@ fs_perm_init(fs_perm_t *fsperm, fs_perm_set_t *fspset, const char *fsname)
static inline void
fs_perm_fini(fs_perm_t *fsperm)
{
who_perm_node_t *node = uu_avl_first(fsperm->fsp_sc_avl);
while (node != NULL) {
who_perm_node_t *next_node = uu_avl_next(fsperm->fsp_sc_avl,
node);
who_perm_node_t *node;
void *cookie = NULL;
while ((node = avl_destroy_nodes(&fsperm->fsp_sc_avl,
&cookie)) != NULL) {
who_perm_t *who_perm = &node->who_perm;
who_perm_fini(who_perm);
uu_avl_remove(fsperm->fsp_sc_avl, node);
free(node);
node = next_node;
}
node = uu_avl_first(fsperm->fsp_uge_avl);
while (node != NULL) {
who_perm_node_t *next_node = uu_avl_next(fsperm->fsp_uge_avl,
node);
cookie = NULL;
while ((node = avl_destroy_nodes(&fsperm->fsp_uge_avl,
&cookie)) != NULL) {
who_perm_t *who_perm = &node->who_perm;
who_perm_fini(who_perm);
uu_avl_remove(fsperm->fsp_uge_avl, node);
free(node);
node = next_node;
}
uu_avl_destroy(fsperm->fsp_sc_avl);
uu_avl_destroy(fsperm->fsp_uge_avl);
avl_destroy(&fsperm->fsp_sc_avl);
avl_destroy(&fsperm->fsp_uge_avl);
}
static void
set_deleg_perm_node(uu_avl_t *avl, deleg_perm_node_t *node,
set_deleg_perm_node(avl_tree_t *avl, deleg_perm_node_t *node,
zfs_deleg_who_type_t who_type, const char *name, char locality)
{
uu_avl_index_t idx = 0;
avl_index_t idx = 0;
deleg_perm_node_t *found_node = NULL;
deleg_perm_t *deleg_perm = &node->dpn_perm;
deleg_perm_init(deleg_perm, who_type, name);
if ((found_node = uu_avl_find(avl, node, NULL, &idx))
== NULL)
uu_avl_insert(avl, node, idx);
if ((found_node = avl_find(avl, node, &idx)) == NULL)
avl_insert(avl, node, idx);
else {
node = found_node;
deleg_perm = &node->dpn_perm;
@@ -5736,20 +5658,17 @@ static inline int
parse_who_perm(who_perm_t *who_perm, nvlist_t *nvl, char locality)
{
nvpair_t *nvp = NULL;
fs_perm_set_t *fspset = who_perm->who_fsperm->fsp_set;
uu_avl_t *avl = who_perm->who_deleg_perm_avl;
avl_tree_t *avl = &who_perm->who_deleg_perm_avl;
zfs_deleg_who_type_t who_type = who_perm->who_type;
while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
const char *name = nvpair_name(nvp);
data_type_t type = nvpair_type(nvp);
uu_avl_pool_t *avl_pool = fspset->fsps_deleg_perm_avl_pool;
deleg_perm_node_t *node =
safe_malloc(sizeof (deleg_perm_node_t));
VERIFY(type == DATA_TYPE_BOOLEAN);
uu_avl_node_init(node, &node->dpn_avl_node, avl_pool);
set_deleg_perm_node(avl, node, who_type, name, locality);
}
@@ -5760,13 +5679,11 @@ static inline int
parse_fs_perm(fs_perm_t *fsperm, nvlist_t *nvl)
{
nvpair_t *nvp = NULL;
fs_perm_set_t *fspset = fsperm->fsp_set;
while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
nvlist_t *nvl2 = NULL;
const char *name = nvpair_name(nvp);
uu_avl_t *avl = NULL;
uu_avl_pool_t *avl_pool = NULL;
avl_tree_t *avl = NULL;
zfs_deleg_who_type_t perm_type = name[0];
char perm_locality = name[1];
const char *perm_name = name + 3;
@@ -5782,8 +5699,7 @@ parse_fs_perm(fs_perm_t *fsperm, nvlist_t *nvl)
case ZFS_DELEG_CREATE_SETS:
case ZFS_DELEG_NAMED_SET:
case ZFS_DELEG_NAMED_SET_SETS:
avl_pool = fspset->fsps_named_set_avl_pool;
avl = fsperm->fsp_sc_avl;
avl = &fsperm->fsp_sc_avl;
break;
case ZFS_DELEG_USER:
case ZFS_DELEG_USER_SETS:
@@ -5791,8 +5707,7 @@ parse_fs_perm(fs_perm_t *fsperm, nvlist_t *nvl)
case ZFS_DELEG_GROUP_SETS:
case ZFS_DELEG_EVERYONE:
case ZFS_DELEG_EVERYONE_SETS:
avl_pool = fspset->fsps_who_perm_avl_pool;
avl = fsperm->fsp_uge_avl;
avl = &fsperm->fsp_uge_avl;
break;
default:
@@ -5803,14 +5718,12 @@ parse_fs_perm(fs_perm_t *fsperm, nvlist_t *nvl)
who_perm_node_t *node = safe_malloc(
sizeof (who_perm_node_t));
who_perm = &node->who_perm;
uu_avl_index_t idx = 0;
avl_index_t idx = 0;
uu_avl_node_init(node, &node->who_avl_node, avl_pool);
who_perm_init(who_perm, fsperm, perm_type, perm_name);
if ((found_node = uu_avl_find(avl, node, NULL, &idx))
== NULL) {
if (avl == fsperm->fsp_uge_avl) {
if ((found_node = avl_find(avl, node, &idx)) == NULL) {
if (avl == &fsperm->fsp_uge_avl) {
uid_t rid = 0;
struct passwd *p = NULL;
struct group *g = NULL;
@@ -5849,7 +5762,7 @@ parse_fs_perm(fs_perm_t *fsperm, nvlist_t *nvl)
}
}
uu_avl_insert(avl, node, idx);
avl_insert(avl, node, idx);
} else {
node = found_node;
who_perm = &node->who_perm;
@@ -5866,7 +5779,7 @@ static inline int
parse_fs_perm_set(fs_perm_set_t *fspset, nvlist_t *nvl)
{
nvpair_t *nvp = NULL;
uu_avl_index_t idx = 0;
avl_index_t idx = 0;
while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
nvlist_t *nvl2 = NULL;
@@ -6442,7 +6355,7 @@ construct_fsacl_list(boolean_t un, struct allow_opts *opts, nvlist_t **nvlp)
}
static void
print_set_creat_perms(uu_avl_t *who_avl)
print_set_creat_perms(avl_tree_t *who_avl)
{
const char *sc_title[] = {
gettext("Permission sets:\n"),
@@ -6452,9 +6365,9 @@ print_set_creat_perms(uu_avl_t *who_avl)
who_perm_node_t *who_node = NULL;
int prev_weight = -1;
for (who_node = uu_avl_first(who_avl); who_node != NULL;
who_node = uu_avl_next(who_avl, who_node)) {
uu_avl_t *avl = who_node->who_perm.who_deleg_perm_avl;
for (who_node = avl_first(who_avl); who_node != NULL;
who_node = AVL_NEXT(who_avl, who_node)) {
avl_tree_t *avl = &who_node->who_perm.who_deleg_perm_avl;
zfs_deleg_who_type_t who_type = who_node->who_perm.who_type;
const char *who_name = who_node->who_perm.who_name;
int weight = who_type2weight(who_type);
@@ -6471,8 +6384,8 @@ print_set_creat_perms(uu_avl_t *who_avl)
else
(void) printf("\t%s ", who_name);
for (deleg_node = uu_avl_first(avl); deleg_node != NULL;
deleg_node = uu_avl_next(avl, deleg_node)) {
for (deleg_node = avl_first(avl); deleg_node != NULL;
deleg_node = AVL_NEXT(avl, deleg_node)) {
if (first) {
(void) printf("%s",
deleg_node->dpn_perm.dp_name);
@@ -6487,28 +6400,24 @@ print_set_creat_perms(uu_avl_t *who_avl)
}
static void
print_uge_deleg_perms(uu_avl_t *who_avl, boolean_t local, boolean_t descend,
print_uge_deleg_perms(avl_tree_t *who_avl, boolean_t local, boolean_t descend,
const char *title)
{
who_perm_node_t *who_node = NULL;
boolean_t prt_title = B_TRUE;
uu_avl_walk_t *walk;
if ((walk = uu_avl_walk_start(who_avl, UU_WALK_ROBUST)) == NULL)
nomem();
while ((who_node = uu_avl_walk_next(walk)) != NULL) {
for (who_node = avl_first(who_avl); who_node != NULL;
who_node = AVL_NEXT(who_avl, who_node)) {
const char *who_name = who_node->who_perm.who_name;
const char *nice_who_name = who_node->who_perm.who_ug_name;
uu_avl_t *avl = who_node->who_perm.who_deleg_perm_avl;
avl_tree_t *avl = &who_node->who_perm.who_deleg_perm_avl;
zfs_deleg_who_type_t who_type = who_node->who_perm.who_type;
char delim = ' ';
deleg_perm_node_t *deleg_node;
boolean_t prt_who = B_TRUE;
for (deleg_node = uu_avl_first(avl);
deleg_node != NULL;
deleg_node = uu_avl_next(avl, deleg_node)) {
for (deleg_node = avl_first(avl); deleg_node != NULL;
deleg_node = AVL_NEXT(avl, deleg_node)) {
if (local != deleg_node->dpn_perm.dp_local ||
descend != deleg_node->dpn_perm.dp_descend)
continue;
@@ -6558,8 +6467,6 @@ print_uge_deleg_perms(uu_avl_t *who_avl, boolean_t local, boolean_t descend,
if (!prt_who)
(void) printf("\n");
}
uu_avl_walk_end(walk);
}
static void
@@ -6571,8 +6478,8 @@ print_fs_perms(fs_perm_set_t *fspset)
for (node = uu_list_first(fspset->fsps_list); node != NULL;
node = uu_list_next(fspset->fsps_list, node)) {
uu_avl_t *sc_avl = node->fspn_fsperm.fsp_sc_avl;
uu_avl_t *uge_avl = node->fspn_fsperm.fsp_uge_avl;
avl_tree_t *sc_avl = &node->fspn_fsperm.fsp_sc_avl;
avl_tree_t *uge_avl = &node->fspn_fsperm.fsp_uge_avl;
int left = 0;
(void) snprintf(buf, sizeof (buf),
@@ -6594,7 +6501,7 @@ print_fs_perms(fs_perm_set_t *fspset)
}
}
static fs_perm_set_t fs_perm_set = { NULL, NULL, NULL, NULL };
static fs_perm_set_t fs_perm_set = {};
struct deleg_perms {
boolean_t un;
@@ -7726,17 +7633,16 @@ zfs_do_share(int argc, char **argv)
typedef struct unshare_unmount_node {
zfs_handle_t *un_zhp;
char *un_mountp;
uu_avl_node_t un_avlnode;
avl_node_t un_avlnode;
} unshare_unmount_node_t;
static int
unshare_unmount_compare(const void *larg, const void *rarg, void *unused)
unshare_unmount_compare(const void *larg, const void *rarg)
{
(void) unused;
const unshare_unmount_node_t *l = larg;
const unshare_unmount_node_t *r = rarg;
return (strcmp(l->un_mountp, r->un_mountp));
return (TREE_ISIGN(strcmp(l->un_mountp, r->un_mountp)));
}
/*
@@ -7918,11 +7824,9 @@ unshare_unmount(int op, int argc, char **argv)
*/
FILE *mnttab;
struct mnttab entry;
uu_avl_pool_t *pool;
uu_avl_t *tree = NULL;
avl_tree_t tree;
unshare_unmount_node_t *node;
uu_avl_index_t idx;
uu_avl_walk_t *walk;
avl_index_t idx;
enum sa_protocol *protocol = NULL,
single_protocol[] = {SA_NO_PROTOCOL, SA_NO_PROTOCOL};
@@ -7938,16 +7842,12 @@ unshare_unmount(int op, int argc, char **argv)
usage(B_FALSE);
}
if (((pool = uu_avl_pool_create("unmount_pool",
avl_create(&tree, unshare_unmount_compare,
sizeof (unshare_unmount_node_t),
offsetof(unshare_unmount_node_t, un_avlnode),
unshare_unmount_compare, UU_DEFAULT)) == NULL) ||
((tree = uu_avl_create(pool, NULL, UU_DEFAULT)) == NULL))
nomem();
offsetof(unshare_unmount_node_t, un_avlnode));
if ((mnttab = fopen(MNTTAB, "re")) == NULL) {
uu_avl_destroy(tree);
uu_avl_pool_destroy(pool);
avl_destroy(&tree);
return (ENOENT);
}
@@ -8012,10 +7912,8 @@ unshare_unmount(int op, int argc, char **argv)
node->un_zhp = zhp;
node->un_mountp = safe_strdup(entry.mnt_mountp);
uu_avl_node_init(node, &node->un_avlnode, pool);
if (uu_avl_find(tree, node, NULL, &idx) == NULL) {
uu_avl_insert(tree, node, idx);
if (avl_find(&tree, node, &idx) == NULL) {
avl_insert(&tree, node, idx);
} else {
zfs_close(node->un_zhp);
free(node->un_mountp);
@@ -8028,14 +7926,10 @@ unshare_unmount(int op, int argc, char **argv)
* Walk the AVL tree in reverse, unmounting each filesystem and
* removing it from the AVL tree in the process.
*/
if ((walk = uu_avl_walk_start(tree,
UU_WALK_REVERSE | UU_WALK_ROBUST)) == NULL)
nomem();
while ((node = uu_avl_walk_next(walk)) != NULL) {
while ((node = avl_last(&tree)) != NULL) {
const char *mntarg = NULL;
uu_avl_remove(tree, node);
avl_remove(&tree, node);
switch (op) {
case OP_SHARE:
if (zfs_unshare(node->un_zhp,
@@ -8058,9 +7952,7 @@ unshare_unmount(int op, int argc, char **argv)
if (op == OP_SHARE)
zfs_commit_shares(protocol);
uu_avl_walk_end(walk);
uu_avl_destroy(tree);
uu_avl_pool_destroy(pool);
avl_destroy(&tree);
} else {
if (argc != 1) {