mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-31 11:14:09 +03:00
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:
committed by
Brian Behlendorf
parent
e63d026b91
commit
b593748287
+21
-35
@@ -28,7 +28,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <libuutil.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -50,14 +49,16 @@
|
|||||||
* When finished, we have an AVL tree of ZFS handles. We go through and execute
|
* 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.
|
* the provided callback for each one, passing whatever data the user supplied.
|
||||||
*/
|
*/
|
||||||
|
typedef struct callback_data callback_data_t;
|
||||||
|
|
||||||
typedef struct zfs_node {
|
typedef struct zfs_node {
|
||||||
zfs_handle_t *zn_handle;
|
zfs_handle_t *zn_handle;
|
||||||
uu_avl_node_t zn_avlnode;
|
callback_data_t *zn_callback;
|
||||||
|
avl_node_t zn_avlnode;
|
||||||
} zfs_node_t;
|
} zfs_node_t;
|
||||||
|
|
||||||
typedef struct callback_data {
|
struct callback_data {
|
||||||
uu_avl_t *cb_avl;
|
avl_tree_t cb_avl;
|
||||||
int cb_flags;
|
int cb_flags;
|
||||||
zfs_type_t cb_types;
|
zfs_type_t cb_types;
|
||||||
zfs_sort_column_t *cb_sortcol;
|
zfs_sort_column_t *cb_sortcol;
|
||||||
@@ -65,9 +66,7 @@ typedef struct callback_data {
|
|||||||
int cb_depth_limit;
|
int cb_depth_limit;
|
||||||
int cb_depth;
|
int cb_depth;
|
||||||
uint8_t cb_props_table[ZFS_NUM_PROPS];
|
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
|
* 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) ||
|
if ((zfs_get_type(zhp) & cb->cb_types) ||
|
||||||
((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
|
((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));
|
zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
|
||||||
|
|
||||||
node->zn_handle = zhp;
|
node->zn_handle = zhp;
|
||||||
uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
|
node->zn_callback = cb;
|
||||||
if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
|
if (avl_find(&cb->cb_avl, node, &idx) == NULL) {
|
||||||
&idx) == NULL) {
|
|
||||||
if (cb->cb_proplist) {
|
if (cb->cb_proplist) {
|
||||||
if ((*cb->cb_proplist) &&
|
if ((*cb->cb_proplist) &&
|
||||||
!(*cb->cb_proplist)->pl_all)
|
!(*cb->cb_proplist)->pl_all)
|
||||||
@@ -120,7 +118,7 @@ zfs_callback(zfs_handle_t *zhp, void *data)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uu_avl_insert(cb->cb_avl, node, idx);
|
avl_insert(&cb->cb_avl, node, idx);
|
||||||
should_close = B_FALSE;
|
should_close = B_FALSE;
|
||||||
} else {
|
} else {
|
||||||
free(node);
|
free(node);
|
||||||
@@ -286,7 +284,7 @@ zfs_compare(const void *larg, const void *rarg)
|
|||||||
if (rat != NULL)
|
if (rat != NULL)
|
||||||
*rat = '\0';
|
*rat = '\0';
|
||||||
|
|
||||||
ret = strcmp(lname, rname);
|
ret = TREE_ISIGN(strcmp(lname, rname));
|
||||||
if (ret == 0 && (lat != NULL || rat != NULL)) {
|
if (ret == 0 && (lat != NULL || rat != NULL)) {
|
||||||
/*
|
/*
|
||||||
* If we're comparing a dataset to one of its snapshots, we
|
* 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.
|
* with snapshots grouped under their parents.
|
||||||
*/
|
*/
|
||||||
static int
|
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 *l = ((zfs_node_t *)larg)->zn_handle;
|
||||||
zfs_handle_t *r = ((zfs_node_t *)rarg)->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;
|
zfs_sort_column_t *psc;
|
||||||
|
|
||||||
for (psc = sc; psc != NULL; psc = psc->sc_next) {
|
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);
|
return (-1);
|
||||||
|
|
||||||
if (lstr)
|
if (lstr)
|
||||||
ret = strcmp(lstr, rstr);
|
ret = TREE_ISIGN(strcmp(lstr, rstr));
|
||||||
else if (lnum < rnum)
|
else if (lnum < rnum)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
else if (lnum > rnum)
|
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};
|
callback_data_t cb = {0};
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
zfs_node_t *node;
|
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_sortcol = sortcol;
|
||||||
cb.cb_flags = flags;
|
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));
|
sizeof (cb.cb_props_table));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL)
|
avl_create(&cb.cb_avl, zfs_sort,
|
||||||
nomem();
|
sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
|
||||||
|
|
||||||
if (argc == 0) {
|
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
|
* At this point we've got our AVL tree full of zfs handles, so iterate
|
||||||
* over each one and execute the real user callback.
|
* over each one and execute the real user callback.
|
||||||
*/
|
*/
|
||||||
for (node = uu_avl_first(cb.cb_avl); node != NULL;
|
for (node = avl_first(&cb.cb_avl); node != NULL;
|
||||||
node = uu_avl_next(cb.cb_avl, node))
|
node = AVL_NEXT(&cb.cb_avl, node))
|
||||||
ret |= callback(node->zn_handle, data);
|
ret |= callback(node->zn_handle, data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finally, clean up the AVL tree.
|
* Finally, clean up the AVL tree.
|
||||||
*/
|
*/
|
||||||
if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL)
|
void *cookie = NULL;
|
||||||
nomem();
|
while ((node = avl_destroy_nodes(&cb.cb_avl, &cookie)) != NULL) {
|
||||||
|
|
||||||
while ((node = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
uu_avl_remove(cb.cb_avl, node);
|
|
||||||
zfs_close(node->zn_handle);
|
zfs_close(node->zn_handle);
|
||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
uu_avl_walk_end(walk);
|
avl_destroy(&cb.cb_avl);
|
||||||
uu_avl_destroy(cb.cb_avl);
|
|
||||||
uu_avl_pool_destroy(avl_pool);
|
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|||||||
+107
-215
@@ -2846,31 +2846,27 @@ static int us_type_bits[] = {
|
|||||||
static const char *const us_type_names[] = { "posixgroup", "posixuser",
|
static const char *const us_type_names[] = { "posixgroup", "posixuser",
|
||||||
"smbgroup", "smbuser", "all" };
|
"smbgroup", "smbuser", "all" };
|
||||||
|
|
||||||
|
typedef struct us_cbdata us_cbdata_t;
|
||||||
typedef struct us_node {
|
typedef struct us_node {
|
||||||
nvlist_t *usn_nvl;
|
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;
|
uu_list_node_t usn_listnode;
|
||||||
} us_node_t;
|
} us_node_t;
|
||||||
|
|
||||||
typedef struct us_cbdata {
|
struct us_cbdata {
|
||||||
nvlist_t **cb_nvlp;
|
nvlist_t **cb_nvlp;
|
||||||
uu_avl_pool_t *cb_avl_pool;
|
avl_tree_t cb_avl;
|
||||||
uu_avl_t *cb_avl;
|
|
||||||
boolean_t cb_numname;
|
boolean_t cb_numname;
|
||||||
boolean_t cb_nicenum;
|
boolean_t cb_nicenum;
|
||||||
boolean_t cb_sid2posix;
|
boolean_t cb_sid2posix;
|
||||||
zfs_userquota_prop_t cb_prop;
|
zfs_userquota_prop_t cb_prop;
|
||||||
zfs_sort_column_t *cb_sortcol;
|
zfs_sort_column_t *cb_sortcol;
|
||||||
size_t cb_width[USFIELD_LAST];
|
size_t cb_width[USFIELD_LAST];
|
||||||
} us_cbdata_t;
|
};
|
||||||
|
|
||||||
static boolean_t us_populated = B_FALSE;
|
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
|
static int
|
||||||
us_field_index(const char *field)
|
us_field_index(const char *field)
|
||||||
{
|
{
|
||||||
@@ -2883,13 +2879,12 @@ us_field_index(const char *field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 *l = larg;
|
||||||
const us_node_t *r = rarg;
|
const us_node_t *r = rarg;
|
||||||
us_sort_info_t *si = (us_sort_info_t *)unused;
|
zfs_sort_column_t *sortcol = l->usn_cbdata->cb_sortcol;
|
||||||
zfs_sort_column_t *sortcol = si->si_sortcol;
|
boolean_t numname = l->usn_cbdata->cb_numname;
|
||||||
boolean_t numname = si->si_numname;
|
|
||||||
nvlist_t *lnvl = l->usn_nvl;
|
nvlist_t *lnvl = l->usn_nvl;
|
||||||
nvlist_t *rnvl = r->usn_nvl;
|
nvlist_t *rnvl = r->usn_nvl;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -3023,25 +3018,22 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space,
|
|||||||
const char *propname;
|
const char *propname;
|
||||||
char sizebuf[32];
|
char sizebuf[32];
|
||||||
us_node_t *node;
|
us_node_t *node;
|
||||||
uu_avl_pool_t *avl_pool = cb->cb_avl_pool;
|
avl_tree_t *avl = &cb->cb_avl;
|
||||||
uu_avl_t *avl = cb->cb_avl;
|
avl_index_t idx;
|
||||||
uu_avl_index_t idx;
|
|
||||||
nvlist_t *props;
|
nvlist_t *props;
|
||||||
us_node_t *n;
|
us_node_t *n;
|
||||||
zfs_sort_column_t *sortcol = cb->cb_sortcol;
|
|
||||||
unsigned type = 0;
|
unsigned type = 0;
|
||||||
const char *typestr;
|
const char *typestr;
|
||||||
size_t namelen;
|
size_t namelen;
|
||||||
size_t typelen;
|
size_t typelen;
|
||||||
size_t sizelen;
|
size_t sizelen;
|
||||||
int typeidx, nameidx, sizeidx;
|
int typeidx, nameidx, sizeidx;
|
||||||
us_sort_info_t sortinfo = { sortcol, cb->cb_numname };
|
|
||||||
boolean_t smbentity = B_FALSE;
|
boolean_t smbentity = B_FALSE;
|
||||||
|
|
||||||
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
|
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
|
||||||
nomem();
|
nomem();
|
||||||
node = safe_malloc(sizeof (us_node_t));
|
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;
|
node->usn_nvl = props;
|
||||||
|
|
||||||
if (domain != NULL && domain[0] != '\0') {
|
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;
|
* Check if this type/name combination is in the list and update it;
|
||||||
* otherwise add new node to the list.
|
* otherwise add new node to the list.
|
||||||
*/
|
*/
|
||||||
if ((n = uu_avl_find(avl, node, &sortinfo, &idx)) == NULL) {
|
if ((n = avl_find(avl, node, &idx)) == NULL) {
|
||||||
uu_avl_insert(avl, node, idx);
|
avl_insert(avl, node, idx);
|
||||||
} else {
|
} else {
|
||||||
nvlist_free(props);
|
nvlist_free(props);
|
||||||
free(node);
|
free(node);
|
||||||
@@ -3318,7 +3310,7 @@ print_us_node(boolean_t scripted, boolean_t parsable, int *fields, int types,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
print_us(boolean_t scripted, boolean_t parsable, int *fields, int types,
|
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;
|
us_node_t *node;
|
||||||
const char *col;
|
const char *col;
|
||||||
@@ -3343,7 +3335,7 @@ print_us(boolean_t scripted, boolean_t parsable, int *fields, int types,
|
|||||||
(void) printf("\n");
|
(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);
|
print_us_node(scripted, parsable, fields, types, width, node);
|
||||||
if (rmnode)
|
if (rmnode)
|
||||||
nvlist_free(node->usn_nvl);
|
nvlist_free(node->usn_nvl);
|
||||||
@@ -3355,9 +3347,6 @@ zfs_do_userspace(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
zfs_handle_t *zhp;
|
zfs_handle_t *zhp;
|
||||||
zfs_userquota_prop_t p;
|
zfs_userquota_prop_t p;
|
||||||
uu_avl_pool_t *avl_pool;
|
|
||||||
uu_avl_t *avl_tree;
|
|
||||||
uu_avl_walk_t *walk;
|
|
||||||
char *delim;
|
char *delim;
|
||||||
char deffields[] = "type,name,used,quota,objused,objquota";
|
char deffields[] = "type,name,used,quota,objused,objquota";
|
||||||
char *ofield = NULL;
|
char *ofield = NULL;
|
||||||
@@ -3378,7 +3367,7 @@ zfs_do_userspace(int argc, char **argv)
|
|||||||
us_node_t *rmnode;
|
us_node_t *rmnode;
|
||||||
uu_list_pool_t *listpool;
|
uu_list_pool_t *listpool;
|
||||||
uu_list_t *list;
|
uu_list_t *list;
|
||||||
uu_avl_index_t idx = 0;
|
avl_index_t idx = 0;
|
||||||
uu_list_index_t idx2 = 0;
|
uu_list_index_t idx2 = 0;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
@@ -3513,12 +3502,6 @@ zfs_do_userspace(int argc, char **argv)
|
|||||||
return (1);
|
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 */
|
/* Always add default sorting columns */
|
||||||
(void) zfs_add_sort_column(&sortcol, "type", B_FALSE);
|
(void) zfs_add_sort_column(&sortcol, "type", B_FALSE);
|
||||||
(void) zfs_add_sort_column(&sortcol, "name", 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_sortcol = sortcol;
|
||||||
cb.cb_numname = prtnum;
|
cb.cb_numname = prtnum;
|
||||||
cb.cb_nicenum = !parsable;
|
cb.cb_nicenum = !parsable;
|
||||||
cb.cb_avl_pool = avl_pool;
|
|
||||||
cb.cb_avl = avl_tree;
|
|
||||||
cb.cb_sid2posix = sid2posix;
|
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++)
|
for (i = 0; i < USFIELD_LAST; i++)
|
||||||
cb.cb_width[i] = strlen(gettext(us_field_hdr[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;
|
cb.cb_prop = p;
|
||||||
if ((ret = zfs_userspace(zhp, p, userspace_cb, &cb)) != 0) {
|
if ((ret = zfs_userspace(zhp, p, userspace_cb, &cb)) != 0) {
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
|
avl_destroy(&cb.cb_avl);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
|
|
||||||
/* Sort the list */
|
/* 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);
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
us_populated = B_TRUE;
|
us_populated = B_TRUE;
|
||||||
|
|
||||||
@@ -3562,18 +3550,17 @@ zfs_do_userspace(int argc, char **argv)
|
|||||||
|
|
||||||
while (node != NULL) {
|
while (node != NULL) {
|
||||||
rmnode = node;
|
rmnode = node;
|
||||||
node = uu_avl_next(avl_tree, node);
|
node = AVL_NEXT(&cb.cb_avl, node);
|
||||||
uu_avl_remove(avl_tree, rmnode);
|
avl_remove(&cb.cb_avl, rmnode);
|
||||||
if (uu_list_find(list, rmnode, NULL, &idx2) == NULL)
|
if (uu_list_find(list, rmnode, NULL, &idx2) == NULL)
|
||||||
uu_list_insert(list, rmnode, idx2);
|
uu_list_insert(list, rmnode, idx2);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (node = uu_list_first(list); node != NULL;
|
for (node = uu_list_first(list); node != NULL;
|
||||||
node = uu_list_next(list, node)) {
|
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)
|
if (avl_find(&cb.cb_avl, node, &idx) == NULL)
|
||||||
uu_avl_insert(avl_tree, node, idx);
|
avl_insert(&cb.cb_avl, node, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
uu_list_destroy(list);
|
uu_list_destroy(list);
|
||||||
@@ -3581,22 +3568,16 @@ zfs_do_userspace(int argc, char **argv)
|
|||||||
|
|
||||||
/* Print and free node nvlist memory */
|
/* Print and free node nvlist memory */
|
||||||
print_us(scripted, parsable, fields, types, cb.cb_width, B_TRUE,
|
print_us(scripted, parsable, fields, types, cb.cb_width, B_TRUE,
|
||||||
cb.cb_avl);
|
&cb.cb_avl);
|
||||||
|
|
||||||
zfs_free_sort_columns(sortcol);
|
zfs_free_sort_columns(sortcol);
|
||||||
|
|
||||||
/* Clean up the AVL tree */
|
/* Clean up the AVL tree */
|
||||||
if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL)
|
void *cookie = NULL;
|
||||||
nomem();
|
while ((node = avl_destroy_nodes(&cb.cb_avl, &cookie)) != NULL) {
|
||||||
|
|
||||||
while ((node = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
uu_avl_remove(cb.cb_avl, node);
|
|
||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
|
avl_destroy(&cb.cb_avl);
|
||||||
uu_avl_walk_end(walk);
|
|
||||||
uu_avl_destroy(avl_tree);
|
|
||||||
uu_avl_pool_destroy(avl_pool);
|
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@@ -5401,7 +5382,7 @@ typedef struct deleg_perm {
|
|||||||
typedef struct deleg_perm_node {
|
typedef struct deleg_perm_node {
|
||||||
deleg_perm_t dpn_perm;
|
deleg_perm_t dpn_perm;
|
||||||
|
|
||||||
uu_avl_node_t dpn_avl_node;
|
avl_node_t dpn_avl_node;
|
||||||
} deleg_perm_node_t;
|
} deleg_perm_node_t;
|
||||||
|
|
||||||
typedef struct fs_perm fs_perm_t;
|
typedef struct fs_perm fs_perm_t;
|
||||||
@@ -5413,13 +5394,13 @@ typedef struct who_perm {
|
|||||||
char who_ug_name[256]; /* user/group name */
|
char who_ug_name[256]; /* user/group name */
|
||||||
fs_perm_t *who_fsperm; /* uplink */
|
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;
|
} who_perm_t;
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
typedef struct who_perm_node {
|
typedef struct who_perm_node {
|
||||||
who_perm_t who_perm;
|
who_perm_t who_perm;
|
||||||
uu_avl_node_t who_avl_node;
|
avl_node_t who_avl_node;
|
||||||
} who_perm_node_t;
|
} who_perm_node_t;
|
||||||
|
|
||||||
typedef struct fs_perm_set fs_perm_set_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 {
|
struct fs_perm {
|
||||||
const char *fsp_name;
|
const char *fsp_name;
|
||||||
|
|
||||||
uu_avl_t *fsp_sc_avl; /* sets,create */
|
avl_tree_t fsp_sc_avl; /* sets,create */
|
||||||
uu_avl_t *fsp_uge_avl; /* user,group,everyone */
|
avl_tree_t fsp_uge_avl; /* user,group,everyone */
|
||||||
|
|
||||||
fs_perm_set_t *fsp_set; /* uplink */
|
fs_perm_set_t *fsp_set; /* uplink */
|
||||||
};
|
};
|
||||||
@@ -5436,7 +5417,7 @@ struct fs_perm {
|
|||||||
/* */
|
/* */
|
||||||
typedef struct fs_perm_node {
|
typedef struct fs_perm_node {
|
||||||
fs_perm_t fspn_fsperm;
|
fs_perm_t fspn_fsperm;
|
||||||
uu_avl_t *fspn_avl;
|
avl_tree_t fspn_avl;
|
||||||
|
|
||||||
uu_list_node_t fspn_list_node;
|
uu_list_node_t fspn_list_node;
|
||||||
} fs_perm_node_t;
|
} fs_perm_node_t;
|
||||||
@@ -5445,10 +5426,6 @@ typedef struct fs_perm_node {
|
|||||||
struct fs_perm_set {
|
struct fs_perm_set {
|
||||||
uu_list_pool_t *fsps_list_pool;
|
uu_list_pool_t *fsps_list_pool;
|
||||||
uu_list_t *fsps_list; /* list of fs_perms */
|
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 *
|
static inline const char *
|
||||||
@@ -5511,9 +5488,8 @@ who_type2weight(zfs_deleg_who_type_t who_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 *l = larg;
|
||||||
const who_perm_node_t *r = rarg;
|
const who_perm_node_t *r = rarg;
|
||||||
zfs_deleg_who_type_t ltype = l->who_perm.who_type;
|
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)
|
if (res == 0)
|
||||||
res = strncmp(l->who_perm.who_name, r->who_perm.who_name,
|
res = strncmp(l->who_perm.who_name, r->who_perm.who_name,
|
||||||
ZFS_MAX_DELEG_NAME-1);
|
ZFS_MAX_DELEG_NAME-1);
|
||||||
|
return (TREE_ISIGN(res));
|
||||||
if (res == 0)
|
|
||||||
return (0);
|
|
||||||
if (res > 0)
|
|
||||||
return (1);
|
|
||||||
else
|
|
||||||
return (-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 *l = larg;
|
||||||
const deleg_perm_node_t *r = rarg;
|
const deleg_perm_node_t *r = rarg;
|
||||||
int res = strncmp(l->dpn_perm.dp_name, r->dpn_perm.dp_name,
|
return (TREE_ISIGN(strncmp(l->dpn_perm.dp_name, r->dpn_perm.dp_name,
|
||||||
ZFS_MAX_DELEG_NAME-1);
|
ZFS_MAX_DELEG_NAME-1)));
|
||||||
|
|
||||||
if (res == 0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
if (res > 0)
|
|
||||||
return (1);
|
|
||||||
else
|
|
||||||
return (-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
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,
|
if ((fspset->fsps_list = uu_list_create(fspset->fsps_list_pool, NULL,
|
||||||
UU_DEFAULT)) == NULL)
|
UU_DEFAULT)) == NULL)
|
||||||
nomem();
|
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 *);
|
static inline void fs_perm_fini(fs_perm_t *);
|
||||||
@@ -5600,10 +5543,6 @@ fs_perm_set_fini(fs_perm_set_t *fspset)
|
|||||||
free(node);
|
free(node);
|
||||||
node = next_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
|
static inline void
|
||||||
@@ -5618,14 +5557,11 @@ static inline void
|
|||||||
who_perm_init(who_perm_t *who_perm, fs_perm_t *fsperm,
|
who_perm_init(who_perm_t *who_perm, fs_perm_t *fsperm,
|
||||||
zfs_deleg_who_type_t type, const char *name)
|
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));
|
memset(who_perm, 0, sizeof (who_perm_t));
|
||||||
|
|
||||||
if ((who_perm->who_deleg_perm_avl = uu_avl_create(pool, NULL,
|
avl_create(&who_perm->who_deleg_perm_avl, deleg_perm_compare,
|
||||||
UU_DEFAULT)) == NULL)
|
sizeof (deleg_perm_node_t),
|
||||||
nomem();
|
offsetof(deleg_perm_node_t, dpn_avl_node));
|
||||||
|
|
||||||
who_perm->who_type = type;
|
who_perm->who_type = type;
|
||||||
who_perm->who_name = name;
|
who_perm->who_name = name;
|
||||||
@@ -5635,35 +5571,26 @@ who_perm_init(who_perm_t *who_perm, fs_perm_t *fsperm,
|
|||||||
static inline void
|
static inline void
|
||||||
who_perm_fini(who_perm_t *who_perm)
|
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) {
|
while ((node = avl_destroy_nodes(&who_perm->who_deleg_perm_avl,
|
||||||
deleg_perm_node_t *next_node =
|
&cookie)) != NULL) {
|
||||||
uu_avl_next(who_perm->who_deleg_perm_avl, node);
|
|
||||||
|
|
||||||
uu_avl_remove(who_perm->who_deleg_perm_avl, node);
|
|
||||||
free(node);
|
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
|
static inline void
|
||||||
fs_perm_init(fs_perm_t *fsperm, fs_perm_set_t *fspset, const char *fsname)
|
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));
|
memset(fsperm, 0, sizeof (fs_perm_t));
|
||||||
|
|
||||||
if ((fsperm->fsp_sc_avl = uu_avl_create(nset_pool, NULL, UU_DEFAULT))
|
avl_create(&fsperm->fsp_sc_avl, who_perm_compare,
|
||||||
== NULL)
|
sizeof (who_perm_node_t), offsetof(who_perm_node_t, who_avl_node));
|
||||||
nomem();
|
avl_create(&fsperm->fsp_uge_avl, who_perm_compare,
|
||||||
|
sizeof (who_perm_node_t), offsetof(who_perm_node_t, who_avl_node));
|
||||||
if ((fsperm->fsp_uge_avl = uu_avl_create(who_pool, NULL, UU_DEFAULT))
|
|
||||||
== NULL)
|
|
||||||
nomem();
|
|
||||||
|
|
||||||
fsperm->fsp_set = fspset;
|
fsperm->fsp_set = fspset;
|
||||||
fsperm->fsp_name = fsname;
|
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
|
static inline void
|
||||||
fs_perm_fini(fs_perm_t *fsperm)
|
fs_perm_fini(fs_perm_t *fsperm)
|
||||||
{
|
{
|
||||||
who_perm_node_t *node = uu_avl_first(fsperm->fsp_sc_avl);
|
who_perm_node_t *node;
|
||||||
while (node != NULL) {
|
void *cookie = NULL;
|
||||||
who_perm_node_t *next_node = uu_avl_next(fsperm->fsp_sc_avl,
|
|
||||||
node);
|
while ((node = avl_destroy_nodes(&fsperm->fsp_sc_avl,
|
||||||
|
&cookie)) != NULL) {
|
||||||
who_perm_t *who_perm = &node->who_perm;
|
who_perm_t *who_perm = &node->who_perm;
|
||||||
who_perm_fini(who_perm);
|
who_perm_fini(who_perm);
|
||||||
uu_avl_remove(fsperm->fsp_sc_avl, node);
|
|
||||||
free(node);
|
free(node);
|
||||||
node = next_node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node = uu_avl_first(fsperm->fsp_uge_avl);
|
cookie = NULL;
|
||||||
while (node != NULL) {
|
while ((node = avl_destroy_nodes(&fsperm->fsp_uge_avl,
|
||||||
who_perm_node_t *next_node = uu_avl_next(fsperm->fsp_uge_avl,
|
&cookie)) != NULL) {
|
||||||
node);
|
|
||||||
who_perm_t *who_perm = &node->who_perm;
|
who_perm_t *who_perm = &node->who_perm;
|
||||||
who_perm_fini(who_perm);
|
who_perm_fini(who_perm);
|
||||||
uu_avl_remove(fsperm->fsp_uge_avl, node);
|
|
||||||
free(node);
|
free(node);
|
||||||
node = next_node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uu_avl_destroy(fsperm->fsp_sc_avl);
|
avl_destroy(&fsperm->fsp_sc_avl);
|
||||||
uu_avl_destroy(fsperm->fsp_uge_avl);
|
avl_destroy(&fsperm->fsp_uge_avl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
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_node_t *found_node = NULL;
|
||||||
deleg_perm_t *deleg_perm = &node->dpn_perm;
|
deleg_perm_t *deleg_perm = &node->dpn_perm;
|
||||||
|
|
||||||
deleg_perm_init(deleg_perm, who_type, name);
|
deleg_perm_init(deleg_perm, who_type, name);
|
||||||
|
|
||||||
if ((found_node = uu_avl_find(avl, node, NULL, &idx))
|
if ((found_node = avl_find(avl, node, &idx)) == NULL)
|
||||||
== NULL)
|
avl_insert(avl, node, idx);
|
||||||
uu_avl_insert(avl, node, idx);
|
|
||||||
else {
|
else {
|
||||||
node = found_node;
|
node = found_node;
|
||||||
deleg_perm = &node->dpn_perm;
|
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)
|
parse_who_perm(who_perm_t *who_perm, nvlist_t *nvl, char locality)
|
||||||
{
|
{
|
||||||
nvpair_t *nvp = NULL;
|
nvpair_t *nvp = NULL;
|
||||||
fs_perm_set_t *fspset = who_perm->who_fsperm->fsp_set;
|
avl_tree_t *avl = &who_perm->who_deleg_perm_avl;
|
||||||
uu_avl_t *avl = who_perm->who_deleg_perm_avl;
|
|
||||||
zfs_deleg_who_type_t who_type = who_perm->who_type;
|
zfs_deleg_who_type_t who_type = who_perm->who_type;
|
||||||
|
|
||||||
while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
|
while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
|
||||||
const char *name = nvpair_name(nvp);
|
const char *name = nvpair_name(nvp);
|
||||||
data_type_t type = nvpair_type(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 =
|
deleg_perm_node_t *node =
|
||||||
safe_malloc(sizeof (deleg_perm_node_t));
|
safe_malloc(sizeof (deleg_perm_node_t));
|
||||||
|
|
||||||
VERIFY(type == DATA_TYPE_BOOLEAN);
|
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);
|
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)
|
parse_fs_perm(fs_perm_t *fsperm, nvlist_t *nvl)
|
||||||
{
|
{
|
||||||
nvpair_t *nvp = NULL;
|
nvpair_t *nvp = NULL;
|
||||||
fs_perm_set_t *fspset = fsperm->fsp_set;
|
|
||||||
|
|
||||||
while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
|
while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
|
||||||
nvlist_t *nvl2 = NULL;
|
nvlist_t *nvl2 = NULL;
|
||||||
const char *name = nvpair_name(nvp);
|
const char *name = nvpair_name(nvp);
|
||||||
uu_avl_t *avl = NULL;
|
avl_tree_t *avl = NULL;
|
||||||
uu_avl_pool_t *avl_pool = NULL;
|
|
||||||
zfs_deleg_who_type_t perm_type = name[0];
|
zfs_deleg_who_type_t perm_type = name[0];
|
||||||
char perm_locality = name[1];
|
char perm_locality = name[1];
|
||||||
const char *perm_name = name + 3;
|
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_CREATE_SETS:
|
||||||
case ZFS_DELEG_NAMED_SET:
|
case ZFS_DELEG_NAMED_SET:
|
||||||
case ZFS_DELEG_NAMED_SET_SETS:
|
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;
|
break;
|
||||||
case ZFS_DELEG_USER:
|
case ZFS_DELEG_USER:
|
||||||
case ZFS_DELEG_USER_SETS:
|
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_GROUP_SETS:
|
||||||
case ZFS_DELEG_EVERYONE:
|
case ZFS_DELEG_EVERYONE:
|
||||||
case ZFS_DELEG_EVERYONE_SETS:
|
case ZFS_DELEG_EVERYONE_SETS:
|
||||||
avl_pool = fspset->fsps_who_perm_avl_pool;
|
avl = &fsperm->fsp_uge_avl;
|
||||||
avl = fsperm->fsp_uge_avl;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -5803,14 +5718,12 @@ parse_fs_perm(fs_perm_t *fsperm, nvlist_t *nvl)
|
|||||||
who_perm_node_t *node = safe_malloc(
|
who_perm_node_t *node = safe_malloc(
|
||||||
sizeof (who_perm_node_t));
|
sizeof (who_perm_node_t));
|
||||||
who_perm = &node->who_perm;
|
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);
|
who_perm_init(who_perm, fsperm, perm_type, perm_name);
|
||||||
|
|
||||||
if ((found_node = uu_avl_find(avl, node, NULL, &idx))
|
if ((found_node = avl_find(avl, node, &idx)) == NULL) {
|
||||||
== NULL) {
|
if (avl == &fsperm->fsp_uge_avl) {
|
||||||
if (avl == fsperm->fsp_uge_avl) {
|
|
||||||
uid_t rid = 0;
|
uid_t rid = 0;
|
||||||
struct passwd *p = NULL;
|
struct passwd *p = NULL;
|
||||||
struct group *g = 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 {
|
} else {
|
||||||
node = found_node;
|
node = found_node;
|
||||||
who_perm = &node->who_perm;
|
who_perm = &node->who_perm;
|
||||||
@@ -5866,7 +5779,7 @@ static inline int
|
|||||||
parse_fs_perm_set(fs_perm_set_t *fspset, nvlist_t *nvl)
|
parse_fs_perm_set(fs_perm_set_t *fspset, nvlist_t *nvl)
|
||||||
{
|
{
|
||||||
nvpair_t *nvp = NULL;
|
nvpair_t *nvp = NULL;
|
||||||
uu_avl_index_t idx = 0;
|
avl_index_t idx = 0;
|
||||||
|
|
||||||
while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
|
while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
|
||||||
nvlist_t *nvl2 = NULL;
|
nvlist_t *nvl2 = NULL;
|
||||||
@@ -6442,7 +6355,7 @@ construct_fsacl_list(boolean_t un, struct allow_opts *opts, nvlist_t **nvlp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_set_creat_perms(uu_avl_t *who_avl)
|
print_set_creat_perms(avl_tree_t *who_avl)
|
||||||
{
|
{
|
||||||
const char *sc_title[] = {
|
const char *sc_title[] = {
|
||||||
gettext("Permission sets:\n"),
|
gettext("Permission sets:\n"),
|
||||||
@@ -6452,9 +6365,9 @@ print_set_creat_perms(uu_avl_t *who_avl)
|
|||||||
who_perm_node_t *who_node = NULL;
|
who_perm_node_t *who_node = NULL;
|
||||||
int prev_weight = -1;
|
int prev_weight = -1;
|
||||||
|
|
||||||
for (who_node = uu_avl_first(who_avl); who_node != NULL;
|
for (who_node = avl_first(who_avl); who_node != NULL;
|
||||||
who_node = uu_avl_next(who_avl, who_node)) {
|
who_node = AVL_NEXT(who_avl, who_node)) {
|
||||||
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;
|
zfs_deleg_who_type_t who_type = who_node->who_perm.who_type;
|
||||||
const char *who_name = who_node->who_perm.who_name;
|
const char *who_name = who_node->who_perm.who_name;
|
||||||
int weight = who_type2weight(who_type);
|
int weight = who_type2weight(who_type);
|
||||||
@@ -6471,8 +6384,8 @@ print_set_creat_perms(uu_avl_t *who_avl)
|
|||||||
else
|
else
|
||||||
(void) printf("\t%s ", who_name);
|
(void) printf("\t%s ", who_name);
|
||||||
|
|
||||||
for (deleg_node = uu_avl_first(avl); deleg_node != NULL;
|
for (deleg_node = avl_first(avl); deleg_node != NULL;
|
||||||
deleg_node = uu_avl_next(avl, deleg_node)) {
|
deleg_node = AVL_NEXT(avl, deleg_node)) {
|
||||||
if (first) {
|
if (first) {
|
||||||
(void) printf("%s",
|
(void) printf("%s",
|
||||||
deleg_node->dpn_perm.dp_name);
|
deleg_node->dpn_perm.dp_name);
|
||||||
@@ -6487,28 +6400,24 @@ print_set_creat_perms(uu_avl_t *who_avl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
const char *title)
|
||||||
{
|
{
|
||||||
who_perm_node_t *who_node = NULL;
|
who_perm_node_t *who_node = NULL;
|
||||||
boolean_t prt_title = B_TRUE;
|
boolean_t prt_title = B_TRUE;
|
||||||
uu_avl_walk_t *walk;
|
|
||||||
|
|
||||||
if ((walk = uu_avl_walk_start(who_avl, UU_WALK_ROBUST)) == NULL)
|
for (who_node = avl_first(who_avl); who_node != NULL;
|
||||||
nomem();
|
who_node = AVL_NEXT(who_avl, who_node)) {
|
||||||
|
|
||||||
while ((who_node = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
const char *who_name = who_node->who_perm.who_name;
|
const char *who_name = who_node->who_perm.who_name;
|
||||||
const char *nice_who_name = who_node->who_perm.who_ug_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;
|
zfs_deleg_who_type_t who_type = who_node->who_perm.who_type;
|
||||||
char delim = ' ';
|
char delim = ' ';
|
||||||
deleg_perm_node_t *deleg_node;
|
deleg_perm_node_t *deleg_node;
|
||||||
boolean_t prt_who = B_TRUE;
|
boolean_t prt_who = B_TRUE;
|
||||||
|
|
||||||
for (deleg_node = uu_avl_first(avl);
|
for (deleg_node = avl_first(avl); deleg_node != NULL;
|
||||||
deleg_node != NULL;
|
deleg_node = AVL_NEXT(avl, deleg_node)) {
|
||||||
deleg_node = uu_avl_next(avl, deleg_node)) {
|
|
||||||
if (local != deleg_node->dpn_perm.dp_local ||
|
if (local != deleg_node->dpn_perm.dp_local ||
|
||||||
descend != deleg_node->dpn_perm.dp_descend)
|
descend != deleg_node->dpn_perm.dp_descend)
|
||||||
continue;
|
continue;
|
||||||
@@ -6558,8 +6467,6 @@ print_uge_deleg_perms(uu_avl_t *who_avl, boolean_t local, boolean_t descend,
|
|||||||
if (!prt_who)
|
if (!prt_who)
|
||||||
(void) printf("\n");
|
(void) printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
uu_avl_walk_end(walk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -6571,8 +6478,8 @@ print_fs_perms(fs_perm_set_t *fspset)
|
|||||||
|
|
||||||
for (node = uu_list_first(fspset->fsps_list); node != NULL;
|
for (node = uu_list_first(fspset->fsps_list); node != NULL;
|
||||||
node = uu_list_next(fspset->fsps_list, node)) {
|
node = uu_list_next(fspset->fsps_list, node)) {
|
||||||
uu_avl_t *sc_avl = node->fspn_fsperm.fsp_sc_avl;
|
avl_tree_t *sc_avl = &node->fspn_fsperm.fsp_sc_avl;
|
||||||
uu_avl_t *uge_avl = node->fspn_fsperm.fsp_uge_avl;
|
avl_tree_t *uge_avl = &node->fspn_fsperm.fsp_uge_avl;
|
||||||
int left = 0;
|
int left = 0;
|
||||||
|
|
||||||
(void) snprintf(buf, sizeof (buf),
|
(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 {
|
struct deleg_perms {
|
||||||
boolean_t un;
|
boolean_t un;
|
||||||
@@ -7726,17 +7633,16 @@ zfs_do_share(int argc, char **argv)
|
|||||||
typedef struct unshare_unmount_node {
|
typedef struct unshare_unmount_node {
|
||||||
zfs_handle_t *un_zhp;
|
zfs_handle_t *un_zhp;
|
||||||
char *un_mountp;
|
char *un_mountp;
|
||||||
uu_avl_node_t un_avlnode;
|
avl_node_t un_avlnode;
|
||||||
} unshare_unmount_node_t;
|
} unshare_unmount_node_t;
|
||||||
|
|
||||||
static int
|
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 *l = larg;
|
||||||
const unshare_unmount_node_t *r = rarg;
|
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;
|
FILE *mnttab;
|
||||||
struct mnttab entry;
|
struct mnttab entry;
|
||||||
uu_avl_pool_t *pool;
|
avl_tree_t tree;
|
||||||
uu_avl_t *tree = NULL;
|
|
||||||
unshare_unmount_node_t *node;
|
unshare_unmount_node_t *node;
|
||||||
uu_avl_index_t idx;
|
avl_index_t idx;
|
||||||
uu_avl_walk_t *walk;
|
|
||||||
enum sa_protocol *protocol = NULL,
|
enum sa_protocol *protocol = NULL,
|
||||||
single_protocol[] = {SA_NO_PROTOCOL, SA_NO_PROTOCOL};
|
single_protocol[] = {SA_NO_PROTOCOL, SA_NO_PROTOCOL};
|
||||||
|
|
||||||
@@ -7938,16 +7842,12 @@ unshare_unmount(int op, int argc, char **argv)
|
|||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((pool = uu_avl_pool_create("unmount_pool",
|
avl_create(&tree, unshare_unmount_compare,
|
||||||
sizeof (unshare_unmount_node_t),
|
sizeof (unshare_unmount_node_t),
|
||||||
offsetof(unshare_unmount_node_t, un_avlnode),
|
offsetof(unshare_unmount_node_t, un_avlnode));
|
||||||
unshare_unmount_compare, UU_DEFAULT)) == NULL) ||
|
|
||||||
((tree = uu_avl_create(pool, NULL, UU_DEFAULT)) == NULL))
|
|
||||||
nomem();
|
|
||||||
|
|
||||||
if ((mnttab = fopen(MNTTAB, "re")) == NULL) {
|
if ((mnttab = fopen(MNTTAB, "re")) == NULL) {
|
||||||
uu_avl_destroy(tree);
|
avl_destroy(&tree);
|
||||||
uu_avl_pool_destroy(pool);
|
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8012,10 +7912,8 @@ unshare_unmount(int op, int argc, char **argv)
|
|||||||
node->un_zhp = zhp;
|
node->un_zhp = zhp;
|
||||||
node->un_mountp = safe_strdup(entry.mnt_mountp);
|
node->un_mountp = safe_strdup(entry.mnt_mountp);
|
||||||
|
|
||||||
uu_avl_node_init(node, &node->un_avlnode, pool);
|
if (avl_find(&tree, node, &idx) == NULL) {
|
||||||
|
avl_insert(&tree, node, idx);
|
||||||
if (uu_avl_find(tree, node, NULL, &idx) == NULL) {
|
|
||||||
uu_avl_insert(tree, node, idx);
|
|
||||||
} else {
|
} else {
|
||||||
zfs_close(node->un_zhp);
|
zfs_close(node->un_zhp);
|
||||||
free(node->un_mountp);
|
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
|
* Walk the AVL tree in reverse, unmounting each filesystem and
|
||||||
* removing it from the AVL tree in the process.
|
* removing it from the AVL tree in the process.
|
||||||
*/
|
*/
|
||||||
if ((walk = uu_avl_walk_start(tree,
|
while ((node = avl_last(&tree)) != NULL) {
|
||||||
UU_WALK_REVERSE | UU_WALK_ROBUST)) == NULL)
|
|
||||||
nomem();
|
|
||||||
|
|
||||||
while ((node = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
const char *mntarg = NULL;
|
const char *mntarg = NULL;
|
||||||
|
|
||||||
uu_avl_remove(tree, node);
|
avl_remove(&tree, node);
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OP_SHARE:
|
case OP_SHARE:
|
||||||
if (zfs_unshare(node->un_zhp,
|
if (zfs_unshare(node->un_zhp,
|
||||||
@@ -8058,9 +7952,7 @@ unshare_unmount(int op, int argc, char **argv)
|
|||||||
if (op == OP_SHARE)
|
if (op == OP_SHARE)
|
||||||
zfs_commit_shares(protocol);
|
zfs_commit_shares(protocol);
|
||||||
|
|
||||||
uu_avl_walk_end(walk);
|
avl_destroy(&tree);
|
||||||
uu_avl_destroy(tree);
|
|
||||||
uu_avl_pool_destroy(pool);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
|
|||||||
+21
-42
@@ -30,7 +30,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <libuutil.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -52,30 +51,28 @@
|
|||||||
|
|
||||||
typedef struct zpool_node {
|
typedef struct zpool_node {
|
||||||
zpool_handle_t *zn_handle;
|
zpool_handle_t *zn_handle;
|
||||||
uu_avl_node_t zn_avlnode;
|
avl_node_t zn_avlnode;
|
||||||
hrtime_t zn_last_refresh;
|
hrtime_t zn_last_refresh;
|
||||||
} zpool_node_t;
|
} zpool_node_t;
|
||||||
|
|
||||||
struct zpool_list {
|
struct zpool_list {
|
||||||
boolean_t zl_findall;
|
boolean_t zl_findall;
|
||||||
boolean_t zl_literal;
|
boolean_t zl_literal;
|
||||||
uu_avl_t *zl_avl;
|
avl_tree_t zl_avl;
|
||||||
uu_avl_pool_t *zl_pool;
|
|
||||||
zprop_list_t **zl_proplist;
|
zprop_list_t **zl_proplist;
|
||||||
zfs_type_t zl_type;
|
zfs_type_t zl_type;
|
||||||
hrtime_t zl_last_refresh;
|
hrtime_t zl_last_refresh;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zpool_compare(const void *larg, const void *rarg, void *unused)
|
zpool_compare(const void *larg, const void *rarg)
|
||||||
{
|
{
|
||||||
(void) unused;
|
|
||||||
zpool_handle_t *l = ((zpool_node_t *)larg)->zn_handle;
|
zpool_handle_t *l = ((zpool_node_t *)larg)->zn_handle;
|
||||||
zpool_handle_t *r = ((zpool_node_t *)rarg)->zn_handle;
|
zpool_handle_t *r = ((zpool_node_t *)rarg)->zn_handle;
|
||||||
const char *lname = zpool_get_name(l);
|
const char *lname = zpool_get_name(l);
|
||||||
const char *rname = zpool_get_name(r);
|
const char *rname = zpool_get_name(r);
|
||||||
|
|
||||||
return (strcmp(lname, rname));
|
return (TREE_ISIGN(strcmp(lname, rname)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -86,12 +83,11 @@ static int
|
|||||||
add_pool(zpool_handle_t *zhp, zpool_list_t *zlp)
|
add_pool(zpool_handle_t *zhp, zpool_list_t *zlp)
|
||||||
{
|
{
|
||||||
zpool_node_t *node, *new = safe_malloc(sizeof (zpool_node_t));
|
zpool_node_t *node, *new = safe_malloc(sizeof (zpool_node_t));
|
||||||
uu_avl_index_t idx;
|
avl_index_t idx;
|
||||||
|
|
||||||
new->zn_handle = zhp;
|
new->zn_handle = zhp;
|
||||||
uu_avl_node_init(new, &new->zn_avlnode, zlp->zl_pool);
|
|
||||||
|
|
||||||
node = uu_avl_find(zlp->zl_avl, new, NULL, &idx);
|
node = avl_find(&zlp->zl_avl, new, &idx);
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
if (zlp->zl_proplist &&
|
if (zlp->zl_proplist &&
|
||||||
zpool_expand_proplist(zhp, zlp->zl_proplist,
|
zpool_expand_proplist(zhp, zlp->zl_proplist,
|
||||||
@@ -101,7 +97,7 @@ add_pool(zpool_handle_t *zhp, zpool_list_t *zlp)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
new->zn_last_refresh = zlp->zl_last_refresh;
|
new->zn_last_refresh = zlp->zl_last_refresh;
|
||||||
uu_avl_insert(zlp->zl_avl, new, idx);
|
avl_insert(&zlp->zl_avl, new, idx);
|
||||||
} else {
|
} else {
|
||||||
zpool_refresh_stats_from_handle(node->zn_handle, zhp);
|
zpool_refresh_stats_from_handle(node->zn_handle, zhp);
|
||||||
node->zn_last_refresh = zlp->zl_last_refresh;
|
node->zn_last_refresh = zlp->zl_last_refresh;
|
||||||
@@ -139,15 +135,8 @@ pool_list_get(int argc, char **argv, zprop_list_t **proplist, zfs_type_t type,
|
|||||||
|
|
||||||
zlp = safe_malloc(sizeof (zpool_list_t));
|
zlp = safe_malloc(sizeof (zpool_list_t));
|
||||||
|
|
||||||
zlp->zl_pool = uu_avl_pool_create("zfs_pool", sizeof (zpool_node_t),
|
avl_create(&zlp->zl_avl, zpool_compare,
|
||||||
offsetof(zpool_node_t, zn_avlnode), zpool_compare, UU_DEFAULT);
|
sizeof (zpool_node_t), offsetof(zpool_node_t, zn_avlnode));
|
||||||
|
|
||||||
if (zlp->zl_pool == NULL)
|
|
||||||
zpool_no_memory();
|
|
||||||
|
|
||||||
if ((zlp->zl_avl = uu_avl_create(zlp->zl_pool, NULL,
|
|
||||||
UU_DEFAULT)) == NULL)
|
|
||||||
zpool_no_memory();
|
|
||||||
|
|
||||||
zlp->zl_proplist = proplist;
|
zlp->zl_proplist = proplist;
|
||||||
zlp->zl_type = type;
|
zlp->zl_type = type;
|
||||||
@@ -194,8 +183,8 @@ pool_list_refresh(zpool_list_t *zlp)
|
|||||||
* state.
|
* state.
|
||||||
*/
|
*/
|
||||||
int navail = 0;
|
int navail = 0;
|
||||||
for (zpool_node_t *node = uu_avl_first(zlp->zl_avl);
|
for (zpool_node_t *node = avl_first(&zlp->zl_avl);
|
||||||
node != NULL; node = uu_avl_next(zlp->zl_avl, node)) {
|
node != NULL; node = AVL_NEXT(&zlp->zl_avl, node)) {
|
||||||
boolean_t missing;
|
boolean_t missing;
|
||||||
zpool_refresh_stats(node->zn_handle, &missing);
|
zpool_refresh_stats(node->zn_handle, &missing);
|
||||||
navail += !missing;
|
navail += !missing;
|
||||||
@@ -209,8 +198,8 @@ pool_list_refresh(zpool_list_t *zlp)
|
|||||||
|
|
||||||
/* Walk the list of existing pools, and update or remove them. */
|
/* Walk the list of existing pools, and update or remove them. */
|
||||||
zpool_node_t *node, *next;
|
zpool_node_t *node, *next;
|
||||||
for (node = uu_avl_first(zlp->zl_avl); node != NULL; node = next) {
|
for (node = avl_first(&zlp->zl_avl); node != NULL; node = next) {
|
||||||
next = uu_avl_next(zlp->zl_avl, node);
|
next = AVL_NEXT(&zlp->zl_avl, node);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip any that were refreshed and are online; they were added
|
* Skip any that were refreshed and are online; they were added
|
||||||
@@ -224,7 +213,7 @@ pool_list_refresh(zpool_list_t *zlp)
|
|||||||
boolean_t missing;
|
boolean_t missing;
|
||||||
zpool_refresh_stats(node->zn_handle, &missing);
|
zpool_refresh_stats(node->zn_handle, &missing);
|
||||||
if (missing) {
|
if (missing) {
|
||||||
uu_avl_remove(zlp->zl_avl, node);
|
avl_remove(&zlp->zl_avl, node);
|
||||||
zpool_close(node->zn_handle);
|
zpool_close(node->zn_handle);
|
||||||
free(node);
|
free(node);
|
||||||
} else {
|
} else {
|
||||||
@@ -232,7 +221,7 @@ pool_list_refresh(zpool_list_t *zlp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uu_avl_numnodes(zlp->zl_avl));
|
return (avl_numnodes(&zlp->zl_avl));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -245,8 +234,8 @@ pool_list_iter(zpool_list_t *zlp, int unavail, zpool_iter_f func,
|
|||||||
zpool_node_t *node, *next_node;
|
zpool_node_t *node, *next_node;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
for (node = uu_avl_first(zlp->zl_avl); node != NULL; node = next_node) {
|
for (node = avl_first(&zlp->zl_avl); node != NULL; node = next_node) {
|
||||||
next_node = uu_avl_next(zlp->zl_avl, node);
|
next_node = AVL_NEXT(&zlp->zl_avl, node);
|
||||||
if (zpool_get_state(node->zn_handle) != POOL_STATE_UNAVAIL ||
|
if (zpool_get_state(node->zn_handle) != POOL_STATE_UNAVAIL ||
|
||||||
unavail)
|
unavail)
|
||||||
ret |= func(node->zn_handle, data);
|
ret |= func(node->zn_handle, data);
|
||||||
@@ -261,25 +250,15 @@ pool_list_iter(zpool_list_t *zlp, int unavail, zpool_iter_f func,
|
|||||||
void
|
void
|
||||||
pool_list_free(zpool_list_t *zlp)
|
pool_list_free(zpool_list_t *zlp)
|
||||||
{
|
{
|
||||||
uu_avl_walk_t *walk;
|
|
||||||
zpool_node_t *node;
|
zpool_node_t *node;
|
||||||
|
void *cookie = NULL;
|
||||||
|
|
||||||
if ((walk = uu_avl_walk_start(zlp->zl_avl, UU_WALK_ROBUST)) == NULL) {
|
while ((node = avl_destroy_nodes(&zlp->zl_avl, &cookie)) != NULL) {
|
||||||
(void) fprintf(stderr,
|
|
||||||
gettext("internal error: out of memory"));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((node = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
uu_avl_remove(zlp->zl_avl, node);
|
|
||||||
zpool_close(node->zn_handle);
|
zpool_close(node->zn_handle);
|
||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
uu_avl_walk_end(walk);
|
avl_destroy(&zlp->zl_avl);
|
||||||
uu_avl_destroy(zlp->zl_avl);
|
|
||||||
uu_avl_pool_destroy(zlp->zl_pool);
|
|
||||||
|
|
||||||
free(zlp);
|
free(zlp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +268,7 @@ pool_list_free(zpool_list_t *zlp)
|
|||||||
int
|
int
|
||||||
pool_list_count(zpool_list_t *zlp)
|
pool_list_count(zpool_list_t *zlp)
|
||||||
{
|
{
|
||||||
return (uu_avl_numnodes(zlp->zl_avl));
|
return (avl_numnodes(&zlp->zl_avl));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ CPPCHECKTARGETS += libuutil.la
|
|||||||
|
|
||||||
libuutil_la_SOURCES = \
|
libuutil_la_SOURCES = \
|
||||||
%D%/uu_alloc.c \
|
%D%/uu_alloc.c \
|
||||||
%D%/uu_avl.c \
|
|
||||||
%D%/uu_ident.c \
|
%D%/uu_ident.c \
|
||||||
%D%/uu_list.c \
|
%D%/uu_list.c \
|
||||||
%D%/uu_misc.c \
|
%D%/uu_misc.c \
|
||||||
%D%/uu_string.c
|
%D%/uu_string.c
|
||||||
|
|
||||||
libuutil_la_LIBADD = \
|
libuutil_la_LIBADD = \
|
||||||
libavl.la \
|
|
||||||
libspl.la
|
libspl.la
|
||||||
|
|
||||||
libuutil_la_LIBADD += $(LTLIBINTL)
|
libuutil_la_LIBADD += $(LTLIBINTL)
|
||||||
|
|||||||
@@ -31,12 +31,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <libuutil.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <zone.h>
|
#include <zone.h>
|
||||||
|
#include <sys/avl.h>
|
||||||
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
|
|
||||||
@@ -70,15 +70,14 @@ typedef struct prop_changenode {
|
|||||||
int cn_mounted;
|
int cn_mounted;
|
||||||
int cn_zoned;
|
int cn_zoned;
|
||||||
boolean_t cn_needpost; /* is postfix() needed? */
|
boolean_t cn_needpost; /* is postfix() needed? */
|
||||||
uu_avl_node_t cn_treenode;
|
avl_node_t cn_treenode;
|
||||||
} prop_changenode_t;
|
} prop_changenode_t;
|
||||||
|
|
||||||
struct prop_changelist {
|
struct prop_changelist {
|
||||||
zfs_prop_t cl_prop;
|
zfs_prop_t cl_prop;
|
||||||
zfs_prop_t cl_realprop;
|
zfs_prop_t cl_realprop;
|
||||||
zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */
|
zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */
|
||||||
uu_avl_pool_t *cl_pool;
|
avl_tree_t cl_tree;
|
||||||
uu_avl_t *cl_tree;
|
|
||||||
boolean_t cl_waslegacy;
|
boolean_t cl_waslegacy;
|
||||||
boolean_t cl_allchildren;
|
boolean_t cl_allchildren;
|
||||||
boolean_t cl_alldependents;
|
boolean_t cl_alldependents;
|
||||||
@@ -97,7 +96,6 @@ int
|
|||||||
changelist_prefix(prop_changelist_t *clp)
|
changelist_prefix(prop_changelist_t *clp)
|
||||||
{
|
{
|
||||||
prop_changenode_t *cn;
|
prop_changenode_t *cn;
|
||||||
uu_avl_walk_t *walk;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
const enum sa_protocol smb[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL};
|
const enum sa_protocol smb[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL};
|
||||||
boolean_t commit_smb_shares = B_FALSE;
|
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)
|
if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
|
for (cn = avl_first(&clp->cl_tree); cn != NULL;
|
||||||
return (-1);
|
cn = AVL_NEXT(&clp->cl_tree, cn)) {
|
||||||
|
|
||||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
|
|
||||||
/* if a previous loop failed, set the remaining to false */
|
/* if a previous loop failed, set the remaining to false */
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
@@ -159,7 +155,6 @@ changelist_prefix(prop_changelist_t *clp)
|
|||||||
|
|
||||||
if (commit_smb_shares)
|
if (commit_smb_shares)
|
||||||
zfs_commit_shares(smb);
|
zfs_commit_shares(smb);
|
||||||
uu_avl_walk_end(walk);
|
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
(void) changelist_postfix(clp);
|
(void) changelist_postfix(clp);
|
||||||
@@ -179,7 +174,6 @@ int
|
|||||||
changelist_postfix(prop_changelist_t *clp)
|
changelist_postfix(prop_changelist_t *clp)
|
||||||
{
|
{
|
||||||
prop_changenode_t *cn;
|
prop_changenode_t *cn;
|
||||||
uu_avl_walk_t *walk;
|
|
||||||
char shareopts[ZFS_MAXPROPLEN];
|
char shareopts[ZFS_MAXPROPLEN];
|
||||||
boolean_t commit_smb_shares = B_FALSE;
|
boolean_t commit_smb_shares = B_FALSE;
|
||||||
boolean_t commit_nfs_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
|
* location), or have explicit mountpoints set (in which case they won't
|
||||||
* be in the changelist).
|
* be in the changelist).
|
||||||
*/
|
*/
|
||||||
if ((cn = uu_avl_last(clp->cl_tree)) == NULL)
|
if ((cn = avl_last(&clp->cl_tree)) == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
|
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
|
* datasets before mounting the children. We walk all datasets even if
|
||||||
* there are errors.
|
* there are errors.
|
||||||
*/
|
*/
|
||||||
if ((walk = uu_avl_walk_start(clp->cl_tree,
|
for (cn = avl_last(&clp->cl_tree); cn != NULL;
|
||||||
UU_WALK_REVERSE | UU_WALK_ROBUST)) == NULL)
|
cn = AVL_PREV(&clp->cl_tree, cn)) {
|
||||||
return (-1);
|
|
||||||
|
|
||||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
|
|
||||||
boolean_t sharenfs;
|
boolean_t sharenfs;
|
||||||
boolean_t sharesmb;
|
boolean_t sharesmb;
|
||||||
@@ -299,7 +290,6 @@ changelist_postfix(prop_changelist_t *clp)
|
|||||||
*p++ = SA_PROTOCOL_SMB;
|
*p++ = SA_PROTOCOL_SMB;
|
||||||
*p++ = SA_NO_PROTOCOL;
|
*p++ = SA_NO_PROTOCOL;
|
||||||
zfs_commit_shares(proto);
|
zfs_commit_shares(proto);
|
||||||
uu_avl_walk_end(walk);
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -334,13 +324,10 @@ void
|
|||||||
changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
|
changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
|
||||||
{
|
{
|
||||||
prop_changenode_t *cn;
|
prop_changenode_t *cn;
|
||||||
uu_avl_walk_t *walk;
|
|
||||||
char newname[ZFS_MAX_DATASET_NAME_LEN];
|
char newname[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
|
|
||||||
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
|
for (cn = avl_first(&clp->cl_tree); cn != NULL;
|
||||||
return;
|
cn = AVL_NEXT(&clp->cl_tree, cn)) {
|
||||||
|
|
||||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
/*
|
/*
|
||||||
* Do not rename a clone that's not in the source hierarchy.
|
* 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,
|
(void) strlcpy(cn->cn_handle->zfs_name, newname,
|
||||||
sizeof (cn->cn_handle->zfs_name));
|
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)
|
changelist_unshare(prop_changelist_t *clp, const enum sa_protocol *proto)
|
||||||
{
|
{
|
||||||
prop_changenode_t *cn;
|
prop_changenode_t *cn;
|
||||||
uu_avl_walk_t *walk;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (clp->cl_prop != ZFS_PROP_SHARENFS &&
|
if (clp->cl_prop != ZFS_PROP_SHARENFS &&
|
||||||
clp->cl_prop != ZFS_PROP_SHARESMB)
|
clp->cl_prop != ZFS_PROP_SHARESMB)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
|
for (cn = avl_first(&clp->cl_tree); cn != NULL;
|
||||||
return (-1);
|
cn = AVL_NEXT(&clp->cl_tree, cn)) {
|
||||||
|
|
||||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
if (zfs_unshare(cn->cn_handle, NULL, proto) != 0)
|
if (zfs_unshare(cn->cn_handle, NULL, proto) != 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
|
for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
|
||||||
sa_commit_shares(*p);
|
sa_commit_shares(*p);
|
||||||
uu_avl_walk_end(walk);
|
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@@ -411,22 +392,16 @@ void
|
|||||||
changelist_remove(prop_changelist_t *clp, const char *name)
|
changelist_remove(prop_changelist_t *clp, const char *name)
|
||||||
{
|
{
|
||||||
prop_changenode_t *cn;
|
prop_changenode_t *cn;
|
||||||
uu_avl_walk_t *walk;
|
|
||||||
|
|
||||||
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
|
for (cn = avl_first(&clp->cl_tree); cn != NULL;
|
||||||
return;
|
cn = AVL_NEXT(&clp->cl_tree, cn)) {
|
||||||
|
|
||||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
|
||||||
if (strcmp(cn->cn_handle->zfs_name, name) == 0) {
|
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);
|
zfs_close(cn->cn_handle);
|
||||||
free(cn);
|
free(cn);
|
||||||
uu_avl_walk_end(walk);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uu_avl_walk_end(walk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -436,26 +411,14 @@ void
|
|||||||
changelist_free(prop_changelist_t *clp)
|
changelist_free(prop_changelist_t *clp)
|
||||||
{
|
{
|
||||||
prop_changenode_t *cn;
|
prop_changenode_t *cn;
|
||||||
|
void *cookie = NULL;
|
||||||
|
|
||||||
if (clp->cl_tree) {
|
while ((cn = avl_destroy_nodes(&clp->cl_tree, &cookie)) != NULL) {
|
||||||
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);
|
zfs_close(cn->cn_handle);
|
||||||
free(cn);
|
free(cn);
|
||||||
}
|
}
|
||||||
|
|
||||||
uu_avl_walk_end(walk);
|
avl_destroy(&clp->cl_tree);
|
||||||
uu_avl_destroy(clp->cl_tree);
|
|
||||||
}
|
|
||||||
if (clp->cl_pool)
|
|
||||||
uu_avl_pool_destroy(clp->cl_pool);
|
|
||||||
|
|
||||||
free(clp);
|
free(clp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,7 +430,7 @@ changelist_add_mounted(zfs_handle_t *zhp, void *data)
|
|||||||
{
|
{
|
||||||
prop_changelist_t *clp = data;
|
prop_changelist_t *clp = data;
|
||||||
prop_changenode_t *cn;
|
prop_changenode_t *cn;
|
||||||
uu_avl_index_t idx;
|
avl_index_t idx;
|
||||||
|
|
||||||
ASSERT3U(clp->cl_prop, ==, ZFS_PROP_MOUNTPOINT);
|
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)
|
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
|
||||||
clp->cl_haszonedchild = B_TRUE;
|
clp->cl_haszonedchild = B_TRUE;
|
||||||
|
|
||||||
uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
|
if (avl_find(&clp->cl_tree, cn, &idx) == NULL) {
|
||||||
|
avl_insert(&clp->cl_tree, cn, idx);
|
||||||
if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
|
|
||||||
uu_avl_insert(clp->cl_tree, cn, idx);
|
|
||||||
} else {
|
} else {
|
||||||
free(cn);
|
free(cn);
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
@@ -553,12 +514,9 @@ change_one(zfs_handle_t *zhp, void *data)
|
|||||||
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
|
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
|
||||||
clp->cl_haszonedchild = B_TRUE;
|
clp->cl_haszonedchild = B_TRUE;
|
||||||
|
|
||||||
uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
|
avl_index_t idx;
|
||||||
|
if (avl_find(&clp->cl_tree, cn, &idx) == NULL) {
|
||||||
uu_avl_index_t idx;
|
avl_insert(&clp->cl_tree, cn, idx);
|
||||||
|
|
||||||
if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
|
|
||||||
uu_avl_insert(clp->cl_tree, cn, idx);
|
|
||||||
} else {
|
} else {
|
||||||
free(cn);
|
free(cn);
|
||||||
cn = NULL;
|
cn = NULL;
|
||||||
@@ -610,11 +568,11 @@ compare_props(const void *a, const void *b, zfs_prop_t prop)
|
|||||||
else if (!haspropa && !haspropb)
|
else if (!haspropa && !haspropb)
|
||||||
return (0);
|
return (0);
|
||||||
else
|
else
|
||||||
return (strcmp(propb, propa));
|
return (TREE_ISIGN(strcmp(propb, propa)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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
|
* 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
|
* hierarchy that is different from the dataset hierarchy, and still
|
||||||
* allow it to be changed.
|
* allow it to be changed.
|
||||||
*/
|
*/
|
||||||
(void) unused;
|
|
||||||
return (compare_props(a, b, ZFS_PROP_MOUNTPOINT));
|
return (compare_props(a, b, ZFS_PROP_MOUNTPOINT));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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));
|
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),
|
sizeof (prop_changenode_t),
|
||||||
offsetof(prop_changenode_t, cn_treenode),
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
clp->cl_tree = uu_avl_create(clp->cl_pool, NULL, UU_DEFAULT);
|
|
||||||
clp->cl_gflags = gather_flags;
|
clp->cl_gflags = gather_flags;
|
||||||
clp->cl_mflags = mnt_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
|
* 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
|
* 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_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
|
||||||
cn->cn_needpost = B_TRUE;
|
cn->cn_needpost = B_TRUE;
|
||||||
|
|
||||||
uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
|
avl_index_t idx;
|
||||||
uu_avl_index_t idx;
|
if (avl_find(&clp->cl_tree, cn, &idx) == NULL) {
|
||||||
if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
|
avl_insert(&clp->cl_tree, cn, idx);
|
||||||
uu_avl_insert(clp->cl_tree, cn, idx);
|
|
||||||
} else {
|
} else {
|
||||||
free(cn);
|
free(cn);
|
||||||
zfs_close(temp);
|
zfs_close(temp);
|
||||||
|
|||||||
+15
-46
@@ -47,55 +47,37 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <libuutil.h>
|
|
||||||
|
|
||||||
#include "libzfs_impl.h"
|
#include "libzfs_impl.h"
|
||||||
|
|
||||||
typedef struct config_node {
|
typedef struct config_node {
|
||||||
char *cn_name;
|
char *cn_name;
|
||||||
nvlist_t *cn_config;
|
nvlist_t *cn_config;
|
||||||
uu_avl_node_t cn_avl;
|
avl_node_t cn_avl;
|
||||||
} config_node_t;
|
} config_node_t;
|
||||||
|
|
||||||
static int
|
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 *ca = (config_node_t *)a;
|
||||||
const config_node_t *cb = (config_node_t *)b;
|
const config_node_t *cb = (config_node_t *)b;
|
||||||
|
|
||||||
int ret = strcmp(ca->cn_name, cb->cn_name);
|
return (TREE_ISIGN(strcmp(ca->cn_name, cb->cn_name)));
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
return (-1);
|
|
||||||
else if (ret > 0)
|
|
||||||
return (1);
|
|
||||||
else
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
namespace_clear(libzfs_handle_t *hdl)
|
namespace_clear(libzfs_handle_t *hdl)
|
||||||
{
|
{
|
||||||
if (hdl->libzfs_ns_avl) {
|
|
||||||
config_node_t *cn;
|
config_node_t *cn;
|
||||||
void *cookie = NULL;
|
void *cookie = NULL;
|
||||||
|
|
||||||
while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl,
|
while ((cn = avl_destroy_nodes(&hdl->libzfs_ns_avl, &cookie)) != NULL) {
|
||||||
&cookie)) != NULL) {
|
|
||||||
nvlist_free(cn->cn_config);
|
nvlist_free(cn->cn_config);
|
||||||
free(cn->cn_name);
|
free(cn->cn_name);
|
||||||
free(cn);
|
free(cn);
|
||||||
}
|
}
|
||||||
|
|
||||||
uu_avl_destroy(hdl->libzfs_ns_avl);
|
avl_destroy(&hdl->libzfs_ns_avl);
|
||||||
hdl->libzfs_ns_avl = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdl->libzfs_ns_avlpool) {
|
|
||||||
uu_avl_pool_destroy(hdl->libzfs_ns_avlpool);
|
|
||||||
hdl->libzfs_ns_avlpool = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -111,20 +93,8 @@ namespace_reload(libzfs_handle_t *hdl)
|
|||||||
void *cookie;
|
void *cookie;
|
||||||
|
|
||||||
if (hdl->libzfs_ns_gen == 0) {
|
if (hdl->libzfs_ns_gen == 0) {
|
||||||
/*
|
avl_create(&hdl->libzfs_ns_avl, config_node_compare,
|
||||||
* This is the first time we've accessed the configuration
|
sizeof (config_node_t), offsetof(config_node_t, cn_avl));
|
||||||
* 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zcmd_alloc_dst_nvlist(hdl, &zc, 0);
|
zcmd_alloc_dst_nvlist(hdl, &zc, 0);
|
||||||
@@ -167,7 +137,7 @@ namespace_reload(libzfs_handle_t *hdl)
|
|||||||
* Clear out any existing configuration information.
|
* Clear out any existing configuration information.
|
||||||
*/
|
*/
|
||||||
cookie = NULL;
|
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);
|
nvlist_free(cn->cn_config);
|
||||||
free(cn->cn_name);
|
free(cn->cn_name);
|
||||||
free(cn);
|
free(cn);
|
||||||
@@ -176,7 +146,7 @@ namespace_reload(libzfs_handle_t *hdl)
|
|||||||
elem = NULL;
|
elem = NULL;
|
||||||
while ((elem = nvlist_next_nvpair(config, elem)) != NULL) {
|
while ((elem = nvlist_next_nvpair(config, elem)) != NULL) {
|
||||||
nvlist_t *child;
|
nvlist_t *child;
|
||||||
uu_avl_index_t where;
|
avl_index_t where;
|
||||||
|
|
||||||
cn = zfs_alloc(hdl, sizeof (config_node_t));
|
cn = zfs_alloc(hdl, sizeof (config_node_t));
|
||||||
cn->cn_name = zfs_strdup(hdl, nvpair_name(elem));
|
cn->cn_name = zfs_strdup(hdl, nvpair_name(elem));
|
||||||
@@ -187,10 +157,9 @@ namespace_reload(libzfs_handle_t *hdl)
|
|||||||
nvlist_free(config);
|
nvlist_free(config);
|
||||||
return (no_memory(hdl));
|
return (no_memory(hdl));
|
||||||
}
|
}
|
||||||
verify(uu_avl_find(hdl->libzfs_ns_avl, cn, NULL, &where)
|
verify(avl_find(&hdl->libzfs_ns_avl, cn, &where) == NULL);
|
||||||
== NULL);
|
|
||||||
|
|
||||||
uu_avl_insert(hdl->libzfs_ns_avl, cn, where);
|
avl_insert(&hdl->libzfs_ns_avl, cn, where);
|
||||||
}
|
}
|
||||||
|
|
||||||
nvlist_free(config);
|
nvlist_free(config);
|
||||||
@@ -400,8 +369,8 @@ zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data)
|
|||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
hdl->libzfs_pool_iter++;
|
hdl->libzfs_pool_iter++;
|
||||||
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
|
for (cn = avl_first(&hdl->libzfs_ns_avl); cn != NULL;
|
||||||
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
|
cn = AVL_NEXT(&hdl->libzfs_ns_avl, cn)) {
|
||||||
|
|
||||||
if (zpool_skip_pool(cn->cn_name))
|
if (zpool_skip_pool(cn->cn_name))
|
||||||
continue;
|
continue;
|
||||||
@@ -438,8 +407,8 @@ zfs_iter_root(libzfs_handle_t *hdl, zfs_iter_f func, void *data)
|
|||||||
if (namespace_reload(hdl) != 0)
|
if (namespace_reload(hdl) != 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
|
for (cn = avl_first(&hdl->libzfs_ns_avl); cn != NULL;
|
||||||
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
|
cn = AVL_NEXT(&hdl->libzfs_ns_avl, cn)) {
|
||||||
|
|
||||||
if (zpool_skip_pool(cn->cn_name))
|
if (zpool_skip_pool(cn->cn_name))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
#include <sys/zfs_ioctl.h>
|
#include <sys/zfs_ioctl.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
||||||
#include <libuutil.h>
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <libshare.h>
|
#include <libshare.h>
|
||||||
#include <libzfs_core.h>
|
#include <libzfs_core.h>
|
||||||
@@ -51,8 +50,7 @@ struct libzfs_handle {
|
|||||||
int libzfs_error;
|
int libzfs_error;
|
||||||
int libzfs_fd;
|
int libzfs_fd;
|
||||||
zpool_handle_t *libzfs_pool_handles;
|
zpool_handle_t *libzfs_pool_handles;
|
||||||
uu_avl_pool_t *libzfs_ns_avlpool;
|
avl_tree_t libzfs_ns_avl;
|
||||||
uu_avl_t *libzfs_ns_avl;
|
|
||||||
uint64_t libzfs_ns_gen;
|
uint64_t libzfs_ns_gen;
|
||||||
int libzfs_desc_active;
|
int libzfs_desc_active;
|
||||||
char libzfs_action[1024];
|
char libzfs_action[1024];
|
||||||
|
|||||||
Reference in New Issue
Block a user