4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2013 Xin Li <delphij@FreeBSD.org>. All rights reserved.
23 * Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
24 * Portions Copyright 2005, 2010, Oracle and/or its affiliates.
25 * All rights reserved.
26 * Use is subject to license terms.
29 #include <sys/types.h>
30 #include <sys/param.h>
34 #include <sys/nvpair.h>
35 #include <sys/dsl_deleg.h>
36 #include <sys/zfs_ioctl.h>
37 #include "zfs_namecheck.h"
38 #include "zfs_ioctl_compat.h"
40 static int zfs_version_ioctl = ZFS_IOCVER_CURRENT;
41 SYSCTL_DECL(_vfs_zfs_version);
42 SYSCTL_INT(_vfs_zfs_version, OID_AUTO, ioctl, CTLFLAG_RD, &zfs_version_ioctl,
43 0, "ZFS_IOCTL_VERSION");
46 * FreeBSD zfs_cmd compatibility with older binaries
47 * appropriately remap/extend the zfs_cmd_t structure
50 zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag)
53 zfs_cmd_v28_t *zc28_c;
54 zfs_cmd_deadman_t *zcdm_c;
55 zfs_cmd_zcmd_t *zcmd_c;
56 zfs_cmd_edbp_t *edbp_c;
57 zfs_cmd_resume_t *resume_c;
60 case ZFS_CMD_COMPAT_RESUME:
61 resume_c = (void *)addr;
63 strlcpy(zc->zc_name, resume_c->zc_name, MAXPATHLEN);
64 strlcpy(zc->zc_value, resume_c->zc_value, MAXPATHLEN * 2);
65 strlcpy(zc->zc_string, resume_c->zc_string, MAXPATHLEN);
67 #define FIELD_COPY(field) zc->field = resume_c->field
68 FIELD_COPY(zc_nvlist_src);
69 FIELD_COPY(zc_nvlist_src_size);
70 FIELD_COPY(zc_nvlist_dst);
71 FIELD_COPY(zc_nvlist_dst_size);
72 FIELD_COPY(zc_nvlist_dst_filled);
74 FIELD_COPY(zc_history);
76 FIELD_COPY(zc_nvlist_conf);
77 FIELD_COPY(zc_nvlist_conf_size);
78 FIELD_COPY(zc_cookie);
79 FIELD_COPY(zc_objset_type);
80 FIELD_COPY(zc_perm_action);
81 FIELD_COPY(zc_history_len);
82 FIELD_COPY(zc_history_offset);
84 FIELD_COPY(zc_iflags);
86 FIELD_COPY(zc_jailid);
87 FIELD_COPY(zc_objset_stats);
88 FIELD_COPY(zc_begin_record);
89 FIELD_COPY(zc_inject_record.zi_objset);
90 FIELD_COPY(zc_inject_record.zi_object);
91 FIELD_COPY(zc_inject_record.zi_start);
92 FIELD_COPY(zc_inject_record.zi_end);
93 FIELD_COPY(zc_inject_record.zi_guid);
94 FIELD_COPY(zc_inject_record.zi_level);
95 FIELD_COPY(zc_inject_record.zi_error);
96 FIELD_COPY(zc_inject_record.zi_type);
97 FIELD_COPY(zc_inject_record.zi_freq);
98 FIELD_COPY(zc_inject_record.zi_failfast);
99 strlcpy(zc->zc_inject_record.zi_func,
100 resume_c->zc_inject_record.zi_func, MAXNAMELEN);
101 FIELD_COPY(zc_inject_record.zi_iotype);
102 FIELD_COPY(zc_inject_record.zi_duration);
103 FIELD_COPY(zc_inject_record.zi_timer);
104 zc->zc_inject_record.zi_nlanes = 1;
105 FIELD_COPY(zc_inject_record.zi_cmd);
106 FIELD_COPY(zc_inject_record.zi_pad);
107 FIELD_COPY(zc_defer_destroy);
108 FIELD_COPY(zc_flags);
109 FIELD_COPY(zc_action_handle);
110 FIELD_COPY(zc_cleanup_fd);
111 FIELD_COPY(zc_simple);
112 FIELD_COPY(zc_resumable);
113 FIELD_COPY(zc_sendobj);
114 FIELD_COPY(zc_fromobj);
115 FIELD_COPY(zc_createtxg);
120 case ZFS_CMD_COMPAT_EDBP:
121 edbp_c = (void *)addr;
123 strlcpy(zc->zc_name, edbp_c->zc_name, MAXPATHLEN);
124 strlcpy(zc->zc_value, edbp_c->zc_value, MAXPATHLEN * 2);
125 strlcpy(zc->zc_string, edbp_c->zc_string, MAXPATHLEN);
127 #define FIELD_COPY(field) zc->field = edbp_c->field
128 FIELD_COPY(zc_nvlist_src);
129 FIELD_COPY(zc_nvlist_src_size);
130 FIELD_COPY(zc_nvlist_dst);
131 FIELD_COPY(zc_nvlist_dst_size);
132 FIELD_COPY(zc_nvlist_dst_filled);
134 FIELD_COPY(zc_history);
136 FIELD_COPY(zc_nvlist_conf);
137 FIELD_COPY(zc_nvlist_conf_size);
138 FIELD_COPY(zc_cookie);
139 FIELD_COPY(zc_objset_type);
140 FIELD_COPY(zc_perm_action);
141 FIELD_COPY(zc_history_len);
142 FIELD_COPY(zc_history_offset);
144 FIELD_COPY(zc_iflags);
145 FIELD_COPY(zc_share);
146 FIELD_COPY(zc_jailid);
147 FIELD_COPY(zc_objset_stats);
148 zc->zc_begin_record.drr_u.drr_begin = edbp_c->zc_begin_record;
149 FIELD_COPY(zc_inject_record.zi_objset);
150 FIELD_COPY(zc_inject_record.zi_object);
151 FIELD_COPY(zc_inject_record.zi_start);
152 FIELD_COPY(zc_inject_record.zi_end);
153 FIELD_COPY(zc_inject_record.zi_guid);
154 FIELD_COPY(zc_inject_record.zi_level);
155 FIELD_COPY(zc_inject_record.zi_error);
156 FIELD_COPY(zc_inject_record.zi_type);
157 FIELD_COPY(zc_inject_record.zi_freq);
158 FIELD_COPY(zc_inject_record.zi_failfast);
159 strlcpy(zc->zc_inject_record.zi_func,
160 edbp_c->zc_inject_record.zi_func, MAXNAMELEN);
161 FIELD_COPY(zc_inject_record.zi_iotype);
162 FIELD_COPY(zc_inject_record.zi_duration);
163 FIELD_COPY(zc_inject_record.zi_timer);
164 zc->zc_inject_record.zi_nlanes = 1;
165 FIELD_COPY(zc_inject_record.zi_cmd);
166 FIELD_COPY(zc_inject_record.zi_pad);
167 FIELD_COPY(zc_defer_destroy);
168 FIELD_COPY(zc_flags);
169 FIELD_COPY(zc_action_handle);
170 FIELD_COPY(zc_cleanup_fd);
171 FIELD_COPY(zc_simple);
172 zc->zc_resumable = B_FALSE;
173 FIELD_COPY(zc_sendobj);
174 FIELD_COPY(zc_fromobj);
175 FIELD_COPY(zc_createtxg);
180 case ZFS_CMD_COMPAT_ZCMD:
181 zcmd_c = (void *)addr;
183 strlcpy(zc->zc_name, zcmd_c->zc_name, MAXPATHLEN);
184 strlcpy(zc->zc_value, zcmd_c->zc_value, MAXPATHLEN * 2);
185 strlcpy(zc->zc_string, zcmd_c->zc_string, MAXPATHLEN);
187 #define FIELD_COPY(field) zc->field = zcmd_c->field
188 FIELD_COPY(zc_nvlist_src);
189 FIELD_COPY(zc_nvlist_src_size);
190 FIELD_COPY(zc_nvlist_dst);
191 FIELD_COPY(zc_nvlist_dst_size);
192 FIELD_COPY(zc_nvlist_dst_filled);
194 FIELD_COPY(zc_history);
196 FIELD_COPY(zc_nvlist_conf);
197 FIELD_COPY(zc_nvlist_conf_size);
198 FIELD_COPY(zc_cookie);
199 FIELD_COPY(zc_objset_type);
200 FIELD_COPY(zc_perm_action);
201 FIELD_COPY(zc_history_len);
202 FIELD_COPY(zc_history_offset);
204 FIELD_COPY(zc_iflags);
205 FIELD_COPY(zc_share);
206 FIELD_COPY(zc_jailid);
207 FIELD_COPY(zc_objset_stats);
208 zc->zc_begin_record.drr_u.drr_begin = zcmd_c->zc_begin_record;
209 FIELD_COPY(zc_inject_record.zi_objset);
210 FIELD_COPY(zc_inject_record.zi_object);
211 FIELD_COPY(zc_inject_record.zi_start);
212 FIELD_COPY(zc_inject_record.zi_end);
213 FIELD_COPY(zc_inject_record.zi_guid);
214 FIELD_COPY(zc_inject_record.zi_level);
215 FIELD_COPY(zc_inject_record.zi_error);
216 FIELD_COPY(zc_inject_record.zi_type);
217 FIELD_COPY(zc_inject_record.zi_freq);
218 FIELD_COPY(zc_inject_record.zi_failfast);
219 strlcpy(zc->zc_inject_record.zi_func,
220 zcmd_c->zc_inject_record.zi_func, MAXNAMELEN);
221 FIELD_COPY(zc_inject_record.zi_iotype);
222 FIELD_COPY(zc_inject_record.zi_duration);
223 FIELD_COPY(zc_inject_record.zi_timer);
224 zc->zc_inject_record.zi_nlanes = 1;
225 FIELD_COPY(zc_inject_record.zi_cmd);
226 FIELD_COPY(zc_inject_record.zi_pad);
228 /* boolean_t -> uint32_t */
229 zc->zc_defer_destroy = (uint32_t)(zcmd_c->zc_defer_destroy);
232 FIELD_COPY(zc_action_handle);
233 FIELD_COPY(zc_cleanup_fd);
234 FIELD_COPY(zc_simple);
235 zc->zc_resumable = B_FALSE;
236 FIELD_COPY(zc_sendobj);
237 FIELD_COPY(zc_fromobj);
238 FIELD_COPY(zc_createtxg);
244 case ZFS_CMD_COMPAT_DEADMAN:
245 zcdm_c = (void *)addr;
247 strlcpy(zc->zc_name, zcdm_c->zc_name, MAXPATHLEN);
248 strlcpy(zc->zc_value, zcdm_c->zc_value, MAXPATHLEN * 2);
249 strlcpy(zc->zc_string, zcdm_c->zc_string, MAXPATHLEN);
251 #define FIELD_COPY(field) zc->field = zcdm_c->field
252 zc->zc_guid = zcdm_c->zc_guid;
253 zc->zc_nvlist_conf = zcdm_c->zc_nvlist_conf;
254 zc->zc_nvlist_conf_size = zcdm_c->zc_nvlist_conf_size;
255 zc->zc_nvlist_src = zcdm_c->zc_nvlist_src;
256 zc->zc_nvlist_src_size = zcdm_c->zc_nvlist_src_size;
257 zc->zc_nvlist_dst = zcdm_c->zc_nvlist_dst;
258 zc->zc_nvlist_dst_size = zcdm_c->zc_nvlist_dst_size;
259 zc->zc_cookie = zcdm_c->zc_cookie;
260 zc->zc_objset_type = zcdm_c->zc_objset_type;
261 zc->zc_perm_action = zcdm_c->zc_perm_action;
262 zc->zc_history = zcdm_c->zc_history;
263 zc->zc_history_len = zcdm_c->zc_history_len;
264 zc->zc_history_offset = zcdm_c->zc_history_offset;
265 zc->zc_obj = zcdm_c->zc_obj;
266 zc->zc_iflags = zcdm_c->zc_iflags;
267 zc->zc_share = zcdm_c->zc_share;
268 zc->zc_jailid = zcdm_c->zc_jailid;
269 zc->zc_objset_stats = zcdm_c->zc_objset_stats;
270 zc->zc_begin_record.drr_u.drr_begin = zcdm_c->zc_begin_record;
271 zc->zc_defer_destroy = zcdm_c->zc_defer_destroy;
272 (void)zcdm_c->zc_temphold;
273 zc->zc_action_handle = zcdm_c->zc_action_handle;
274 zc->zc_cleanup_fd = zcdm_c->zc_cleanup_fd;
275 zc->zc_simple = zcdm_c->zc_simple;
276 zc->zc_resumable = B_FALSE;
277 zc->zc_sendobj = zcdm_c->zc_sendobj;
278 zc->zc_fromobj = zcdm_c->zc_fromobj;
279 zc->zc_createtxg = zcdm_c->zc_createtxg;
280 zc->zc_stat = zcdm_c->zc_stat;
281 FIELD_COPY(zc_inject_record.zi_objset);
282 FIELD_COPY(zc_inject_record.zi_object);
283 FIELD_COPY(zc_inject_record.zi_start);
284 FIELD_COPY(zc_inject_record.zi_end);
285 FIELD_COPY(zc_inject_record.zi_guid);
286 FIELD_COPY(zc_inject_record.zi_level);
287 FIELD_COPY(zc_inject_record.zi_error);
288 FIELD_COPY(zc_inject_record.zi_type);
289 FIELD_COPY(zc_inject_record.zi_freq);
290 FIELD_COPY(zc_inject_record.zi_failfast);
291 strlcpy(zc->zc_inject_record.zi_func,
292 resume_c->zc_inject_record.zi_func, MAXNAMELEN);
293 FIELD_COPY(zc_inject_record.zi_iotype);
294 FIELD_COPY(zc_inject_record.zi_duration);
295 FIELD_COPY(zc_inject_record.zi_timer);
296 zc->zc_inject_record.zi_nlanes = 1;
297 FIELD_COPY(zc_inject_record.zi_cmd);
298 FIELD_COPY(zc_inject_record.zi_pad);
300 /* we always assume zc_nvlist_dst_filled is true */
301 zc->zc_nvlist_dst_filled = B_TRUE;
305 case ZFS_CMD_COMPAT_V28:
306 zc28_c = (void *)addr;
309 strlcpy(zc->zc_name, zc28_c->zc_name, MAXPATHLEN);
310 strlcpy(zc->zc_value, zc28_c->zc_value, MAXPATHLEN * 2);
311 strlcpy(zc->zc_string, zc28_c->zc_string, MAXPATHLEN);
312 zc->zc_guid = zc28_c->zc_guid;
313 zc->zc_nvlist_conf = zc28_c->zc_nvlist_conf;
314 zc->zc_nvlist_conf_size = zc28_c->zc_nvlist_conf_size;
315 zc->zc_nvlist_src = zc28_c->zc_nvlist_src;
316 zc->zc_nvlist_src_size = zc28_c->zc_nvlist_src_size;
317 zc->zc_nvlist_dst = zc28_c->zc_nvlist_dst;
318 zc->zc_nvlist_dst_size = zc28_c->zc_nvlist_dst_size;
319 zc->zc_cookie = zc28_c->zc_cookie;
320 zc->zc_objset_type = zc28_c->zc_objset_type;
321 zc->zc_perm_action = zc28_c->zc_perm_action;
322 zc->zc_history = zc28_c->zc_history;
323 zc->zc_history_len = zc28_c->zc_history_len;
324 zc->zc_history_offset = zc28_c->zc_history_offset;
325 zc->zc_obj = zc28_c->zc_obj;
326 zc->zc_iflags = zc28_c->zc_iflags;
327 zc->zc_share = zc28_c->zc_share;
328 zc->zc_jailid = zc28_c->zc_jailid;
329 zc->zc_objset_stats = zc28_c->zc_objset_stats;
330 zc->zc_begin_record.drr_u.drr_begin = zc28_c->zc_begin_record;
331 zc->zc_defer_destroy = zc28_c->zc_defer_destroy;
332 (void)zc28_c->zc_temphold;
333 zc->zc_action_handle = zc28_c->zc_action_handle;
334 zc->zc_cleanup_fd = zc28_c->zc_cleanup_fd;
335 zc->zc_simple = zc28_c->zc_simple;
336 zc->zc_resumable = B_FALSE;
337 zc->zc_sendobj = zc28_c->zc_sendobj;
338 zc->zc_fromobj = zc28_c->zc_fromobj;
339 zc->zc_createtxg = zc28_c->zc_createtxg;
340 zc->zc_stat = zc28_c->zc_stat;
342 /* zc->zc_inject_record */
343 zc->zc_inject_record.zi_objset =
344 zc28_c->zc_inject_record.zi_objset;
345 zc->zc_inject_record.zi_object =
346 zc28_c->zc_inject_record.zi_object;
347 zc->zc_inject_record.zi_start =
348 zc28_c->zc_inject_record.zi_start;
349 zc->zc_inject_record.zi_end =
350 zc28_c->zc_inject_record.zi_end;
351 zc->zc_inject_record.zi_guid =
352 zc28_c->zc_inject_record.zi_guid;
353 zc->zc_inject_record.zi_level =
354 zc28_c->zc_inject_record.zi_level;
355 zc->zc_inject_record.zi_error =
356 zc28_c->zc_inject_record.zi_error;
357 zc->zc_inject_record.zi_type =
358 zc28_c->zc_inject_record.zi_type;
359 zc->zc_inject_record.zi_freq =
360 zc28_c->zc_inject_record.zi_freq;
361 zc->zc_inject_record.zi_failfast =
362 zc28_c->zc_inject_record.zi_failfast;
363 strlcpy(zc->zc_inject_record.zi_func,
364 zc28_c->zc_inject_record.zi_func, MAXNAMELEN);
365 zc->zc_inject_record.zi_iotype =
366 zc28_c->zc_inject_record.zi_iotype;
367 zc->zc_inject_record.zi_duration =
368 zc28_c->zc_inject_record.zi_duration;
369 zc->zc_inject_record.zi_timer =
370 zc28_c->zc_inject_record.zi_timer;
371 zc->zc_inject_record.zi_nlanes = 1;
372 zc->zc_inject_record.zi_cmd = ZINJECT_UNINITIALIZED;
373 zc->zc_inject_record.zi_pad = 0;
376 case ZFS_CMD_COMPAT_V15:
380 strlcpy(zc->zc_name, zc_c->zc_name, MAXPATHLEN);
381 strlcpy(zc->zc_value, zc_c->zc_value, MAXPATHLEN);
382 strlcpy(zc->zc_string, zc_c->zc_string, MAXPATHLEN);
383 zc->zc_guid = zc_c->zc_guid;
384 zc->zc_nvlist_conf = zc_c->zc_nvlist_conf;
385 zc->zc_nvlist_conf_size = zc_c->zc_nvlist_conf_size;
386 zc->zc_nvlist_src = zc_c->zc_nvlist_src;
387 zc->zc_nvlist_src_size = zc_c->zc_nvlist_src_size;
388 zc->zc_nvlist_dst = zc_c->zc_nvlist_dst;
389 zc->zc_nvlist_dst_size = zc_c->zc_nvlist_dst_size;
390 zc->zc_cookie = zc_c->zc_cookie;
391 zc->zc_objset_type = zc_c->zc_objset_type;
392 zc->zc_perm_action = zc_c->zc_perm_action;
393 zc->zc_history = zc_c->zc_history;
394 zc->zc_history_len = zc_c->zc_history_len;
395 zc->zc_history_offset = zc_c->zc_history_offset;
396 zc->zc_obj = zc_c->zc_obj;
397 zc->zc_share = zc_c->zc_share;
398 zc->zc_jailid = zc_c->zc_jailid;
399 zc->zc_objset_stats = zc_c->zc_objset_stats;
400 zc->zc_begin_record.drr_u.drr_begin = zc_c->zc_begin_record;
402 /* zc->zc_inject_record */
403 zc->zc_inject_record.zi_objset =
404 zc_c->zc_inject_record.zi_objset;
405 zc->zc_inject_record.zi_object =
406 zc_c->zc_inject_record.zi_object;
407 zc->zc_inject_record.zi_start =
408 zc_c->zc_inject_record.zi_start;
409 zc->zc_inject_record.zi_end =
410 zc_c->zc_inject_record.zi_end;
411 zc->zc_inject_record.zi_guid =
412 zc_c->zc_inject_record.zi_guid;
413 zc->zc_inject_record.zi_level =
414 zc_c->zc_inject_record.zi_level;
415 zc->zc_inject_record.zi_error =
416 zc_c->zc_inject_record.zi_error;
417 zc->zc_inject_record.zi_type =
418 zc_c->zc_inject_record.zi_type;
419 zc->zc_inject_record.zi_freq =
420 zc_c->zc_inject_record.zi_freq;
421 zc->zc_inject_record.zi_failfast =
422 zc_c->zc_inject_record.zi_failfast;
428 zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request,
432 zfs_cmd_v28_t *zc28_c;
433 zfs_cmd_deadman_t *zcdm_c;
434 zfs_cmd_zcmd_t *zcmd_c;
435 zfs_cmd_edbp_t *edbp_c;
436 zfs_cmd_resume_t *resume_c;
439 case ZFS_CMD_COMPAT_RESUME:
440 resume_c = (void *)addr;
441 strlcpy(resume_c->zc_name, zc->zc_name, MAXPATHLEN);
442 strlcpy(resume_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
443 strlcpy(resume_c->zc_string, zc->zc_string, MAXPATHLEN);
445 #define FIELD_COPY(field) resume_c->field = zc->field
446 FIELD_COPY(zc_nvlist_src);
447 FIELD_COPY(zc_nvlist_src_size);
448 FIELD_COPY(zc_nvlist_dst);
449 FIELD_COPY(zc_nvlist_dst_size);
450 FIELD_COPY(zc_nvlist_dst_filled);
452 FIELD_COPY(zc_history);
454 FIELD_COPY(zc_nvlist_conf);
455 FIELD_COPY(zc_nvlist_conf_size);
456 FIELD_COPY(zc_cookie);
457 FIELD_COPY(zc_objset_type);
458 FIELD_COPY(zc_perm_action);
459 FIELD_COPY(zc_history_len);
460 FIELD_COPY(zc_history_offset);
462 FIELD_COPY(zc_iflags);
463 FIELD_COPY(zc_share);
464 FIELD_COPY(zc_jailid);
465 FIELD_COPY(zc_objset_stats);
466 FIELD_COPY(zc_begin_record);
467 FIELD_COPY(zc_inject_record.zi_objset);
468 FIELD_COPY(zc_inject_record.zi_object);
469 FIELD_COPY(zc_inject_record.zi_start);
470 FIELD_COPY(zc_inject_record.zi_end);
471 FIELD_COPY(zc_inject_record.zi_guid);
472 FIELD_COPY(zc_inject_record.zi_level);
473 FIELD_COPY(zc_inject_record.zi_error);
474 FIELD_COPY(zc_inject_record.zi_type);
475 FIELD_COPY(zc_inject_record.zi_freq);
476 FIELD_COPY(zc_inject_record.zi_failfast);
477 strlcpy(resume_c->zc_inject_record.zi_func,
478 zc->zc_inject_record.zi_func, MAXNAMELEN);
479 FIELD_COPY(zc_inject_record.zi_iotype);
480 FIELD_COPY(zc_inject_record.zi_duration);
481 FIELD_COPY(zc_inject_record.zi_timer);
482 FIELD_COPY(zc_inject_record.zi_cmd);
483 FIELD_COPY(zc_inject_record.zi_pad);
484 FIELD_COPY(zc_defer_destroy);
485 FIELD_COPY(zc_flags);
486 FIELD_COPY(zc_action_handle);
487 FIELD_COPY(zc_cleanup_fd);
488 FIELD_COPY(zc_simple);
489 FIELD_COPY(zc_sendobj);
490 FIELD_COPY(zc_fromobj);
491 FIELD_COPY(zc_createtxg);
496 case ZFS_CMD_COMPAT_EDBP:
497 edbp_c = (void *)addr;
498 strlcpy(edbp_c->zc_name, zc->zc_name, MAXPATHLEN);
499 strlcpy(edbp_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
500 strlcpy(edbp_c->zc_string, zc->zc_string, MAXPATHLEN);
502 #define FIELD_COPY(field) edbp_c->field = zc->field
503 FIELD_COPY(zc_nvlist_src);
504 FIELD_COPY(zc_nvlist_src_size);
505 FIELD_COPY(zc_nvlist_dst);
506 FIELD_COPY(zc_nvlist_dst_size);
507 FIELD_COPY(zc_nvlist_dst_filled);
509 FIELD_COPY(zc_history);
511 FIELD_COPY(zc_nvlist_conf);
512 FIELD_COPY(zc_nvlist_conf_size);
513 FIELD_COPY(zc_cookie);
514 FIELD_COPY(zc_objset_type);
515 FIELD_COPY(zc_perm_action);
516 FIELD_COPY(zc_history_len);
517 FIELD_COPY(zc_history_offset);
519 FIELD_COPY(zc_iflags);
520 FIELD_COPY(zc_share);
521 FIELD_COPY(zc_jailid);
522 FIELD_COPY(zc_objset_stats);
523 edbp_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
524 FIELD_COPY(zc_inject_record.zi_objset);
525 FIELD_COPY(zc_inject_record.zi_object);
526 FIELD_COPY(zc_inject_record.zi_start);
527 FIELD_COPY(zc_inject_record.zi_end);
528 FIELD_COPY(zc_inject_record.zi_guid);
529 FIELD_COPY(zc_inject_record.zi_level);
530 FIELD_COPY(zc_inject_record.zi_error);
531 FIELD_COPY(zc_inject_record.zi_type);
532 FIELD_COPY(zc_inject_record.zi_freq);
533 FIELD_COPY(zc_inject_record.zi_failfast);
534 strlcpy(resume_c->zc_inject_record.zi_func,
535 zc->zc_inject_record.zi_func, MAXNAMELEN);
536 FIELD_COPY(zc_inject_record.zi_iotype);
537 FIELD_COPY(zc_inject_record.zi_duration);
538 FIELD_COPY(zc_inject_record.zi_timer);
539 FIELD_COPY(zc_inject_record.zi_cmd);
540 FIELD_COPY(zc_inject_record.zi_pad);
541 FIELD_COPY(zc_defer_destroy);
542 FIELD_COPY(zc_flags);
543 FIELD_COPY(zc_action_handle);
544 FIELD_COPY(zc_cleanup_fd);
545 FIELD_COPY(zc_simple);
546 FIELD_COPY(zc_sendobj);
547 FIELD_COPY(zc_fromobj);
548 FIELD_COPY(zc_createtxg);
553 case ZFS_CMD_COMPAT_ZCMD:
554 zcmd_c = (void *)addr;
556 strlcpy(zcmd_c->zc_name, zc->zc_name, MAXPATHLEN);
557 strlcpy(zcmd_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
558 strlcpy(zcmd_c->zc_string, zc->zc_string, MAXPATHLEN);
560 #define FIELD_COPY(field) zcmd_c->field = zc->field
561 FIELD_COPY(zc_nvlist_src);
562 FIELD_COPY(zc_nvlist_src_size);
563 FIELD_COPY(zc_nvlist_dst);
564 FIELD_COPY(zc_nvlist_dst_size);
565 FIELD_COPY(zc_nvlist_dst_filled);
567 FIELD_COPY(zc_history);
569 FIELD_COPY(zc_nvlist_conf);
570 FIELD_COPY(zc_nvlist_conf_size);
571 FIELD_COPY(zc_cookie);
572 FIELD_COPY(zc_objset_type);
573 FIELD_COPY(zc_perm_action);
574 FIELD_COPY(zc_history_len);
575 FIELD_COPY(zc_history_offset);
577 FIELD_COPY(zc_iflags);
578 FIELD_COPY(zc_share);
579 FIELD_COPY(zc_jailid);
580 FIELD_COPY(zc_objset_stats);
581 zcmd_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
582 FIELD_COPY(zc_inject_record.zi_objset);
583 FIELD_COPY(zc_inject_record.zi_object);
584 FIELD_COPY(zc_inject_record.zi_start);
585 FIELD_COPY(zc_inject_record.zi_end);
586 FIELD_COPY(zc_inject_record.zi_guid);
587 FIELD_COPY(zc_inject_record.zi_level);
588 FIELD_COPY(zc_inject_record.zi_error);
589 FIELD_COPY(zc_inject_record.zi_type);
590 FIELD_COPY(zc_inject_record.zi_freq);
591 FIELD_COPY(zc_inject_record.zi_failfast);
592 strlcpy(resume_c->zc_inject_record.zi_func,
593 zc->zc_inject_record.zi_func, MAXNAMELEN);
594 FIELD_COPY(zc_inject_record.zi_iotype);
595 FIELD_COPY(zc_inject_record.zi_duration);
596 FIELD_COPY(zc_inject_record.zi_timer);
597 FIELD_COPY(zc_inject_record.zi_cmd);
598 FIELD_COPY(zc_inject_record.zi_pad);
600 /* boolean_t -> uint32_t */
601 zcmd_c->zc_defer_destroy = (uint32_t)(zc->zc_defer_destroy);
602 zcmd_c->zc_temphold = 0;
604 FIELD_COPY(zc_action_handle);
605 FIELD_COPY(zc_cleanup_fd);
606 FIELD_COPY(zc_simple);
607 FIELD_COPY(zc_sendobj);
608 FIELD_COPY(zc_fromobj);
609 FIELD_COPY(zc_createtxg);
615 case ZFS_CMD_COMPAT_DEADMAN:
616 zcdm_c = (void *)addr;
618 strlcpy(zcdm_c->zc_name, zc->zc_name, MAXPATHLEN);
619 strlcpy(zcdm_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
620 strlcpy(zcdm_c->zc_string, zc->zc_string, MAXPATHLEN);
622 #define FIELD_COPY(field) zcdm_c->field = zc->field
623 zcdm_c->zc_guid = zc->zc_guid;
624 zcdm_c->zc_nvlist_conf = zc->zc_nvlist_conf;
625 zcdm_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
626 zcdm_c->zc_nvlist_src = zc->zc_nvlist_src;
627 zcdm_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
628 zcdm_c->zc_nvlist_dst = zc->zc_nvlist_dst;
629 zcdm_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
630 zcdm_c->zc_cookie = zc->zc_cookie;
631 zcdm_c->zc_objset_type = zc->zc_objset_type;
632 zcdm_c->zc_perm_action = zc->zc_perm_action;
633 zcdm_c->zc_history = zc->zc_history;
634 zcdm_c->zc_history_len = zc->zc_history_len;
635 zcdm_c->zc_history_offset = zc->zc_history_offset;
636 zcdm_c->zc_obj = zc->zc_obj;
637 zcdm_c->zc_iflags = zc->zc_iflags;
638 zcdm_c->zc_share = zc->zc_share;
639 zcdm_c->zc_jailid = zc->zc_jailid;
640 zcdm_c->zc_objset_stats = zc->zc_objset_stats;
641 zcdm_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
642 zcdm_c->zc_defer_destroy = zc->zc_defer_destroy;
643 zcdm_c->zc_temphold = 0;
644 zcdm_c->zc_action_handle = zc->zc_action_handle;
645 zcdm_c->zc_cleanup_fd = zc->zc_cleanup_fd;
646 zcdm_c->zc_simple = zc->zc_simple;
647 zcdm_c->zc_sendobj = zc->zc_sendobj;
648 zcdm_c->zc_fromobj = zc->zc_fromobj;
649 zcdm_c->zc_createtxg = zc->zc_createtxg;
650 zcdm_c->zc_stat = zc->zc_stat;
651 FIELD_COPY(zc_inject_record.zi_objset);
652 FIELD_COPY(zc_inject_record.zi_object);
653 FIELD_COPY(zc_inject_record.zi_start);
654 FIELD_COPY(zc_inject_record.zi_end);
655 FIELD_COPY(zc_inject_record.zi_guid);
656 FIELD_COPY(zc_inject_record.zi_level);
657 FIELD_COPY(zc_inject_record.zi_error);
658 FIELD_COPY(zc_inject_record.zi_type);
659 FIELD_COPY(zc_inject_record.zi_freq);
660 FIELD_COPY(zc_inject_record.zi_failfast);
661 strlcpy(resume_c->zc_inject_record.zi_func,
662 zc->zc_inject_record.zi_func, MAXNAMELEN);
663 FIELD_COPY(zc_inject_record.zi_iotype);
664 FIELD_COPY(zc_inject_record.zi_duration);
665 FIELD_COPY(zc_inject_record.zi_timer);
666 FIELD_COPY(zc_inject_record.zi_cmd);
667 FIELD_COPY(zc_inject_record.zi_pad);
670 if (request == ZFS_IOC_RECV)
671 strlcpy(zcdm_c->zc_top_ds,
672 zc->zc_value + strlen(zc->zc_value) + 1,
673 (MAXPATHLEN * 2) - strlen(zc->zc_value) - 1);
677 case ZFS_CMD_COMPAT_V28:
678 zc28_c = (void *)addr;
680 strlcpy(zc28_c->zc_name, zc->zc_name, MAXPATHLEN);
681 strlcpy(zc28_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
682 strlcpy(zc28_c->zc_string, zc->zc_string, MAXPATHLEN);
683 zc28_c->zc_guid = zc->zc_guid;
684 zc28_c->zc_nvlist_conf = zc->zc_nvlist_conf;
685 zc28_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
686 zc28_c->zc_nvlist_src = zc->zc_nvlist_src;
687 zc28_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
688 zc28_c->zc_nvlist_dst = zc->zc_nvlist_dst;
689 zc28_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
690 zc28_c->zc_cookie = zc->zc_cookie;
691 zc28_c->zc_objset_type = zc->zc_objset_type;
692 zc28_c->zc_perm_action = zc->zc_perm_action;
693 zc28_c->zc_history = zc->zc_history;
694 zc28_c->zc_history_len = zc->zc_history_len;
695 zc28_c->zc_history_offset = zc->zc_history_offset;
696 zc28_c->zc_obj = zc->zc_obj;
697 zc28_c->zc_iflags = zc->zc_iflags;
698 zc28_c->zc_share = zc->zc_share;
699 zc28_c->zc_jailid = zc->zc_jailid;
700 zc28_c->zc_objset_stats = zc->zc_objset_stats;
701 zc28_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
702 zc28_c->zc_defer_destroy = zc->zc_defer_destroy;
703 zc28_c->zc_temphold = 0;
704 zc28_c->zc_action_handle = zc->zc_action_handle;
705 zc28_c->zc_cleanup_fd = zc->zc_cleanup_fd;
706 zc28_c->zc_simple = zc->zc_simple;
707 zc28_c->zc_sendobj = zc->zc_sendobj;
708 zc28_c->zc_fromobj = zc->zc_fromobj;
709 zc28_c->zc_createtxg = zc->zc_createtxg;
710 zc28_c->zc_stat = zc->zc_stat;
712 if (request == ZFS_IOC_RECV)
713 strlcpy(zc28_c->zc_top_ds,
714 zc->zc_value + strlen(zc->zc_value) + 1,
715 MAXPATHLEN * 2 - strlen(zc->zc_value) - 1);
717 /* zc_inject_record */
718 zc28_c->zc_inject_record.zi_objset =
719 zc->zc_inject_record.zi_objset;
720 zc28_c->zc_inject_record.zi_object =
721 zc->zc_inject_record.zi_object;
722 zc28_c->zc_inject_record.zi_start =
723 zc->zc_inject_record.zi_start;
724 zc28_c->zc_inject_record.zi_end =
725 zc->zc_inject_record.zi_end;
726 zc28_c->zc_inject_record.zi_guid =
727 zc->zc_inject_record.zi_guid;
728 zc28_c->zc_inject_record.zi_level =
729 zc->zc_inject_record.zi_level;
730 zc28_c->zc_inject_record.zi_error =
731 zc->zc_inject_record.zi_error;
732 zc28_c->zc_inject_record.zi_type =
733 zc->zc_inject_record.zi_type;
734 zc28_c->zc_inject_record.zi_freq =
735 zc->zc_inject_record.zi_freq;
736 zc28_c->zc_inject_record.zi_failfast =
737 zc->zc_inject_record.zi_failfast;
738 strlcpy(zc28_c->zc_inject_record.zi_func,
739 zc->zc_inject_record.zi_func, MAXNAMELEN);
740 zc28_c->zc_inject_record.zi_iotype =
741 zc->zc_inject_record.zi_iotype;
742 zc28_c->zc_inject_record.zi_duration =
743 zc->zc_inject_record.zi_duration;
744 zc28_c->zc_inject_record.zi_timer =
745 zc->zc_inject_record.zi_timer;
748 case ZFS_CMD_COMPAT_V15:
752 strlcpy(zc_c->zc_name, zc->zc_name, MAXPATHLEN);
753 strlcpy(zc_c->zc_value, zc->zc_value, MAXPATHLEN);
754 strlcpy(zc_c->zc_string, zc->zc_string, MAXPATHLEN);
755 zc_c->zc_guid = zc->zc_guid;
756 zc_c->zc_nvlist_conf = zc->zc_nvlist_conf;
757 zc_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
758 zc_c->zc_nvlist_src = zc->zc_nvlist_src;
759 zc_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
760 zc_c->zc_nvlist_dst = zc->zc_nvlist_dst;
761 zc_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
762 zc_c->zc_cookie = zc->zc_cookie;
763 zc_c->zc_objset_type = zc->zc_objset_type;
764 zc_c->zc_perm_action = zc->zc_perm_action;
765 zc_c->zc_history = zc->zc_history;
766 zc_c->zc_history_len = zc->zc_history_len;
767 zc_c->zc_history_offset = zc->zc_history_offset;
768 zc_c->zc_obj = zc->zc_obj;
769 zc_c->zc_share = zc->zc_share;
770 zc_c->zc_jailid = zc->zc_jailid;
771 zc_c->zc_objset_stats = zc->zc_objset_stats;
772 zc_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
774 /* zc_inject_record */
775 zc_c->zc_inject_record.zi_objset =
776 zc->zc_inject_record.zi_objset;
777 zc_c->zc_inject_record.zi_object =
778 zc->zc_inject_record.zi_object;
779 zc_c->zc_inject_record.zi_start =
780 zc->zc_inject_record.zi_start;
781 zc_c->zc_inject_record.zi_end =
782 zc->zc_inject_record.zi_end;
783 zc_c->zc_inject_record.zi_guid =
784 zc->zc_inject_record.zi_guid;
785 zc_c->zc_inject_record.zi_level =
786 zc->zc_inject_record.zi_level;
787 zc_c->zc_inject_record.zi_error =
788 zc->zc_inject_record.zi_error;
789 zc_c->zc_inject_record.zi_type =
790 zc->zc_inject_record.zi_type;
791 zc_c->zc_inject_record.zi_freq =
792 zc->zc_inject_record.zi_freq;
793 zc_c->zc_inject_record.zi_failfast =
794 zc->zc_inject_record.zi_failfast;
801 zfs_ioctl_compat_get_nvlist(uint64_t nvl, size_t size, int iflag,
806 nvlist_t *list = NULL;
809 * Read in and unpack the user-supplied nvlist.
815 packed = kmem_alloc(size, KM_SLEEP);
816 if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
818 kmem_free(packed, size);
822 packed = (void *)(uintptr_t)nvl;
825 error = nvlist_unpack(packed, size, &list, 0);
828 kmem_free(packed, size);
839 zfs_ioctl_compat_put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
845 VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0);
848 packed = kmem_alloc(size, KM_SLEEP);
849 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
852 if (ddi_copyout(packed,
853 (void *)(uintptr_t)zc->zc_nvlist_dst, size, zc->zc_iflags) != 0)
855 kmem_free(packed, size);
857 packed = (void *)(uintptr_t)zc->zc_nvlist_dst;
858 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
862 zc->zc_nvlist_dst_size = size;
867 zfs_ioctl_compat_fix_stats_nvlist(nvlist_t *nvl)
870 nvlist_t *nvroot = NULL;
872 uint_t c, children, nelem;
874 if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN,
875 &child, &children) == 0) {
876 for (c = 0; c < children; c++) {
877 zfs_ioctl_compat_fix_stats_nvlist(child[c]);
881 if (nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_VDEV_TREE,
883 zfs_ioctl_compat_fix_stats_nvlist(nvroot);
885 if ((nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_VDEV_STATS,
887 if ((nvlist_lookup_uint64_array(nvl, "stats",
890 (uint64_t **)&vs, &nelem) == 0)) {
891 nvlist_add_uint64_array(nvl,
895 ZPOOL_CONFIG_VDEV_STATS,
897 (uint64_t *)vs, nelem);
899 nvlist_remove(nvl, ZPOOL_CONFIG_VDEV_STATS,
901 nvlist_remove(nvl, "stats",
903 DATA_TYPE_UINT64_ARRAY);
908 zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int nc)
910 nvlist_t *nv, *nvp = NULL;
914 if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
915 zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
918 if (nc == 5) { /* ZFS_IOC_POOL_STATS */
920 while ((elem = nvlist_next_nvpair(nv, elem)) != NULL) {
921 if (nvpair_value_nvlist(elem, &nvp) == 0)
922 zfs_ioctl_compat_fix_stats_nvlist(nvp);
926 zfs_ioctl_compat_fix_stats_nvlist(nv);
928 error = zfs_ioctl_compat_put_nvlist(zc, nv);
936 zfs_ioctl_compat_pool_get_props(zfs_cmd_t *zc)
938 nvlist_t *nv, *nva = NULL;
941 if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
942 zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
946 if (nvlist_lookup_nvlist(nv, "allocated", &nva) == 0) {
947 nvlist_add_nvlist(nv, "used", nva);
948 nvlist_remove(nv, "allocated", DATA_TYPE_NVLIST);
951 if (nvlist_lookup_nvlist(nv, "free", &nva) == 0) {
952 nvlist_add_nvlist(nv, "available", nva);
953 nvlist_remove(nv, "free", DATA_TYPE_NVLIST);
956 if (nvlist_lookup_nvlist(nv, "used", &nva) == 0) {
957 nvlist_add_nvlist(nv, "allocated", nva);
958 nvlist_remove(nv, "used", DATA_TYPE_NVLIST);
961 if (nvlist_lookup_nvlist(nv, "available", &nva) == 0) {
962 nvlist_add_nvlist(nv, "free", nva);
963 nvlist_remove(nv, "available", DATA_TYPE_NVLIST);
967 error = zfs_ioctl_compat_put_nvlist(zc, nv);
976 zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
984 case ZFS_CMD_COMPAT_NONE:
985 ncmd = _IOWR('Z', request, struct zfs_iocparm);
986 zp.zfs_cmd = (uint64_t)zc;
987 zp.zfs_cmd_size = sizeof(zfs_cmd_t);
988 zp.zfs_ioctl_version = ZFS_IOCVER_CURRENT;
989 return (ioctl(fd, ncmd, &zp));
990 case ZFS_CMD_COMPAT_RESUME:
991 ncmd = _IOWR('Z', request, struct zfs_iocparm);
992 zp.zfs_cmd = (uint64_t)zc;
993 zp.zfs_cmd_size = sizeof(zfs_cmd_resume_t);
994 zp.zfs_ioctl_version = ZFS_IOCVER_RESUME;
995 return (ioctl(fd, ncmd, &zp));
996 case ZFS_CMD_COMPAT_EDBP:
997 ncmd = _IOWR('Z', request, struct zfs_iocparm);
998 zp.zfs_cmd = (uint64_t)zc;
999 zp.zfs_cmd_size = sizeof(zfs_cmd_edbp_t);
1000 zp.zfs_ioctl_version = ZFS_IOCVER_EDBP;
1001 return (ioctl(fd, ncmd, &zp));
1002 case ZFS_CMD_COMPAT_ZCMD:
1003 ncmd = _IOWR('Z', request, struct zfs_iocparm);
1004 zp.zfs_cmd = (uint64_t)zc;
1005 zp.zfs_cmd_size = sizeof(zfs_cmd_zcmd_t);
1006 zp.zfs_ioctl_version = ZFS_IOCVER_ZCMD;
1007 return (ioctl(fd, ncmd, &zp));
1008 case ZFS_CMD_COMPAT_LZC:
1009 ncmd = _IOWR('Z', request, struct zfs_cmd);
1010 return (ioctl(fd, ncmd, zc));
1011 case ZFS_CMD_COMPAT_DEADMAN:
1012 zc_c = malloc(sizeof(zfs_cmd_deadman_t));
1013 ncmd = _IOWR('Z', request, struct zfs_cmd_deadman);
1015 case ZFS_CMD_COMPAT_V28:
1016 zc_c = malloc(sizeof(zfs_cmd_v28_t));
1017 ncmd = _IOWR('Z', request, struct zfs_cmd_v28);
1019 case ZFS_CMD_COMPAT_V15:
1020 nc = zfs_ioctl_v28_to_v15[request];
1021 zc_c = malloc(sizeof(zfs_cmd_v15_t));
1022 ncmd = _IOWR('Z', nc, struct zfs_cmd_v15);
1028 if (ZFS_IOCREQ(ncmd) == ZFS_IOC_COMPAT_FAIL)
1031 zfs_cmd_compat_put(zc, (caddr_t)zc_c, request, cflag);
1033 ret = ioctl(fd, ncmd, zc_c);
1034 if (cflag == ZFS_CMD_COMPAT_V15 &&
1035 nc == ZFS_IOC_POOL_IMPORT)
1036 ret = ioctl(fd, _IOWR('Z', ZFS_IOC_POOL_CONFIGS,
1037 struct zfs_cmd_v15), zc_c);
1038 zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag);
1041 if (cflag == ZFS_CMD_COMPAT_V15) {
1043 case ZFS_IOC_POOL_IMPORT:
1044 case ZFS_IOC_POOL_CONFIGS:
1045 case ZFS_IOC_POOL_STATS:
1046 case ZFS_IOC_POOL_TRYIMPORT:
1047 zfs_ioctl_compat_fix_stats(zc, nc);
1049 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
1050 zfs_ioctl_compat_pool_get_props(zc);
1059 zfs_ioctl_compat_pre(zfs_cmd_t *zc, int *vec, const int cflag)
1063 /* are we creating a clone? */
1064 if (*vec == ZFS_IOC_CREATE && zc->zc_value[0] != '\0')
1065 *vec = ZFS_IOC_CLONE;
1067 if (cflag == ZFS_CMD_COMPAT_V15) {
1070 case 7: /* ZFS_IOC_POOL_SCRUB (v15) */
1071 zc->zc_cookie = POOL_SCAN_SCRUB;
1080 zfs_ioctl_compat_post(zfs_cmd_t *zc, int vec, const int cflag)
1082 if (cflag == ZFS_CMD_COMPAT_V15) {
1084 case ZFS_IOC_POOL_CONFIGS:
1085 case ZFS_IOC_POOL_STATS:
1086 case ZFS_IOC_POOL_TRYIMPORT:
1087 zfs_ioctl_compat_fix_stats(zc, vec);
1089 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
1090 zfs_ioctl_compat_pool_get_props(zc);
1097 zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec,
1100 nvlist_t *nvl, *tmpnvl, *hnvl;
1102 char *poolname, *snapname;
1105 if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC ||
1106 cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP ||
1107 cflag == ZFS_CMD_COMPAT_RESUME)
1111 case ZFS_IOC_CREATE:
1112 nvl = fnvlist_alloc();
1113 fnvlist_add_int32(nvl, "type", zc->zc_objset_type);
1114 if (innvl != NULL) {
1115 fnvlist_add_nvlist(nvl, "props", innvl);
1121 nvl = fnvlist_alloc();
1122 fnvlist_add_string(nvl, "origin", zc->zc_value);
1123 if (innvl != NULL) {
1124 fnvlist_add_nvlist(nvl, "props", innvl);
1129 case ZFS_IOC_SNAPSHOT:
1132 nvl = fnvlist_alloc();
1133 fnvlist_add_nvlist(nvl, "props", innvl);
1134 tmpnvl = fnvlist_alloc();
1135 snapname = kmem_asprintf("%s@%s", zc->zc_name, zc->zc_value);
1136 fnvlist_add_boolean(tmpnvl, snapname);
1137 kmem_free(snapname, strlen(snapname + 1));
1138 /* check if we are doing a recursive snapshot */
1140 dmu_get_recursive_snaps_nvl(zc->zc_name, zc->zc_value,
1142 fnvlist_add_nvlist(nvl, "snaps", tmpnvl);
1143 fnvlist_free(tmpnvl);
1145 /* strip dataset part from zc->zc_name */
1146 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1149 case ZFS_IOC_SPACE_SNAPS:
1150 nvl = fnvlist_alloc();
1151 fnvlist_add_string(nvl, "firstsnap", zc->zc_value);
1156 case ZFS_IOC_DESTROY_SNAPS:
1157 if (innvl == NULL && cflag == ZFS_CMD_COMPAT_DEADMAN)
1159 nvl = fnvlist_alloc();
1160 if (innvl != NULL) {
1161 fnvlist_add_nvlist(nvl, "snaps", innvl);
1164 * We are probably called by even older binaries,
1165 * allocate and populate nvlist with recursive
1168 if (zfs_component_namecheck(zc->zc_value, NULL,
1170 tmpnvl = fnvlist_alloc();
1171 if (dmu_get_recursive_snaps_nvl(zc->zc_name,
1172 zc->zc_value, tmpnvl) == 0)
1173 fnvlist_add_nvlist(nvl, "snaps",
1175 nvlist_free(tmpnvl);
1180 /* strip dataset part from zc->zc_name */
1181 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1185 nvl = fnvlist_alloc();
1186 tmpnvl = fnvlist_alloc();
1187 if (zc->zc_cleanup_fd != -1)
1188 fnvlist_add_int32(nvl, "cleanup_fd",
1189 (int32_t)zc->zc_cleanup_fd);
1190 if (zc->zc_cookie) {
1191 hnvl = fnvlist_alloc();
1192 if (dmu_get_recursive_snaps_nvl(zc->zc_name,
1193 zc->zc_value, hnvl) == 0) {
1195 while ((elem = nvlist_next_nvpair(hnvl,
1197 nvlist_add_string(tmpnvl,
1198 nvpair_name(elem), zc->zc_string);
1203 snapname = kmem_asprintf("%s@%s", zc->zc_name,
1205 nvlist_add_string(tmpnvl, snapname, zc->zc_string);
1206 kmem_free(snapname, strlen(snapname + 1));
1208 fnvlist_add_nvlist(nvl, "holds", tmpnvl);
1209 nvlist_free(tmpnvl);
1212 /* strip dataset part from zc->zc_name */
1213 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1216 case ZFS_IOC_RELEASE:
1217 nvl = fnvlist_alloc();
1218 tmpnvl = fnvlist_alloc();
1219 if (zc->zc_cookie) {
1220 hnvl = fnvlist_alloc();
1221 if (dmu_get_recursive_snaps_nvl(zc->zc_name,
1222 zc->zc_value, hnvl) == 0) {
1224 while ((elem = nvlist_next_nvpair(hnvl,
1226 fnvlist_add_boolean(tmpnvl,
1228 fnvlist_add_nvlist(nvl,
1229 nvpair_name(elem), tmpnvl);
1234 snapname = kmem_asprintf("%s@%s", zc->zc_name,
1236 fnvlist_add_boolean(tmpnvl, zc->zc_string);
1237 fnvlist_add_nvlist(nvl, snapname, tmpnvl);
1238 kmem_free(snapname, strlen(snapname + 1));
1240 nvlist_free(tmpnvl);
1243 /* strip dataset part from zc->zc_name */
1244 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1253 zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec,
1258 if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC ||
1259 cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP ||
1260 cflag == ZFS_CMD_COMPAT_RESUME)
1264 case ZFS_IOC_SPACE_SNAPS:
1265 (void) nvlist_lookup_uint64(outnvl, "used", &zc->zc_cookie);
1266 (void) nvlist_lookup_uint64(outnvl, "compressed",
1267 &zc->zc_objset_type);
1268 (void) nvlist_lookup_uint64(outnvl, "uncompressed",
1269 &zc->zc_perm_action);
1270 nvlist_free(outnvl);
1271 /* return empty outnvl */
1272 tmpnvl = fnvlist_alloc();
1275 case ZFS_IOC_CREATE:
1278 case ZFS_IOC_RELEASE:
1279 nvlist_free(outnvl);
1280 /* return empty outnvl */
1281 tmpnvl = fnvlist_alloc();