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;
58 zfs_cmd_inlanes_t *inlanes_c;
61 case ZFS_CMD_COMPAT_INLANES:
62 inlanes_c = (void *)addr;
64 strlcpy(zc->zc_name, inlanes_c->zc_name, MAXPATHLEN);
65 strlcpy(zc->zc_value, inlanes_c->zc_value, MAXPATHLEN * 2);
66 strlcpy(zc->zc_string, inlanes_c->zc_string, MAXPATHLEN);
68 #define FIELD_COPY(field) zc->field = inlanes_c->field
69 FIELD_COPY(zc_nvlist_src);
70 FIELD_COPY(zc_nvlist_src_size);
71 FIELD_COPY(zc_nvlist_dst);
72 FIELD_COPY(zc_nvlist_dst_size);
73 FIELD_COPY(zc_nvlist_dst_filled);
75 FIELD_COPY(zc_history);
77 FIELD_COPY(zc_nvlist_conf);
78 FIELD_COPY(zc_nvlist_conf_size);
79 FIELD_COPY(zc_cookie);
80 FIELD_COPY(zc_objset_type);
81 FIELD_COPY(zc_perm_action);
82 FIELD_COPY(zc_history_len);
83 FIELD_COPY(zc_history_offset);
85 FIELD_COPY(zc_iflags);
87 FIELD_COPY(zc_jailid);
88 FIELD_COPY(zc_objset_stats);
89 FIELD_COPY(zc_begin_record);
90 FIELD_COPY(zc_inject_record);
91 FIELD_COPY(zc_defer_destroy);
93 FIELD_COPY(zc_action_handle);
94 FIELD_COPY(zc_cleanup_fd);
95 FIELD_COPY(zc_simple);
96 FIELD_COPY(zc_resumable);
97 FIELD_COPY(zc_sendobj);
98 FIELD_COPY(zc_fromobj);
99 FIELD_COPY(zc_createtxg);
104 case ZFS_CMD_COMPAT_RESUME:
105 resume_c = (void *)addr;
107 strlcpy(zc->zc_name, resume_c->zc_name, MAXPATHLEN);
108 strlcpy(zc->zc_value, resume_c->zc_value, MAXPATHLEN * 2);
109 strlcpy(zc->zc_string, resume_c->zc_string, MAXPATHLEN);
111 #define FIELD_COPY(field) zc->field = resume_c->field
112 FIELD_COPY(zc_nvlist_src);
113 FIELD_COPY(zc_nvlist_src_size);
114 FIELD_COPY(zc_nvlist_dst);
115 FIELD_COPY(zc_nvlist_dst_size);
116 FIELD_COPY(zc_nvlist_dst_filled);
118 FIELD_COPY(zc_history);
120 FIELD_COPY(zc_nvlist_conf);
121 FIELD_COPY(zc_nvlist_conf_size);
122 FIELD_COPY(zc_cookie);
123 FIELD_COPY(zc_objset_type);
124 FIELD_COPY(zc_perm_action);
125 FIELD_COPY(zc_history_len);
126 FIELD_COPY(zc_history_offset);
128 FIELD_COPY(zc_iflags);
129 FIELD_COPY(zc_share);
130 FIELD_COPY(zc_jailid);
131 FIELD_COPY(zc_objset_stats);
132 FIELD_COPY(zc_begin_record);
133 FIELD_COPY(zc_inject_record.zi_objset);
134 FIELD_COPY(zc_inject_record.zi_object);
135 FIELD_COPY(zc_inject_record.zi_start);
136 FIELD_COPY(zc_inject_record.zi_end);
137 FIELD_COPY(zc_inject_record.zi_guid);
138 FIELD_COPY(zc_inject_record.zi_level);
139 FIELD_COPY(zc_inject_record.zi_error);
140 FIELD_COPY(zc_inject_record.zi_type);
141 FIELD_COPY(zc_inject_record.zi_freq);
142 FIELD_COPY(zc_inject_record.zi_failfast);
143 strlcpy(zc->zc_inject_record.zi_func,
144 resume_c->zc_inject_record.zi_func, MAXNAMELEN);
145 FIELD_COPY(zc_inject_record.zi_iotype);
146 FIELD_COPY(zc_inject_record.zi_duration);
147 FIELD_COPY(zc_inject_record.zi_timer);
148 zc->zc_inject_record.zi_nlanes = 1;
149 FIELD_COPY(zc_inject_record.zi_cmd);
150 FIELD_COPY(zc_inject_record.zi_pad);
151 FIELD_COPY(zc_defer_destroy);
152 FIELD_COPY(zc_flags);
153 FIELD_COPY(zc_action_handle);
154 FIELD_COPY(zc_cleanup_fd);
155 FIELD_COPY(zc_simple);
156 FIELD_COPY(zc_resumable);
157 FIELD_COPY(zc_sendobj);
158 FIELD_COPY(zc_fromobj);
159 FIELD_COPY(zc_createtxg);
164 case ZFS_CMD_COMPAT_EDBP:
165 edbp_c = (void *)addr;
167 strlcpy(zc->zc_name, edbp_c->zc_name, MAXPATHLEN);
168 strlcpy(zc->zc_value, edbp_c->zc_value, MAXPATHLEN * 2);
169 strlcpy(zc->zc_string, edbp_c->zc_string, MAXPATHLEN);
171 #define FIELD_COPY(field) zc->field = edbp_c->field
172 FIELD_COPY(zc_nvlist_src);
173 FIELD_COPY(zc_nvlist_src_size);
174 FIELD_COPY(zc_nvlist_dst);
175 FIELD_COPY(zc_nvlist_dst_size);
176 FIELD_COPY(zc_nvlist_dst_filled);
178 FIELD_COPY(zc_history);
180 FIELD_COPY(zc_nvlist_conf);
181 FIELD_COPY(zc_nvlist_conf_size);
182 FIELD_COPY(zc_cookie);
183 FIELD_COPY(zc_objset_type);
184 FIELD_COPY(zc_perm_action);
185 FIELD_COPY(zc_history_len);
186 FIELD_COPY(zc_history_offset);
188 FIELD_COPY(zc_iflags);
189 FIELD_COPY(zc_share);
190 FIELD_COPY(zc_jailid);
191 FIELD_COPY(zc_objset_stats);
192 zc->zc_begin_record.drr_u.drr_begin = edbp_c->zc_begin_record;
193 FIELD_COPY(zc_inject_record.zi_objset);
194 FIELD_COPY(zc_inject_record.zi_object);
195 FIELD_COPY(zc_inject_record.zi_start);
196 FIELD_COPY(zc_inject_record.zi_end);
197 FIELD_COPY(zc_inject_record.zi_guid);
198 FIELD_COPY(zc_inject_record.zi_level);
199 FIELD_COPY(zc_inject_record.zi_error);
200 FIELD_COPY(zc_inject_record.zi_type);
201 FIELD_COPY(zc_inject_record.zi_freq);
202 FIELD_COPY(zc_inject_record.zi_failfast);
203 strlcpy(zc->zc_inject_record.zi_func,
204 edbp_c->zc_inject_record.zi_func, MAXNAMELEN);
205 FIELD_COPY(zc_inject_record.zi_iotype);
206 FIELD_COPY(zc_inject_record.zi_duration);
207 FIELD_COPY(zc_inject_record.zi_timer);
208 zc->zc_inject_record.zi_nlanes = 1;
209 FIELD_COPY(zc_inject_record.zi_cmd);
210 FIELD_COPY(zc_inject_record.zi_pad);
211 FIELD_COPY(zc_defer_destroy);
212 FIELD_COPY(zc_flags);
213 FIELD_COPY(zc_action_handle);
214 FIELD_COPY(zc_cleanup_fd);
215 FIELD_COPY(zc_simple);
216 zc->zc_resumable = B_FALSE;
217 FIELD_COPY(zc_sendobj);
218 FIELD_COPY(zc_fromobj);
219 FIELD_COPY(zc_createtxg);
224 case ZFS_CMD_COMPAT_ZCMD:
225 zcmd_c = (void *)addr;
227 strlcpy(zc->zc_name, zcmd_c->zc_name, MAXPATHLEN);
228 strlcpy(zc->zc_value, zcmd_c->zc_value, MAXPATHLEN * 2);
229 strlcpy(zc->zc_string, zcmd_c->zc_string, MAXPATHLEN);
231 #define FIELD_COPY(field) zc->field = zcmd_c->field
232 FIELD_COPY(zc_nvlist_src);
233 FIELD_COPY(zc_nvlist_src_size);
234 FIELD_COPY(zc_nvlist_dst);
235 FIELD_COPY(zc_nvlist_dst_size);
236 FIELD_COPY(zc_nvlist_dst_filled);
238 FIELD_COPY(zc_history);
240 FIELD_COPY(zc_nvlist_conf);
241 FIELD_COPY(zc_nvlist_conf_size);
242 FIELD_COPY(zc_cookie);
243 FIELD_COPY(zc_objset_type);
244 FIELD_COPY(zc_perm_action);
245 FIELD_COPY(zc_history_len);
246 FIELD_COPY(zc_history_offset);
248 FIELD_COPY(zc_iflags);
249 FIELD_COPY(zc_share);
250 FIELD_COPY(zc_jailid);
251 FIELD_COPY(zc_objset_stats);
252 zc->zc_begin_record.drr_u.drr_begin = zcmd_c->zc_begin_record;
253 FIELD_COPY(zc_inject_record.zi_objset);
254 FIELD_COPY(zc_inject_record.zi_object);
255 FIELD_COPY(zc_inject_record.zi_start);
256 FIELD_COPY(zc_inject_record.zi_end);
257 FIELD_COPY(zc_inject_record.zi_guid);
258 FIELD_COPY(zc_inject_record.zi_level);
259 FIELD_COPY(zc_inject_record.zi_error);
260 FIELD_COPY(zc_inject_record.zi_type);
261 FIELD_COPY(zc_inject_record.zi_freq);
262 FIELD_COPY(zc_inject_record.zi_failfast);
263 strlcpy(zc->zc_inject_record.zi_func,
264 zcmd_c->zc_inject_record.zi_func, MAXNAMELEN);
265 FIELD_COPY(zc_inject_record.zi_iotype);
266 FIELD_COPY(zc_inject_record.zi_duration);
267 FIELD_COPY(zc_inject_record.zi_timer);
268 zc->zc_inject_record.zi_nlanes = 1;
269 FIELD_COPY(zc_inject_record.zi_cmd);
270 FIELD_COPY(zc_inject_record.zi_pad);
272 /* boolean_t -> uint32_t */
273 zc->zc_defer_destroy = (uint32_t)(zcmd_c->zc_defer_destroy);
276 FIELD_COPY(zc_action_handle);
277 FIELD_COPY(zc_cleanup_fd);
278 FIELD_COPY(zc_simple);
279 zc->zc_resumable = B_FALSE;
280 FIELD_COPY(zc_sendobj);
281 FIELD_COPY(zc_fromobj);
282 FIELD_COPY(zc_createtxg);
288 case ZFS_CMD_COMPAT_DEADMAN:
289 zcdm_c = (void *)addr;
291 strlcpy(zc->zc_name, zcdm_c->zc_name, MAXPATHLEN);
292 strlcpy(zc->zc_value, zcdm_c->zc_value, MAXPATHLEN * 2);
293 strlcpy(zc->zc_string, zcdm_c->zc_string, MAXPATHLEN);
295 #define FIELD_COPY(field) zc->field = zcdm_c->field
296 zc->zc_guid = zcdm_c->zc_guid;
297 zc->zc_nvlist_conf = zcdm_c->zc_nvlist_conf;
298 zc->zc_nvlist_conf_size = zcdm_c->zc_nvlist_conf_size;
299 zc->zc_nvlist_src = zcdm_c->zc_nvlist_src;
300 zc->zc_nvlist_src_size = zcdm_c->zc_nvlist_src_size;
301 zc->zc_nvlist_dst = zcdm_c->zc_nvlist_dst;
302 zc->zc_nvlist_dst_size = zcdm_c->zc_nvlist_dst_size;
303 zc->zc_cookie = zcdm_c->zc_cookie;
304 zc->zc_objset_type = zcdm_c->zc_objset_type;
305 zc->zc_perm_action = zcdm_c->zc_perm_action;
306 zc->zc_history = zcdm_c->zc_history;
307 zc->zc_history_len = zcdm_c->zc_history_len;
308 zc->zc_history_offset = zcdm_c->zc_history_offset;
309 zc->zc_obj = zcdm_c->zc_obj;
310 zc->zc_iflags = zcdm_c->zc_iflags;
311 zc->zc_share = zcdm_c->zc_share;
312 zc->zc_jailid = zcdm_c->zc_jailid;
313 zc->zc_objset_stats = zcdm_c->zc_objset_stats;
314 zc->zc_begin_record.drr_u.drr_begin = zcdm_c->zc_begin_record;
315 zc->zc_defer_destroy = zcdm_c->zc_defer_destroy;
316 (void)zcdm_c->zc_temphold;
317 zc->zc_action_handle = zcdm_c->zc_action_handle;
318 zc->zc_cleanup_fd = zcdm_c->zc_cleanup_fd;
319 zc->zc_simple = zcdm_c->zc_simple;
320 zc->zc_resumable = B_FALSE;
321 zc->zc_sendobj = zcdm_c->zc_sendobj;
322 zc->zc_fromobj = zcdm_c->zc_fromobj;
323 zc->zc_createtxg = zcdm_c->zc_createtxg;
324 zc->zc_stat = zcdm_c->zc_stat;
325 FIELD_COPY(zc_inject_record.zi_objset);
326 FIELD_COPY(zc_inject_record.zi_object);
327 FIELD_COPY(zc_inject_record.zi_start);
328 FIELD_COPY(zc_inject_record.zi_end);
329 FIELD_COPY(zc_inject_record.zi_guid);
330 FIELD_COPY(zc_inject_record.zi_level);
331 FIELD_COPY(zc_inject_record.zi_error);
332 FIELD_COPY(zc_inject_record.zi_type);
333 FIELD_COPY(zc_inject_record.zi_freq);
334 FIELD_COPY(zc_inject_record.zi_failfast);
335 strlcpy(zc->zc_inject_record.zi_func,
336 resume_c->zc_inject_record.zi_func, MAXNAMELEN);
337 FIELD_COPY(zc_inject_record.zi_iotype);
338 FIELD_COPY(zc_inject_record.zi_duration);
339 FIELD_COPY(zc_inject_record.zi_timer);
340 zc->zc_inject_record.zi_nlanes = 1;
341 FIELD_COPY(zc_inject_record.zi_cmd);
342 FIELD_COPY(zc_inject_record.zi_pad);
344 /* we always assume zc_nvlist_dst_filled is true */
345 zc->zc_nvlist_dst_filled = B_TRUE;
349 case ZFS_CMD_COMPAT_V28:
350 zc28_c = (void *)addr;
353 strlcpy(zc->zc_name, zc28_c->zc_name, MAXPATHLEN);
354 strlcpy(zc->zc_value, zc28_c->zc_value, MAXPATHLEN * 2);
355 strlcpy(zc->zc_string, zc28_c->zc_string, MAXPATHLEN);
356 zc->zc_guid = zc28_c->zc_guid;
357 zc->zc_nvlist_conf = zc28_c->zc_nvlist_conf;
358 zc->zc_nvlist_conf_size = zc28_c->zc_nvlist_conf_size;
359 zc->zc_nvlist_src = zc28_c->zc_nvlist_src;
360 zc->zc_nvlist_src_size = zc28_c->zc_nvlist_src_size;
361 zc->zc_nvlist_dst = zc28_c->zc_nvlist_dst;
362 zc->zc_nvlist_dst_size = zc28_c->zc_nvlist_dst_size;
363 zc->zc_cookie = zc28_c->zc_cookie;
364 zc->zc_objset_type = zc28_c->zc_objset_type;
365 zc->zc_perm_action = zc28_c->zc_perm_action;
366 zc->zc_history = zc28_c->zc_history;
367 zc->zc_history_len = zc28_c->zc_history_len;
368 zc->zc_history_offset = zc28_c->zc_history_offset;
369 zc->zc_obj = zc28_c->zc_obj;
370 zc->zc_iflags = zc28_c->zc_iflags;
371 zc->zc_share = zc28_c->zc_share;
372 zc->zc_jailid = zc28_c->zc_jailid;
373 zc->zc_objset_stats = zc28_c->zc_objset_stats;
374 zc->zc_begin_record.drr_u.drr_begin = zc28_c->zc_begin_record;
375 zc->zc_defer_destroy = zc28_c->zc_defer_destroy;
376 (void)zc28_c->zc_temphold;
377 zc->zc_action_handle = zc28_c->zc_action_handle;
378 zc->zc_cleanup_fd = zc28_c->zc_cleanup_fd;
379 zc->zc_simple = zc28_c->zc_simple;
380 zc->zc_resumable = B_FALSE;
381 zc->zc_sendobj = zc28_c->zc_sendobj;
382 zc->zc_fromobj = zc28_c->zc_fromobj;
383 zc->zc_createtxg = zc28_c->zc_createtxg;
384 zc->zc_stat = zc28_c->zc_stat;
386 /* zc->zc_inject_record */
387 zc->zc_inject_record.zi_objset =
388 zc28_c->zc_inject_record.zi_objset;
389 zc->zc_inject_record.zi_object =
390 zc28_c->zc_inject_record.zi_object;
391 zc->zc_inject_record.zi_start =
392 zc28_c->zc_inject_record.zi_start;
393 zc->zc_inject_record.zi_end =
394 zc28_c->zc_inject_record.zi_end;
395 zc->zc_inject_record.zi_guid =
396 zc28_c->zc_inject_record.zi_guid;
397 zc->zc_inject_record.zi_level =
398 zc28_c->zc_inject_record.zi_level;
399 zc->zc_inject_record.zi_error =
400 zc28_c->zc_inject_record.zi_error;
401 zc->zc_inject_record.zi_type =
402 zc28_c->zc_inject_record.zi_type;
403 zc->zc_inject_record.zi_freq =
404 zc28_c->zc_inject_record.zi_freq;
405 zc->zc_inject_record.zi_failfast =
406 zc28_c->zc_inject_record.zi_failfast;
407 strlcpy(zc->zc_inject_record.zi_func,
408 zc28_c->zc_inject_record.zi_func, MAXNAMELEN);
409 zc->zc_inject_record.zi_iotype =
410 zc28_c->zc_inject_record.zi_iotype;
411 zc->zc_inject_record.zi_duration =
412 zc28_c->zc_inject_record.zi_duration;
413 zc->zc_inject_record.zi_timer =
414 zc28_c->zc_inject_record.zi_timer;
415 zc->zc_inject_record.zi_nlanes = 1;
416 zc->zc_inject_record.zi_cmd = ZINJECT_UNINITIALIZED;
417 zc->zc_inject_record.zi_pad = 0;
420 case ZFS_CMD_COMPAT_V15:
424 strlcpy(zc->zc_name, zc_c->zc_name, MAXPATHLEN);
425 strlcpy(zc->zc_value, zc_c->zc_value, MAXPATHLEN);
426 strlcpy(zc->zc_string, zc_c->zc_string, MAXPATHLEN);
427 zc->zc_guid = zc_c->zc_guid;
428 zc->zc_nvlist_conf = zc_c->zc_nvlist_conf;
429 zc->zc_nvlist_conf_size = zc_c->zc_nvlist_conf_size;
430 zc->zc_nvlist_src = zc_c->zc_nvlist_src;
431 zc->zc_nvlist_src_size = zc_c->zc_nvlist_src_size;
432 zc->zc_nvlist_dst = zc_c->zc_nvlist_dst;
433 zc->zc_nvlist_dst_size = zc_c->zc_nvlist_dst_size;
434 zc->zc_cookie = zc_c->zc_cookie;
435 zc->zc_objset_type = zc_c->zc_objset_type;
436 zc->zc_perm_action = zc_c->zc_perm_action;
437 zc->zc_history = zc_c->zc_history;
438 zc->zc_history_len = zc_c->zc_history_len;
439 zc->zc_history_offset = zc_c->zc_history_offset;
440 zc->zc_obj = zc_c->zc_obj;
441 zc->zc_share = zc_c->zc_share;
442 zc->zc_jailid = zc_c->zc_jailid;
443 zc->zc_objset_stats = zc_c->zc_objset_stats;
444 zc->zc_begin_record.drr_u.drr_begin = zc_c->zc_begin_record;
446 /* zc->zc_inject_record */
447 zc->zc_inject_record.zi_objset =
448 zc_c->zc_inject_record.zi_objset;
449 zc->zc_inject_record.zi_object =
450 zc_c->zc_inject_record.zi_object;
451 zc->zc_inject_record.zi_start =
452 zc_c->zc_inject_record.zi_start;
453 zc->zc_inject_record.zi_end =
454 zc_c->zc_inject_record.zi_end;
455 zc->zc_inject_record.zi_guid =
456 zc_c->zc_inject_record.zi_guid;
457 zc->zc_inject_record.zi_level =
458 zc_c->zc_inject_record.zi_level;
459 zc->zc_inject_record.zi_error =
460 zc_c->zc_inject_record.zi_error;
461 zc->zc_inject_record.zi_type =
462 zc_c->zc_inject_record.zi_type;
463 zc->zc_inject_record.zi_freq =
464 zc_c->zc_inject_record.zi_freq;
465 zc->zc_inject_record.zi_failfast =
466 zc_c->zc_inject_record.zi_failfast;
472 zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request,
476 zfs_cmd_v28_t *zc28_c;
477 zfs_cmd_deadman_t *zcdm_c;
478 zfs_cmd_zcmd_t *zcmd_c;
479 zfs_cmd_edbp_t *edbp_c;
480 zfs_cmd_resume_t *resume_c;
481 zfs_cmd_inlanes_t *inlanes_c;
484 case ZFS_CMD_COMPAT_INLANES:
485 inlanes_c = (void *)addr;
486 strlcpy(inlanes_c->zc_name, zc->zc_name, MAXPATHLEN);
487 strlcpy(inlanes_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
488 strlcpy(inlanes_c->zc_string, zc->zc_string, MAXPATHLEN);
490 #define FIELD_COPY(field) inlanes_c->field = zc->field
491 FIELD_COPY(zc_nvlist_src);
492 FIELD_COPY(zc_nvlist_src_size);
493 FIELD_COPY(zc_nvlist_dst);
494 FIELD_COPY(zc_nvlist_dst_size);
495 FIELD_COPY(zc_nvlist_dst_filled);
497 FIELD_COPY(zc_history);
499 FIELD_COPY(zc_nvlist_conf);
500 FIELD_COPY(zc_nvlist_conf_size);
501 FIELD_COPY(zc_cookie);
502 FIELD_COPY(zc_objset_type);
503 FIELD_COPY(zc_perm_action);
504 FIELD_COPY(zc_history_len);
505 FIELD_COPY(zc_history_offset);
507 FIELD_COPY(zc_iflags);
508 FIELD_COPY(zc_share);
509 FIELD_COPY(zc_jailid);
510 FIELD_COPY(zc_objset_stats);
511 FIELD_COPY(zc_begin_record);
512 FIELD_COPY(zc_inject_record);
513 FIELD_COPY(zc_defer_destroy);
514 FIELD_COPY(zc_flags);
515 FIELD_COPY(zc_action_handle);
516 FIELD_COPY(zc_cleanup_fd);
517 FIELD_COPY(zc_simple);
518 FIELD_COPY(zc_sendobj);
519 FIELD_COPY(zc_fromobj);
520 FIELD_COPY(zc_createtxg);
525 case ZFS_CMD_COMPAT_RESUME:
526 resume_c = (void *)addr;
527 strlcpy(resume_c->zc_name, zc->zc_name, MAXPATHLEN);
528 strlcpy(resume_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
529 strlcpy(resume_c->zc_string, zc->zc_string, MAXPATHLEN);
531 #define FIELD_COPY(field) resume_c->field = zc->field
532 FIELD_COPY(zc_nvlist_src);
533 FIELD_COPY(zc_nvlist_src_size);
534 FIELD_COPY(zc_nvlist_dst);
535 FIELD_COPY(zc_nvlist_dst_size);
536 FIELD_COPY(zc_nvlist_dst_filled);
538 FIELD_COPY(zc_history);
540 FIELD_COPY(zc_nvlist_conf);
541 FIELD_COPY(zc_nvlist_conf_size);
542 FIELD_COPY(zc_cookie);
543 FIELD_COPY(zc_objset_type);
544 FIELD_COPY(zc_perm_action);
545 FIELD_COPY(zc_history_len);
546 FIELD_COPY(zc_history_offset);
548 FIELD_COPY(zc_iflags);
549 FIELD_COPY(zc_share);
550 FIELD_COPY(zc_jailid);
551 FIELD_COPY(zc_objset_stats);
552 FIELD_COPY(zc_begin_record);
553 FIELD_COPY(zc_inject_record.zi_objset);
554 FIELD_COPY(zc_inject_record.zi_object);
555 FIELD_COPY(zc_inject_record.zi_start);
556 FIELD_COPY(zc_inject_record.zi_end);
557 FIELD_COPY(zc_inject_record.zi_guid);
558 FIELD_COPY(zc_inject_record.zi_level);
559 FIELD_COPY(zc_inject_record.zi_error);
560 FIELD_COPY(zc_inject_record.zi_type);
561 FIELD_COPY(zc_inject_record.zi_freq);
562 FIELD_COPY(zc_inject_record.zi_failfast);
563 strlcpy(resume_c->zc_inject_record.zi_func,
564 zc->zc_inject_record.zi_func, MAXNAMELEN);
565 FIELD_COPY(zc_inject_record.zi_iotype);
566 FIELD_COPY(zc_inject_record.zi_duration);
567 FIELD_COPY(zc_inject_record.zi_timer);
568 FIELD_COPY(zc_inject_record.zi_cmd);
569 FIELD_COPY(zc_inject_record.zi_pad);
570 FIELD_COPY(zc_defer_destroy);
571 FIELD_COPY(zc_flags);
572 FIELD_COPY(zc_action_handle);
573 FIELD_COPY(zc_cleanup_fd);
574 FIELD_COPY(zc_simple);
575 FIELD_COPY(zc_sendobj);
576 FIELD_COPY(zc_fromobj);
577 FIELD_COPY(zc_createtxg);
582 case ZFS_CMD_COMPAT_EDBP:
583 edbp_c = (void *)addr;
584 strlcpy(edbp_c->zc_name, zc->zc_name, MAXPATHLEN);
585 strlcpy(edbp_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
586 strlcpy(edbp_c->zc_string, zc->zc_string, MAXPATHLEN);
588 #define FIELD_COPY(field) edbp_c->field = zc->field
589 FIELD_COPY(zc_nvlist_src);
590 FIELD_COPY(zc_nvlist_src_size);
591 FIELD_COPY(zc_nvlist_dst);
592 FIELD_COPY(zc_nvlist_dst_size);
593 FIELD_COPY(zc_nvlist_dst_filled);
595 FIELD_COPY(zc_history);
597 FIELD_COPY(zc_nvlist_conf);
598 FIELD_COPY(zc_nvlist_conf_size);
599 FIELD_COPY(zc_cookie);
600 FIELD_COPY(zc_objset_type);
601 FIELD_COPY(zc_perm_action);
602 FIELD_COPY(zc_history_len);
603 FIELD_COPY(zc_history_offset);
605 FIELD_COPY(zc_iflags);
606 FIELD_COPY(zc_share);
607 FIELD_COPY(zc_jailid);
608 FIELD_COPY(zc_objset_stats);
609 edbp_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
610 FIELD_COPY(zc_inject_record.zi_objset);
611 FIELD_COPY(zc_inject_record.zi_object);
612 FIELD_COPY(zc_inject_record.zi_start);
613 FIELD_COPY(zc_inject_record.zi_end);
614 FIELD_COPY(zc_inject_record.zi_guid);
615 FIELD_COPY(zc_inject_record.zi_level);
616 FIELD_COPY(zc_inject_record.zi_error);
617 FIELD_COPY(zc_inject_record.zi_type);
618 FIELD_COPY(zc_inject_record.zi_freq);
619 FIELD_COPY(zc_inject_record.zi_failfast);
620 strlcpy(resume_c->zc_inject_record.zi_func,
621 zc->zc_inject_record.zi_func, MAXNAMELEN);
622 FIELD_COPY(zc_inject_record.zi_iotype);
623 FIELD_COPY(zc_inject_record.zi_duration);
624 FIELD_COPY(zc_inject_record.zi_timer);
625 FIELD_COPY(zc_inject_record.zi_cmd);
626 FIELD_COPY(zc_inject_record.zi_pad);
627 FIELD_COPY(zc_defer_destroy);
628 FIELD_COPY(zc_flags);
629 FIELD_COPY(zc_action_handle);
630 FIELD_COPY(zc_cleanup_fd);
631 FIELD_COPY(zc_simple);
632 FIELD_COPY(zc_sendobj);
633 FIELD_COPY(zc_fromobj);
634 FIELD_COPY(zc_createtxg);
639 case ZFS_CMD_COMPAT_ZCMD:
640 zcmd_c = (void *)addr;
642 strlcpy(zcmd_c->zc_name, zc->zc_name, MAXPATHLEN);
643 strlcpy(zcmd_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
644 strlcpy(zcmd_c->zc_string, zc->zc_string, MAXPATHLEN);
646 #define FIELD_COPY(field) zcmd_c->field = zc->field
647 FIELD_COPY(zc_nvlist_src);
648 FIELD_COPY(zc_nvlist_src_size);
649 FIELD_COPY(zc_nvlist_dst);
650 FIELD_COPY(zc_nvlist_dst_size);
651 FIELD_COPY(zc_nvlist_dst_filled);
653 FIELD_COPY(zc_history);
655 FIELD_COPY(zc_nvlist_conf);
656 FIELD_COPY(zc_nvlist_conf_size);
657 FIELD_COPY(zc_cookie);
658 FIELD_COPY(zc_objset_type);
659 FIELD_COPY(zc_perm_action);
660 FIELD_COPY(zc_history_len);
661 FIELD_COPY(zc_history_offset);
663 FIELD_COPY(zc_iflags);
664 FIELD_COPY(zc_share);
665 FIELD_COPY(zc_jailid);
666 FIELD_COPY(zc_objset_stats);
667 zcmd_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
668 FIELD_COPY(zc_inject_record.zi_objset);
669 FIELD_COPY(zc_inject_record.zi_object);
670 FIELD_COPY(zc_inject_record.zi_start);
671 FIELD_COPY(zc_inject_record.zi_end);
672 FIELD_COPY(zc_inject_record.zi_guid);
673 FIELD_COPY(zc_inject_record.zi_level);
674 FIELD_COPY(zc_inject_record.zi_error);
675 FIELD_COPY(zc_inject_record.zi_type);
676 FIELD_COPY(zc_inject_record.zi_freq);
677 FIELD_COPY(zc_inject_record.zi_failfast);
678 strlcpy(resume_c->zc_inject_record.zi_func,
679 zc->zc_inject_record.zi_func, MAXNAMELEN);
680 FIELD_COPY(zc_inject_record.zi_iotype);
681 FIELD_COPY(zc_inject_record.zi_duration);
682 FIELD_COPY(zc_inject_record.zi_timer);
683 FIELD_COPY(zc_inject_record.zi_cmd);
684 FIELD_COPY(zc_inject_record.zi_pad);
686 /* boolean_t -> uint32_t */
687 zcmd_c->zc_defer_destroy = (uint32_t)(zc->zc_defer_destroy);
688 zcmd_c->zc_temphold = 0;
690 FIELD_COPY(zc_action_handle);
691 FIELD_COPY(zc_cleanup_fd);
692 FIELD_COPY(zc_simple);
693 FIELD_COPY(zc_sendobj);
694 FIELD_COPY(zc_fromobj);
695 FIELD_COPY(zc_createtxg);
701 case ZFS_CMD_COMPAT_DEADMAN:
702 zcdm_c = (void *)addr;
704 strlcpy(zcdm_c->zc_name, zc->zc_name, MAXPATHLEN);
705 strlcpy(zcdm_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
706 strlcpy(zcdm_c->zc_string, zc->zc_string, MAXPATHLEN);
708 #define FIELD_COPY(field) zcdm_c->field = zc->field
709 zcdm_c->zc_guid = zc->zc_guid;
710 zcdm_c->zc_nvlist_conf = zc->zc_nvlist_conf;
711 zcdm_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
712 zcdm_c->zc_nvlist_src = zc->zc_nvlist_src;
713 zcdm_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
714 zcdm_c->zc_nvlist_dst = zc->zc_nvlist_dst;
715 zcdm_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
716 zcdm_c->zc_cookie = zc->zc_cookie;
717 zcdm_c->zc_objset_type = zc->zc_objset_type;
718 zcdm_c->zc_perm_action = zc->zc_perm_action;
719 zcdm_c->zc_history = zc->zc_history;
720 zcdm_c->zc_history_len = zc->zc_history_len;
721 zcdm_c->zc_history_offset = zc->zc_history_offset;
722 zcdm_c->zc_obj = zc->zc_obj;
723 zcdm_c->zc_iflags = zc->zc_iflags;
724 zcdm_c->zc_share = zc->zc_share;
725 zcdm_c->zc_jailid = zc->zc_jailid;
726 zcdm_c->zc_objset_stats = zc->zc_objset_stats;
727 zcdm_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
728 zcdm_c->zc_defer_destroy = zc->zc_defer_destroy;
729 zcdm_c->zc_temphold = 0;
730 zcdm_c->zc_action_handle = zc->zc_action_handle;
731 zcdm_c->zc_cleanup_fd = zc->zc_cleanup_fd;
732 zcdm_c->zc_simple = zc->zc_simple;
733 zcdm_c->zc_sendobj = zc->zc_sendobj;
734 zcdm_c->zc_fromobj = zc->zc_fromobj;
735 zcdm_c->zc_createtxg = zc->zc_createtxg;
736 zcdm_c->zc_stat = zc->zc_stat;
737 FIELD_COPY(zc_inject_record.zi_objset);
738 FIELD_COPY(zc_inject_record.zi_object);
739 FIELD_COPY(zc_inject_record.zi_start);
740 FIELD_COPY(zc_inject_record.zi_end);
741 FIELD_COPY(zc_inject_record.zi_guid);
742 FIELD_COPY(zc_inject_record.zi_level);
743 FIELD_COPY(zc_inject_record.zi_error);
744 FIELD_COPY(zc_inject_record.zi_type);
745 FIELD_COPY(zc_inject_record.zi_freq);
746 FIELD_COPY(zc_inject_record.zi_failfast);
747 strlcpy(resume_c->zc_inject_record.zi_func,
748 zc->zc_inject_record.zi_func, MAXNAMELEN);
749 FIELD_COPY(zc_inject_record.zi_iotype);
750 FIELD_COPY(zc_inject_record.zi_duration);
751 FIELD_COPY(zc_inject_record.zi_timer);
752 FIELD_COPY(zc_inject_record.zi_cmd);
753 FIELD_COPY(zc_inject_record.zi_pad);
756 if (request == ZFS_IOC_RECV)
757 strlcpy(zcdm_c->zc_top_ds,
758 zc->zc_value + strlen(zc->zc_value) + 1,
759 (MAXPATHLEN * 2) - strlen(zc->zc_value) - 1);
763 case ZFS_CMD_COMPAT_V28:
764 zc28_c = (void *)addr;
766 strlcpy(zc28_c->zc_name, zc->zc_name, MAXPATHLEN);
767 strlcpy(zc28_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
768 strlcpy(zc28_c->zc_string, zc->zc_string, MAXPATHLEN);
769 zc28_c->zc_guid = zc->zc_guid;
770 zc28_c->zc_nvlist_conf = zc->zc_nvlist_conf;
771 zc28_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
772 zc28_c->zc_nvlist_src = zc->zc_nvlist_src;
773 zc28_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
774 zc28_c->zc_nvlist_dst = zc->zc_nvlist_dst;
775 zc28_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
776 zc28_c->zc_cookie = zc->zc_cookie;
777 zc28_c->zc_objset_type = zc->zc_objset_type;
778 zc28_c->zc_perm_action = zc->zc_perm_action;
779 zc28_c->zc_history = zc->zc_history;
780 zc28_c->zc_history_len = zc->zc_history_len;
781 zc28_c->zc_history_offset = zc->zc_history_offset;
782 zc28_c->zc_obj = zc->zc_obj;
783 zc28_c->zc_iflags = zc->zc_iflags;
784 zc28_c->zc_share = zc->zc_share;
785 zc28_c->zc_jailid = zc->zc_jailid;
786 zc28_c->zc_objset_stats = zc->zc_objset_stats;
787 zc28_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
788 zc28_c->zc_defer_destroy = zc->zc_defer_destroy;
789 zc28_c->zc_temphold = 0;
790 zc28_c->zc_action_handle = zc->zc_action_handle;
791 zc28_c->zc_cleanup_fd = zc->zc_cleanup_fd;
792 zc28_c->zc_simple = zc->zc_simple;
793 zc28_c->zc_sendobj = zc->zc_sendobj;
794 zc28_c->zc_fromobj = zc->zc_fromobj;
795 zc28_c->zc_createtxg = zc->zc_createtxg;
796 zc28_c->zc_stat = zc->zc_stat;
798 if (request == ZFS_IOC_RECV)
799 strlcpy(zc28_c->zc_top_ds,
800 zc->zc_value + strlen(zc->zc_value) + 1,
801 MAXPATHLEN * 2 - strlen(zc->zc_value) - 1);
803 /* zc_inject_record */
804 zc28_c->zc_inject_record.zi_objset =
805 zc->zc_inject_record.zi_objset;
806 zc28_c->zc_inject_record.zi_object =
807 zc->zc_inject_record.zi_object;
808 zc28_c->zc_inject_record.zi_start =
809 zc->zc_inject_record.zi_start;
810 zc28_c->zc_inject_record.zi_end =
811 zc->zc_inject_record.zi_end;
812 zc28_c->zc_inject_record.zi_guid =
813 zc->zc_inject_record.zi_guid;
814 zc28_c->zc_inject_record.zi_level =
815 zc->zc_inject_record.zi_level;
816 zc28_c->zc_inject_record.zi_error =
817 zc->zc_inject_record.zi_error;
818 zc28_c->zc_inject_record.zi_type =
819 zc->zc_inject_record.zi_type;
820 zc28_c->zc_inject_record.zi_freq =
821 zc->zc_inject_record.zi_freq;
822 zc28_c->zc_inject_record.zi_failfast =
823 zc->zc_inject_record.zi_failfast;
824 strlcpy(zc28_c->zc_inject_record.zi_func,
825 zc->zc_inject_record.zi_func, MAXNAMELEN);
826 zc28_c->zc_inject_record.zi_iotype =
827 zc->zc_inject_record.zi_iotype;
828 zc28_c->zc_inject_record.zi_duration =
829 zc->zc_inject_record.zi_duration;
830 zc28_c->zc_inject_record.zi_timer =
831 zc->zc_inject_record.zi_timer;
834 case ZFS_CMD_COMPAT_V15:
838 strlcpy(zc_c->zc_name, zc->zc_name, MAXPATHLEN);
839 strlcpy(zc_c->zc_value, zc->zc_value, MAXPATHLEN);
840 strlcpy(zc_c->zc_string, zc->zc_string, MAXPATHLEN);
841 zc_c->zc_guid = zc->zc_guid;
842 zc_c->zc_nvlist_conf = zc->zc_nvlist_conf;
843 zc_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
844 zc_c->zc_nvlist_src = zc->zc_nvlist_src;
845 zc_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
846 zc_c->zc_nvlist_dst = zc->zc_nvlist_dst;
847 zc_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
848 zc_c->zc_cookie = zc->zc_cookie;
849 zc_c->zc_objset_type = zc->zc_objset_type;
850 zc_c->zc_perm_action = zc->zc_perm_action;
851 zc_c->zc_history = zc->zc_history;
852 zc_c->zc_history_len = zc->zc_history_len;
853 zc_c->zc_history_offset = zc->zc_history_offset;
854 zc_c->zc_obj = zc->zc_obj;
855 zc_c->zc_share = zc->zc_share;
856 zc_c->zc_jailid = zc->zc_jailid;
857 zc_c->zc_objset_stats = zc->zc_objset_stats;
858 zc_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
860 /* zc_inject_record */
861 zc_c->zc_inject_record.zi_objset =
862 zc->zc_inject_record.zi_objset;
863 zc_c->zc_inject_record.zi_object =
864 zc->zc_inject_record.zi_object;
865 zc_c->zc_inject_record.zi_start =
866 zc->zc_inject_record.zi_start;
867 zc_c->zc_inject_record.zi_end =
868 zc->zc_inject_record.zi_end;
869 zc_c->zc_inject_record.zi_guid =
870 zc->zc_inject_record.zi_guid;
871 zc_c->zc_inject_record.zi_level =
872 zc->zc_inject_record.zi_level;
873 zc_c->zc_inject_record.zi_error =
874 zc->zc_inject_record.zi_error;
875 zc_c->zc_inject_record.zi_type =
876 zc->zc_inject_record.zi_type;
877 zc_c->zc_inject_record.zi_freq =
878 zc->zc_inject_record.zi_freq;
879 zc_c->zc_inject_record.zi_failfast =
880 zc->zc_inject_record.zi_failfast;
887 zfs_ioctl_compat_get_nvlist(uint64_t nvl, size_t size, int iflag,
892 nvlist_t *list = NULL;
895 * Read in and unpack the user-supplied nvlist.
901 packed = kmem_alloc(size, KM_SLEEP);
902 if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
904 kmem_free(packed, size);
908 packed = (void *)(uintptr_t)nvl;
911 error = nvlist_unpack(packed, size, &list, 0);
914 kmem_free(packed, size);
925 zfs_ioctl_compat_put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
931 VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0);
934 packed = kmem_alloc(size, KM_SLEEP);
935 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
938 if (ddi_copyout(packed,
939 (void *)(uintptr_t)zc->zc_nvlist_dst, size, zc->zc_iflags) != 0)
941 kmem_free(packed, size);
943 packed = (void *)(uintptr_t)zc->zc_nvlist_dst;
944 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
948 zc->zc_nvlist_dst_size = size;
953 zfs_ioctl_compat_fix_stats_nvlist(nvlist_t *nvl)
956 nvlist_t *nvroot = NULL;
958 uint_t c, children, nelem;
960 if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN,
961 &child, &children) == 0) {
962 for (c = 0; c < children; c++) {
963 zfs_ioctl_compat_fix_stats_nvlist(child[c]);
967 if (nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_VDEV_TREE,
969 zfs_ioctl_compat_fix_stats_nvlist(nvroot);
971 if ((nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_VDEV_STATS,
973 if ((nvlist_lookup_uint64_array(nvl, "stats",
976 (uint64_t **)&vs, &nelem) == 0)) {
977 nvlist_add_uint64_array(nvl,
981 ZPOOL_CONFIG_VDEV_STATS,
983 (uint64_t *)vs, nelem);
985 nvlist_remove(nvl, ZPOOL_CONFIG_VDEV_STATS,
987 nvlist_remove(nvl, "stats",
989 DATA_TYPE_UINT64_ARRAY);
994 zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int nc)
996 nvlist_t *nv, *nvp = NULL;
1000 if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
1001 zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
1004 if (nc == 5) { /* ZFS_IOC_POOL_STATS */
1006 while ((elem = nvlist_next_nvpair(nv, elem)) != NULL) {
1007 if (nvpair_value_nvlist(elem, &nvp) == 0)
1008 zfs_ioctl_compat_fix_stats_nvlist(nvp);
1012 zfs_ioctl_compat_fix_stats_nvlist(nv);
1014 error = zfs_ioctl_compat_put_nvlist(zc, nv);
1022 zfs_ioctl_compat_pool_get_props(zfs_cmd_t *zc)
1024 nvlist_t *nv, *nva = NULL;
1027 if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
1028 zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
1032 if (nvlist_lookup_nvlist(nv, "allocated", &nva) == 0) {
1033 nvlist_add_nvlist(nv, "used", nva);
1034 nvlist_remove(nv, "allocated", DATA_TYPE_NVLIST);
1037 if (nvlist_lookup_nvlist(nv, "free", &nva) == 0) {
1038 nvlist_add_nvlist(nv, "available", nva);
1039 nvlist_remove(nv, "free", DATA_TYPE_NVLIST);
1042 if (nvlist_lookup_nvlist(nv, "used", &nva) == 0) {
1043 nvlist_add_nvlist(nv, "allocated", nva);
1044 nvlist_remove(nv, "used", DATA_TYPE_NVLIST);
1047 if (nvlist_lookup_nvlist(nv, "available", &nva) == 0) {
1048 nvlist_add_nvlist(nv, "free", nva);
1049 nvlist_remove(nv, "available", DATA_TYPE_NVLIST);
1053 error = zfs_ioctl_compat_put_nvlist(zc, nv);
1062 zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
1070 case ZFS_CMD_COMPAT_NONE:
1071 ncmd = _IOWR('Z', request, struct zfs_iocparm);
1072 zp.zfs_cmd = (uint64_t)zc;
1073 zp.zfs_cmd_size = sizeof(zfs_cmd_t);
1074 zp.zfs_ioctl_version = ZFS_IOCVER_CURRENT;
1075 return (ioctl(fd, ncmd, &zp));
1076 case ZFS_CMD_COMPAT_INLANES:
1077 ncmd = _IOWR('Z', request, struct zfs_iocparm);
1078 zp.zfs_cmd = (uint64_t)zc;
1079 zp.zfs_cmd_size = sizeof(zfs_cmd_inlanes_t);
1080 zp.zfs_ioctl_version = ZFS_IOCVER_INLANES;
1081 return (ioctl(fd, ncmd, &zp));
1082 case ZFS_CMD_COMPAT_RESUME:
1083 ncmd = _IOWR('Z', request, struct zfs_iocparm);
1084 zp.zfs_cmd = (uint64_t)zc;
1085 zp.zfs_cmd_size = sizeof(zfs_cmd_resume_t);
1086 zp.zfs_ioctl_version = ZFS_IOCVER_RESUME;
1087 return (ioctl(fd, ncmd, &zp));
1088 case ZFS_CMD_COMPAT_EDBP:
1089 ncmd = _IOWR('Z', request, struct zfs_iocparm);
1090 zp.zfs_cmd = (uint64_t)zc;
1091 zp.zfs_cmd_size = sizeof(zfs_cmd_edbp_t);
1092 zp.zfs_ioctl_version = ZFS_IOCVER_EDBP;
1093 return (ioctl(fd, ncmd, &zp));
1094 case ZFS_CMD_COMPAT_ZCMD:
1095 ncmd = _IOWR('Z', request, struct zfs_iocparm);
1096 zp.zfs_cmd = (uint64_t)zc;
1097 zp.zfs_cmd_size = sizeof(zfs_cmd_zcmd_t);
1098 zp.zfs_ioctl_version = ZFS_IOCVER_ZCMD;
1099 return (ioctl(fd, ncmd, &zp));
1100 case ZFS_CMD_COMPAT_LZC:
1101 ncmd = _IOWR('Z', request, struct zfs_cmd);
1102 return (ioctl(fd, ncmd, zc));
1103 case ZFS_CMD_COMPAT_DEADMAN:
1104 zc_c = malloc(sizeof(zfs_cmd_deadman_t));
1105 ncmd = _IOWR('Z', request, struct zfs_cmd_deadman);
1107 case ZFS_CMD_COMPAT_V28:
1108 zc_c = malloc(sizeof(zfs_cmd_v28_t));
1109 ncmd = _IOWR('Z', request, struct zfs_cmd_v28);
1111 case ZFS_CMD_COMPAT_V15:
1112 nc = zfs_ioctl_v28_to_v15[request];
1113 zc_c = malloc(sizeof(zfs_cmd_v15_t));
1114 ncmd = _IOWR('Z', nc, struct zfs_cmd_v15);
1120 if (ZFS_IOCREQ(ncmd) == ZFS_IOC_COMPAT_FAIL)
1123 zfs_cmd_compat_put(zc, (caddr_t)zc_c, request, cflag);
1125 ret = ioctl(fd, ncmd, zc_c);
1126 if (cflag == ZFS_CMD_COMPAT_V15 &&
1127 nc == ZFS_IOC_POOL_IMPORT)
1128 ret = ioctl(fd, _IOWR('Z', ZFS_IOC_POOL_CONFIGS,
1129 struct zfs_cmd_v15), zc_c);
1130 zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag);
1133 if (cflag == ZFS_CMD_COMPAT_V15) {
1135 case ZFS_IOC_POOL_IMPORT:
1136 case ZFS_IOC_POOL_CONFIGS:
1137 case ZFS_IOC_POOL_STATS:
1138 case ZFS_IOC_POOL_TRYIMPORT:
1139 zfs_ioctl_compat_fix_stats(zc, nc);
1141 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
1142 zfs_ioctl_compat_pool_get_props(zc);
1151 zfs_ioctl_compat_pre(zfs_cmd_t *zc, int *vec, const int cflag)
1155 /* are we creating a clone? */
1156 if (*vec == ZFS_IOC_CREATE && zc->zc_value[0] != '\0')
1157 *vec = ZFS_IOC_CLONE;
1159 if (cflag == ZFS_CMD_COMPAT_V15) {
1162 case 7: /* ZFS_IOC_POOL_SCRUB (v15) */
1163 zc->zc_cookie = POOL_SCAN_SCRUB;
1172 zfs_ioctl_compat_post(zfs_cmd_t *zc, int vec, const int cflag)
1174 if (cflag == ZFS_CMD_COMPAT_V15) {
1176 case ZFS_IOC_POOL_CONFIGS:
1177 case ZFS_IOC_POOL_STATS:
1178 case ZFS_IOC_POOL_TRYIMPORT:
1179 zfs_ioctl_compat_fix_stats(zc, vec);
1181 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
1182 zfs_ioctl_compat_pool_get_props(zc);
1189 zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec,
1192 nvlist_t *nvl, *tmpnvl, *hnvl;
1194 char *poolname, *snapname;
1197 if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC ||
1198 cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP ||
1199 cflag == ZFS_CMD_COMPAT_RESUME || cflag == ZFS_CMD_COMPAT_INLANES)
1203 case ZFS_IOC_CREATE:
1204 nvl = fnvlist_alloc();
1205 fnvlist_add_int32(nvl, "type", zc->zc_objset_type);
1206 if (innvl != NULL) {
1207 fnvlist_add_nvlist(nvl, "props", innvl);
1213 nvl = fnvlist_alloc();
1214 fnvlist_add_string(nvl, "origin", zc->zc_value);
1215 if (innvl != NULL) {
1216 fnvlist_add_nvlist(nvl, "props", innvl);
1221 case ZFS_IOC_SNAPSHOT:
1224 nvl = fnvlist_alloc();
1225 fnvlist_add_nvlist(nvl, "props", innvl);
1226 tmpnvl = fnvlist_alloc();
1227 snapname = kmem_asprintf("%s@%s", zc->zc_name, zc->zc_value);
1228 fnvlist_add_boolean(tmpnvl, snapname);
1229 kmem_free(snapname, strlen(snapname + 1));
1230 /* check if we are doing a recursive snapshot */
1232 dmu_get_recursive_snaps_nvl(zc->zc_name, zc->zc_value,
1234 fnvlist_add_nvlist(nvl, "snaps", tmpnvl);
1235 fnvlist_free(tmpnvl);
1237 /* strip dataset part from zc->zc_name */
1238 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1241 case ZFS_IOC_SPACE_SNAPS:
1242 nvl = fnvlist_alloc();
1243 fnvlist_add_string(nvl, "firstsnap", zc->zc_value);
1248 case ZFS_IOC_DESTROY_SNAPS:
1249 if (innvl == NULL && cflag == ZFS_CMD_COMPAT_DEADMAN)
1251 nvl = fnvlist_alloc();
1252 if (innvl != NULL) {
1253 fnvlist_add_nvlist(nvl, "snaps", innvl);
1256 * We are probably called by even older binaries,
1257 * allocate and populate nvlist with recursive
1260 if (zfs_component_namecheck(zc->zc_value, NULL,
1262 tmpnvl = fnvlist_alloc();
1263 if (dmu_get_recursive_snaps_nvl(zc->zc_name,
1264 zc->zc_value, tmpnvl) == 0)
1265 fnvlist_add_nvlist(nvl, "snaps",
1267 nvlist_free(tmpnvl);
1272 /* strip dataset part from zc->zc_name */
1273 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1277 nvl = fnvlist_alloc();
1278 tmpnvl = fnvlist_alloc();
1279 if (zc->zc_cleanup_fd != -1)
1280 fnvlist_add_int32(nvl, "cleanup_fd",
1281 (int32_t)zc->zc_cleanup_fd);
1282 if (zc->zc_cookie) {
1283 hnvl = fnvlist_alloc();
1284 if (dmu_get_recursive_snaps_nvl(zc->zc_name,
1285 zc->zc_value, hnvl) == 0) {
1287 while ((elem = nvlist_next_nvpair(hnvl,
1289 nvlist_add_string(tmpnvl,
1290 nvpair_name(elem), zc->zc_string);
1295 snapname = kmem_asprintf("%s@%s", zc->zc_name,
1297 nvlist_add_string(tmpnvl, snapname, zc->zc_string);
1298 kmem_free(snapname, strlen(snapname + 1));
1300 fnvlist_add_nvlist(nvl, "holds", tmpnvl);
1301 nvlist_free(tmpnvl);
1304 /* strip dataset part from zc->zc_name */
1305 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1308 case ZFS_IOC_RELEASE:
1309 nvl = fnvlist_alloc();
1310 tmpnvl = fnvlist_alloc();
1311 if (zc->zc_cookie) {
1312 hnvl = fnvlist_alloc();
1313 if (dmu_get_recursive_snaps_nvl(zc->zc_name,
1314 zc->zc_value, hnvl) == 0) {
1316 while ((elem = nvlist_next_nvpair(hnvl,
1318 fnvlist_add_boolean(tmpnvl,
1320 fnvlist_add_nvlist(nvl,
1321 nvpair_name(elem), tmpnvl);
1326 snapname = kmem_asprintf("%s@%s", zc->zc_name,
1328 fnvlist_add_boolean(tmpnvl, zc->zc_string);
1329 fnvlist_add_nvlist(nvl, snapname, tmpnvl);
1330 kmem_free(snapname, strlen(snapname + 1));
1332 nvlist_free(tmpnvl);
1335 /* strip dataset part from zc->zc_name */
1336 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1345 zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec,
1350 if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC ||
1351 cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP ||
1352 cflag == ZFS_CMD_COMPAT_RESUME || cflag == ZFS_CMD_COMPAT_INLANES)
1356 case ZFS_IOC_SPACE_SNAPS:
1357 (void) nvlist_lookup_uint64(outnvl, "used", &zc->zc_cookie);
1358 (void) nvlist_lookup_uint64(outnvl, "compressed",
1359 &zc->zc_objset_type);
1360 (void) nvlist_lookup_uint64(outnvl, "uncompressed",
1361 &zc->zc_perm_action);
1362 nvlist_free(outnvl);
1363 /* return empty outnvl */
1364 tmpnvl = fnvlist_alloc();
1367 case ZFS_IOC_CREATE:
1370 case ZFS_IOC_RELEASE:
1371 nvlist_free(outnvl);
1372 /* return empty outnvl */
1373 tmpnvl = fnvlist_alloc();