@@ -81,6 +81,75 @@ zfs_type_to_nvl(zfs_type_t type)
81
81
return (nvl );
82
82
}
83
83
84
+ typedef struct zfs_iter_cb_data {
85
+ libzfs_handle_t * zicb_hdl ;
86
+ zfs_handle_t zicb_zhp ;
87
+ void * zicb_data ;
88
+ zfs_iter_f zicb_func ;
89
+ zfs_cmd_t zicb_zc ;
90
+ } zfs_iter_cb_data_t ;
91
+
92
+ int
93
+ zfs_iter_cb (nvlist_t * nvl , void * data )
94
+ {
95
+ nvlist_t * nvl_prop , * nvl_dds ;
96
+ zfs_iter_cb_data_t * cb = data ;
97
+ zfs_handle_t * nzhp ;
98
+ char * name ;
99
+ int ret ;
100
+
101
+ if ((ret = nvlist_lookup_nvlist (nvl , "properties" , & nvl_prop ))
102
+ != 0 ||
103
+ (ret = nvlist_lookup_string (nvl , "name" , & name )) != 0 ||
104
+ (ret = nvlist_lookup_nvlist (nvl , "dmu_objset_stats" ,
105
+ & nvl_dds )) != 0 ||
106
+ (ret = dmu_objset_stat_nvlts (nvl_dds , & cb -> zicb_zc .zc_objset_stats ))
107
+ != 0 ) {
108
+ return (EINVAL );
109
+ }
110
+
111
+ strlcpy (cb -> zicb_zc .zc_name , name , sizeof (cb -> zicb_zc .zc_name ));
112
+
113
+ cb -> zicb_zc .zc_nvlist_dst_size = fnvlist_size (nvl_prop );
114
+ if ((ret = zcmd_expand_dst_nvlist (cb -> zicb_hdl , & cb -> zicb_zc ))) {
115
+ if (ret == -1 )
116
+ ret = ENOMEM ;
117
+ return (ret );
118
+ }
119
+
120
+ ret = nvlist_pack (nvl_prop , (char * * ) & cb -> zicb_zc .zc_nvlist_dst ,
121
+ & cb -> zicb_zc .zc_nvlist_dst_size , NV_ENCODE_NATIVE , 0 );
122
+
123
+ cb -> zicb_zc .zc_nvlist_dst_filled = B_TRUE ;
124
+
125
+ /*
126
+ * Errors here do not make sense, so we bail.
127
+ */
128
+ if (strchr (name , '#' ) != NULL ) {
129
+ zfs_handle_t * zhp = & cb -> zicb_zhp ;
130
+ zhp -> zfs_hdl = cb -> zicb_hdl ;
131
+ switch (cb -> zicb_zc .zc_objset_stats .dds_type ) {
132
+ case DMU_OST_ZFS :
133
+ zhp -> zfs_head_type = ZFS_TYPE_FILESYSTEM ;
134
+ break ;
135
+ case DMU_OST_ZVOL :
136
+ zhp -> zfs_head_type = ZFS_TYPE_VOLUME ;
137
+ break ;
138
+ default :
139
+ return (EINVAL );
140
+ }
141
+ nzhp = make_bookmark_handle (zhp , name , nvl_prop );
142
+ } else if ((ret != 0 ) ||
143
+ (nzhp = make_dataset_handle_zc (cb -> zicb_hdl , & cb -> zicb_zc )) == NULL )
144
+ return (EINVAL );
145
+
146
+ ret = (* cb -> zicb_func )(nzhp , cb -> zicb_data );
147
+
148
+ zfs_close (nzhp );
149
+
150
+ return (ret );
151
+ }
152
+
84
153
/*
85
154
* Iterate over all children filesystems
86
155
*/
@@ -89,28 +158,14 @@ zfs_iter_generic(libzfs_handle_t *hdl, const char *name, zfs_type_t type,
89
158
int64_t mindepth , int64_t maxdepth , boolean_t depth_specified ,
90
159
zfs_iter_f func , void * data )
91
160
{
92
- zfs_cmd_t zc = {"\0" };
93
- zfs_handle_t * nzhp ;
94
- nvlist_t * tnvl ;
95
- nvlist_t * opts ;
96
- int fildes [2 ];
97
- zfs_pipe_record_t zpr ;
161
+ zfs_iter_cb_data_t cb_data ;
162
+ nvlist_t * tnvl , * opts ;
98
163
int ret ;
99
164
100
- if (zcmd_alloc_dst_nvlist (hdl , & zc , 0 ) != 0 )
165
+ bzero (& cb_data .zicb_zc , sizeof (cb_data .zicb_zc ));
166
+ if (zcmd_alloc_dst_nvlist (hdl , & cb_data .zicb_zc , 0 ) != 0 )
101
167
return (-1 );
102
168
103
- ret = pipe (fildes );
104
- if (ret == -1 ) {
105
- switch (errno ) {
106
- default :
107
- ret = zfs_standard_error (hdl , errno ,
108
- dgettext (TEXT_DOMAIN ,
109
- "cannot iterate filesystems" ));
110
- break ;
111
- }
112
- }
113
-
114
169
opts = fnvlist_alloc ();
115
170
if (depth_specified ) {
116
171
switch (maxdepth ) {
@@ -119,7 +174,8 @@ zfs_iter_generic(libzfs_handle_t *hdl, const char *name, zfs_type_t type,
119
174
default :
120
175
if (maxdepth < 0 ) {
121
176
fnvlist_free (opts );
122
- return (-1 );
177
+ ret = -1 ;
178
+ goto out ;
123
179
}
124
180
fnvlist_add_uint64 (opts , "maxrecurse" , maxdepth );
125
181
}
@@ -129,105 +185,23 @@ zfs_iter_generic(libzfs_handle_t *hdl, const char *name, zfs_type_t type,
129
185
130
186
tnvl = zfs_type_to_nvl (type );
131
187
fnvlist_add_nvlist (opts , "type" , tnvl );
132
- fnvlist_add_int32 (opts , "fd" , fildes [1 ]);
133
-
134
- if ((ret = lzc_list (name , opts )) != 0 ) {
135
- fnvlist_free (opts );
136
- close (fildes [0 ]);
137
- close (fildes [1 ]);
138
- return (ret );
139
- }
140
- fnvlist_free (tnvl );
141
- fnvlist_free (opts );
142
-
143
- while ((ret = read (fildes [0 ], & zpr ,
144
- sizeof (zfs_pipe_record_t ))) == sizeof (uint64_t ) &&
145
- zpr .zpr_data_size != 0 && zpr .zpr_err == 0 ) {
146
- nvlist_t * nvl , * nvl_prop , * nvl_dds ;
147
- char * name ;
148
- #ifdef _LITTLE_ENDIAN
149
- uint32_t size = (zpr .zpr_endian ) ? zpr .zpr_data_size :
150
- BSWAP_32 (zpr .zpr_data_size );
151
- #else
152
- uint32_t size = (zpr .zpr_endian ) ? BSWAP_32 (zpr .zpr_data_size ) :
153
- zpr .zpr_data_size ;
154
- #endif
155
- char * buf = umem_alloc (size , UMEM_NOFAIL );
156
-
157
- ret = read (fildes [0 ], buf , size );
158
-
159
- if (size != ret || (ret = nvlist_unpack (buf +
160
- zpr .zpr_header_size , size , & nvl , 0 )) != 0 ) {
161
- umem_free (buf , size );
162
- goto out ;
163
- }
164
-
165
- if ((ret = nvlist_lookup_nvlist (nvl , "properties" , & nvl_prop ))
166
- != 0 ||
167
- (ret = nvlist_lookup_string (nvl , "name" , & name )) != 0 ||
168
- (ret = nvlist_lookup_nvlist (nvl , "dmu_objset_stats" ,
169
- & nvl_dds )) != 0 ||
170
- (ret = dmu_objset_stat_nvlts (nvl_dds , & zc .zc_objset_stats ))
171
- != 0 ) {
172
- ret = EINVAL ;
173
- umem_free (buf , size );
174
- goto out ;
175
- }
176
-
177
- strlcpy (zc .zc_name , name , sizeof (zc .zc_name ));
178
- umem_free (buf , size );
179
-
180
- zc .zc_nvlist_dst_size = fnvlist_size (nvl_prop );
181
- if ((ret = zcmd_expand_dst_nvlist (hdl , & zc ))) {
182
- if (ret == -1 )
183
- ret = ENOMEM ;
184
- goto out ;
185
- }
186
188
187
- ret = nvlist_pack (nvl_prop , (char * * ) & zc .zc_nvlist_dst ,
188
- & zc .zc_nvlist_dst_size , NV_ENCODE_NATIVE , 0 );
189
+ cb_data .zicb_hdl = hdl ;
190
+ cb_data .zicb_func = func ;
191
+ cb_data .zicb_data = data ;
189
192
190
- zc . zc_nvlist_dst_filled = B_TRUE ;
193
+ ret = lzc_list_iter ( name , opts , & zfs_iter_cb , & cb_data ) ;
191
194
192
- /*
193
- * Errors here do not make sense, so we bail.
194
- */
195
- if (strchr (name , '#' ) != NULL ) {
196
- zfs_handle_t * zhp = calloc (sizeof (zfs_handle_t ), 1 );
197
- if (zhp == NULL ) {
198
- ret = ENOMEM ;
199
- goto out ;
200
- }
201
- zhp -> zfs_hdl = hdl ;
202
- switch (zc .zc_objset_stats .dds_type ) {
203
- case DMU_OST_ZFS :
204
- zhp -> zfs_head_type = ZFS_TYPE_FILESYSTEM ;
205
- break ;
206
- case DMU_OST_ZVOL :
207
- zhp -> zfs_head_type = ZFS_TYPE_VOLUME ;
208
- break ;
209
- default :
210
- ret = EINVAL ;
211
- goto out ;
212
- }
213
- nzhp = make_bookmark_handle (zhp , name , nvl_prop );
214
- free (zhp );
215
- if (nzhp == NULL )
216
- continue ;
217
- } else if ((ret != 0 ) ||
218
- (nzhp = make_dataset_handle_zc (hdl , & zc )) == NULL ) {
219
- ret = EINVAL ;
220
- goto out ;
221
- }
195
+ if (ret )
196
+ (void ) zfs_standard_error (hdl , ret , dgettext (TEXT_DOMAIN ,
197
+ "cannot iterate filesystems" ));
222
198
223
- if ((ret = func (nzhp , data )) != 0 )
224
- goto out ;
225
- }
226
199
200
+ fnvlist_free (tnvl );
201
+ fnvlist_free (opts );
227
202
out :
228
- close (fildes [0 ]);
229
- close (fildes [1 ]);
230
- zcmd_free_nvlists (& zc );
203
+ zcmd_free_nvlists (& cb_data .zicb_zc );
204
+
231
205
return ((ret < 0 ) ? ret : 0 );
232
206
}
233
207
0 commit comments