78 zpool_handle_t *zph;
79
80 if ((cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS) == 0)
81 return (cb->cb_types & ZFS_TYPE_SNAPSHOT);
82
83 zph = zfs_get_pool_handle(zhp);
84 return (zpool_get_prop_int(zph, ZPOOL_PROP_LISTSNAPS, NULL));
85 }
86
87 /*
88 * Called for each dataset. If the object is of an appropriate type,
89 * add it to the avl tree and recurse over any children as necessary.
90 */
91 static int
92 zfs_callback(zfs_handle_t *zhp, void *data)
93 {
94 callback_data_t *cb = data;
95 boolean_t should_close = B_TRUE;
96 boolean_t include_snaps = zfs_include_snapshots(zhp, cb);
97 boolean_t include_bmarks = (cb->cb_types & ZFS_TYPE_BOOKMARK);
98
99 if ((zfs_get_type(zhp) & cb->cb_types) ||
100 ((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
101 uu_avl_index_t idx;
102 zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
103
104 node->zn_handle = zhp;
105 uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
106 if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
107 &idx) == NULL) {
108 if (cb->cb_proplist) {
109 if ((*cb->cb_proplist) &&
110 !(*cb->cb_proplist)->pl_all)
111 zfs_prune_proplist(zhp,
112 cb->cb_props_table);
113
114 if (zfs_expand_proplist(zhp, cb->cb_proplist,
115 (cb->cb_flags & ZFS_ITER_RECVD_PROPS),
116 (cb->cb_flags & ZFS_ITER_LITERAL_PROPS))
117 != 0) {
119 return (-1);
120 }
121 }
122 uu_avl_insert(cb->cb_avl, node, idx);
123 should_close = B_FALSE;
124 } else {
125 free(node);
126 }
127 }
128
129 /*
130 * Recurse if necessary.
131 */
132 if (cb->cb_flags & ZFS_ITER_RECURSE &&
133 ((cb->cb_flags & ZFS_ITER_DEPTH_LIMIT) == 0 ||
134 cb->cb_depth < cb->cb_depth_limit)) {
135 cb->cb_depth++;
136 if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
137 (void) zfs_iter_filesystems(zhp, zfs_callback, data);
138 if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
139 ZFS_TYPE_BOOKMARK)) == 0) && include_snaps)
140 (void) zfs_iter_snapshots(zhp,
141 (cb->cb_flags & ZFS_ITER_SIMPLE) != 0, zfs_callback,
142 data);
143 if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
144 ZFS_TYPE_BOOKMARK)) == 0) && include_bmarks)
145 (void) zfs_iter_bookmarks(zhp, zfs_callback, data);
146 cb->cb_depth--;
147 }
148
149 if (should_close)
150 zfs_close(zhp);
151
152 return (0);
153 }
154
155 int
156 zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
157 boolean_t reverse)
158 {
159 zfs_sort_column_t *col;
160 zfs_prop_t prop;
161
162 if ((prop = zfs_name_to_prop(name)) == ZPROP_INVAL &&
|
78 zpool_handle_t *zph;
79
80 if ((cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS) == 0)
81 return (cb->cb_types & ZFS_TYPE_SNAPSHOT);
82
83 zph = zfs_get_pool_handle(zhp);
84 return (zpool_get_prop_int(zph, ZPOOL_PROP_LISTSNAPS, NULL));
85 }
86
87 /*
88 * Called for each dataset. If the object is of an appropriate type,
89 * add it to the avl tree and recurse over any children as necessary.
90 */
91 static int
92 zfs_callback(zfs_handle_t *zhp, void *data)
93 {
94 callback_data_t *cb = data;
95 boolean_t should_close = B_TRUE;
96 boolean_t include_snaps = zfs_include_snapshots(zhp, cb);
97 boolean_t include_bmarks = (cb->cb_types & ZFS_TYPE_BOOKMARK);
98 boolean_t include_autosnaps =
99 ((cb->cb_types & ZFS_TYPE_AUTOSNAP) &&
100 !(cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS));
101
102 if ((zfs_get_type(zhp) & cb->cb_types) ||
103 ((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
104 uu_avl_index_t idx;
105 zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
106
107 node->zn_handle = zhp;
108 uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
109 if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
110 &idx) == NULL) {
111 if (cb->cb_proplist) {
112 if ((*cb->cb_proplist) &&
113 !(*cb->cb_proplist)->pl_all)
114 zfs_prune_proplist(zhp,
115 cb->cb_props_table);
116
117 if (zfs_expand_proplist(zhp, cb->cb_proplist,
118 (cb->cb_flags & ZFS_ITER_RECVD_PROPS),
119 (cb->cb_flags & ZFS_ITER_LITERAL_PROPS))
120 != 0) {
122 return (-1);
123 }
124 }
125 uu_avl_insert(cb->cb_avl, node, idx);
126 should_close = B_FALSE;
127 } else {
128 free(node);
129 }
130 }
131
132 /*
133 * Recurse if necessary.
134 */
135 if (cb->cb_flags & ZFS_ITER_RECURSE &&
136 ((cb->cb_flags & ZFS_ITER_DEPTH_LIMIT) == 0 ||
137 cb->cb_depth < cb->cb_depth_limit)) {
138 cb->cb_depth++;
139 if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
140 (void) zfs_iter_filesystems(zhp, zfs_callback, data);
141 if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
142 ZFS_TYPE_BOOKMARK | ZFS_TYPE_AUTOSNAP)) == 0)) {
143 if (include_snaps) {
144 (void) zfs_iter_snapshots(zhp,
145 (cb->cb_flags & ZFS_ITER_SIMPLE) != 0,
146 zfs_callback, data);
147 }
148
149 if (include_autosnaps) {
150 (void) zfs_iter_autosnapshots(zhp,
151 (cb->cb_flags & ZFS_ITER_SIMPLE) != 0,
152 zfs_callback, data);
153 }
154 }
155
156 if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
157 ZFS_TYPE_BOOKMARK)) == 0) && include_bmarks)
158 (void) zfs_iter_bookmarks(zhp, zfs_callback, data);
159 cb->cb_depth--;
160 }
161
162 if (should_close)
163 zfs_close(zhp);
164
165 return (0);
166 }
167
168 int
169 zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
170 boolean_t reverse)
171 {
172 zfs_sort_column_t *col;
173 zfs_prop_t prop;
174
175 if ((prop = zfs_name_to_prop(name)) == ZPROP_INVAL &&
|