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;
59 case ZFS_CMD_COMPAT_EDBP:
60 edbp_c = (void *)addr;
62 strlcpy(zc->zc_name, edbp_c->zc_name, MAXPATHLEN);
63 strlcpy(zc->zc_value, edbp_c->zc_value, MAXPATHLEN * 2);
64 strlcpy(zc->zc_string, edbp_c->zc_string, MAXPATHLEN);
66 #define ZCMD_COPY(field) zc->field = edbp_c->field
67 ZCMD_COPY(zc_nvlist_src);
68 ZCMD_COPY(zc_nvlist_src_size);
69 ZCMD_COPY(zc_nvlist_dst);
70 ZCMD_COPY(zc_nvlist_dst_size);
71 ZCMD_COPY(zc_nvlist_dst_filled);
73 ZCMD_COPY(zc_history);
75 ZCMD_COPY(zc_nvlist_conf);
76 ZCMD_COPY(zc_nvlist_conf_size);
78 ZCMD_COPY(zc_objset_type);
79 ZCMD_COPY(zc_perm_action);
80 ZCMD_COPY(zc_history_len);
81 ZCMD_COPY(zc_history_offset);
86 ZCMD_COPY(zc_objset_stats);
87 zc->zc_begin_record.drr_u.drr_begin = edbp_c->zc_begin_record;
88 ZCMD_COPY(zc_inject_record);
89 ZCMD_COPY(zc_defer_destroy);
91 ZCMD_COPY(zc_action_handle);
92 ZCMD_COPY(zc_cleanup_fd);
94 zc->zc_resumable = B_FALSE;
95 ZCMD_COPY(zc_sendobj);
96 ZCMD_COPY(zc_fromobj);
97 ZCMD_COPY(zc_createtxg);
102 case ZFS_CMD_COMPAT_ZCMD:
103 zcmd_c = (void *)addr;
105 strlcpy(zc->zc_name, zcmd_c->zc_name, MAXPATHLEN);
106 strlcpy(zc->zc_value, zcmd_c->zc_value, MAXPATHLEN * 2);
107 strlcpy(zc->zc_string, zcmd_c->zc_string, MAXPATHLEN);
109 #define ZCMD_COPY(field) zc->field = zcmd_c->field
110 ZCMD_COPY(zc_nvlist_src);
111 ZCMD_COPY(zc_nvlist_src_size);
112 ZCMD_COPY(zc_nvlist_dst);
113 ZCMD_COPY(zc_nvlist_dst_size);
114 ZCMD_COPY(zc_nvlist_dst_filled);
116 ZCMD_COPY(zc_history);
118 ZCMD_COPY(zc_nvlist_conf);
119 ZCMD_COPY(zc_nvlist_conf_size);
120 ZCMD_COPY(zc_cookie);
121 ZCMD_COPY(zc_objset_type);
122 ZCMD_COPY(zc_perm_action);
123 ZCMD_COPY(zc_history_len);
124 ZCMD_COPY(zc_history_offset);
126 ZCMD_COPY(zc_iflags);
128 ZCMD_COPY(zc_jailid);
129 ZCMD_COPY(zc_objset_stats);
130 zc->zc_begin_record.drr_u.drr_begin = zcmd_c->zc_begin_record;
131 ZCMD_COPY(zc_inject_record);
133 /* boolean_t -> uint32_t */
134 zc->zc_defer_destroy = (uint32_t)(zcmd_c->zc_defer_destroy);
137 ZCMD_COPY(zc_action_handle);
138 ZCMD_COPY(zc_cleanup_fd);
139 ZCMD_COPY(zc_simple);
140 zc->zc_resumable = B_FALSE;
141 ZCMD_COPY(zc_sendobj);
142 ZCMD_COPY(zc_fromobj);
143 ZCMD_COPY(zc_createtxg);
149 case ZFS_CMD_COMPAT_DEADMAN:
150 zcdm_c = (void *)addr;
152 strlcpy(zc->zc_name, zcdm_c->zc_name, MAXPATHLEN);
153 strlcpy(zc->zc_value, zcdm_c->zc_value, MAXPATHLEN * 2);
154 strlcpy(zc->zc_string, zcdm_c->zc_string, MAXPATHLEN);
155 zc->zc_guid = zcdm_c->zc_guid;
156 zc->zc_nvlist_conf = zcdm_c->zc_nvlist_conf;
157 zc->zc_nvlist_conf_size = zcdm_c->zc_nvlist_conf_size;
158 zc->zc_nvlist_src = zcdm_c->zc_nvlist_src;
159 zc->zc_nvlist_src_size = zcdm_c->zc_nvlist_src_size;
160 zc->zc_nvlist_dst = zcdm_c->zc_nvlist_dst;
161 zc->zc_nvlist_dst_size = zcdm_c->zc_nvlist_dst_size;
162 zc->zc_cookie = zcdm_c->zc_cookie;
163 zc->zc_objset_type = zcdm_c->zc_objset_type;
164 zc->zc_perm_action = zcdm_c->zc_perm_action;
165 zc->zc_history = zcdm_c->zc_history;
166 zc->zc_history_len = zcdm_c->zc_history_len;
167 zc->zc_history_offset = zcdm_c->zc_history_offset;
168 zc->zc_obj = zcdm_c->zc_obj;
169 zc->zc_iflags = zcdm_c->zc_iflags;
170 zc->zc_share = zcdm_c->zc_share;
171 zc->zc_jailid = zcdm_c->zc_jailid;
172 zc->zc_objset_stats = zcdm_c->zc_objset_stats;
173 zc->zc_begin_record.drr_u.drr_begin = zcdm_c->zc_begin_record;
174 zc->zc_defer_destroy = zcdm_c->zc_defer_destroy;
175 (void)zcdm_c->zc_temphold;
176 zc->zc_action_handle = zcdm_c->zc_action_handle;
177 zc->zc_cleanup_fd = zcdm_c->zc_cleanup_fd;
178 zc->zc_simple = zcdm_c->zc_simple;
179 zc->zc_resumable = B_FALSE;
180 zc->zc_sendobj = zcdm_c->zc_sendobj;
181 zc->zc_fromobj = zcdm_c->zc_fromobj;
182 zc->zc_createtxg = zcdm_c->zc_createtxg;
183 zc->zc_stat = zcdm_c->zc_stat;
185 /* zc_inject_record doesn't change in libzfs_core */
186 zcdm_c->zc_inject_record = zc->zc_inject_record;
188 /* we always assume zc_nvlist_dst_filled is true */
189 zc->zc_nvlist_dst_filled = B_TRUE;
192 case ZFS_CMD_COMPAT_V28:
193 zc28_c = (void *)addr;
196 strlcpy(zc->zc_name, zc28_c->zc_name, MAXPATHLEN);
197 strlcpy(zc->zc_value, zc28_c->zc_value, MAXPATHLEN * 2);
198 strlcpy(zc->zc_string, zc28_c->zc_string, MAXPATHLEN);
199 zc->zc_guid = zc28_c->zc_guid;
200 zc->zc_nvlist_conf = zc28_c->zc_nvlist_conf;
201 zc->zc_nvlist_conf_size = zc28_c->zc_nvlist_conf_size;
202 zc->zc_nvlist_src = zc28_c->zc_nvlist_src;
203 zc->zc_nvlist_src_size = zc28_c->zc_nvlist_src_size;
204 zc->zc_nvlist_dst = zc28_c->zc_nvlist_dst;
205 zc->zc_nvlist_dst_size = zc28_c->zc_nvlist_dst_size;
206 zc->zc_cookie = zc28_c->zc_cookie;
207 zc->zc_objset_type = zc28_c->zc_objset_type;
208 zc->zc_perm_action = zc28_c->zc_perm_action;
209 zc->zc_history = zc28_c->zc_history;
210 zc->zc_history_len = zc28_c->zc_history_len;
211 zc->zc_history_offset = zc28_c->zc_history_offset;
212 zc->zc_obj = zc28_c->zc_obj;
213 zc->zc_iflags = zc28_c->zc_iflags;
214 zc->zc_share = zc28_c->zc_share;
215 zc->zc_jailid = zc28_c->zc_jailid;
216 zc->zc_objset_stats = zc28_c->zc_objset_stats;
217 zc->zc_begin_record.drr_u.drr_begin = zc28_c->zc_begin_record;
218 zc->zc_defer_destroy = zc28_c->zc_defer_destroy;
219 (void)zc28_c->zc_temphold;
220 zc->zc_action_handle = zc28_c->zc_action_handle;
221 zc->zc_cleanup_fd = zc28_c->zc_cleanup_fd;
222 zc->zc_simple = zc28_c->zc_simple;
223 zc->zc_resumable = B_FALSE;
224 zc->zc_sendobj = zc28_c->zc_sendobj;
225 zc->zc_fromobj = zc28_c->zc_fromobj;
226 zc->zc_createtxg = zc28_c->zc_createtxg;
227 zc->zc_stat = zc28_c->zc_stat;
229 /* zc->zc_inject_record */
230 zc->zc_inject_record.zi_objset =
231 zc28_c->zc_inject_record.zi_objset;
232 zc->zc_inject_record.zi_object =
233 zc28_c->zc_inject_record.zi_object;
234 zc->zc_inject_record.zi_start =
235 zc28_c->zc_inject_record.zi_start;
236 zc->zc_inject_record.zi_end =
237 zc28_c->zc_inject_record.zi_end;
238 zc->zc_inject_record.zi_guid =
239 zc28_c->zc_inject_record.zi_guid;
240 zc->zc_inject_record.zi_level =
241 zc28_c->zc_inject_record.zi_level;
242 zc->zc_inject_record.zi_error =
243 zc28_c->zc_inject_record.zi_error;
244 zc->zc_inject_record.zi_type =
245 zc28_c->zc_inject_record.zi_type;
246 zc->zc_inject_record.zi_freq =
247 zc28_c->zc_inject_record.zi_freq;
248 zc->zc_inject_record.zi_failfast =
249 zc28_c->zc_inject_record.zi_failfast;
250 strlcpy(zc->zc_inject_record.zi_func,
251 zc28_c->zc_inject_record.zi_func, MAXNAMELEN);
252 zc->zc_inject_record.zi_iotype =
253 zc28_c->zc_inject_record.zi_iotype;
254 zc->zc_inject_record.zi_duration =
255 zc28_c->zc_inject_record.zi_duration;
256 zc->zc_inject_record.zi_timer =
257 zc28_c->zc_inject_record.zi_timer;
258 zc->zc_inject_record.zi_cmd = ZINJECT_UNINITIALIZED;
259 zc->zc_inject_record.zi_pad = 0;
262 case ZFS_CMD_COMPAT_V15:
266 strlcpy(zc->zc_name, zc_c->zc_name, MAXPATHLEN);
267 strlcpy(zc->zc_value, zc_c->zc_value, MAXPATHLEN);
268 strlcpy(zc->zc_string, zc_c->zc_string, MAXPATHLEN);
269 zc->zc_guid = zc_c->zc_guid;
270 zc->zc_nvlist_conf = zc_c->zc_nvlist_conf;
271 zc->zc_nvlist_conf_size = zc_c->zc_nvlist_conf_size;
272 zc->zc_nvlist_src = zc_c->zc_nvlist_src;
273 zc->zc_nvlist_src_size = zc_c->zc_nvlist_src_size;
274 zc->zc_nvlist_dst = zc_c->zc_nvlist_dst;
275 zc->zc_nvlist_dst_size = zc_c->zc_nvlist_dst_size;
276 zc->zc_cookie = zc_c->zc_cookie;
277 zc->zc_objset_type = zc_c->zc_objset_type;
278 zc->zc_perm_action = zc_c->zc_perm_action;
279 zc->zc_history = zc_c->zc_history;
280 zc->zc_history_len = zc_c->zc_history_len;
281 zc->zc_history_offset = zc_c->zc_history_offset;
282 zc->zc_obj = zc_c->zc_obj;
283 zc->zc_share = zc_c->zc_share;
284 zc->zc_jailid = zc_c->zc_jailid;
285 zc->zc_objset_stats = zc_c->zc_objset_stats;
286 zc->zc_begin_record.drr_u.drr_begin = zc_c->zc_begin_record;
288 /* zc->zc_inject_record */
289 zc->zc_inject_record.zi_objset =
290 zc_c->zc_inject_record.zi_objset;
291 zc->zc_inject_record.zi_object =
292 zc_c->zc_inject_record.zi_object;
293 zc->zc_inject_record.zi_start =
294 zc_c->zc_inject_record.zi_start;
295 zc->zc_inject_record.zi_end =
296 zc_c->zc_inject_record.zi_end;
297 zc->zc_inject_record.zi_guid =
298 zc_c->zc_inject_record.zi_guid;
299 zc->zc_inject_record.zi_level =
300 zc_c->zc_inject_record.zi_level;
301 zc->zc_inject_record.zi_error =
302 zc_c->zc_inject_record.zi_error;
303 zc->zc_inject_record.zi_type =
304 zc_c->zc_inject_record.zi_type;
305 zc->zc_inject_record.zi_freq =
306 zc_c->zc_inject_record.zi_freq;
307 zc->zc_inject_record.zi_failfast =
308 zc_c->zc_inject_record.zi_failfast;
314 zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request,
318 zfs_cmd_v28_t *zc28_c;
319 zfs_cmd_deadman_t *zcdm_c;
320 zfs_cmd_zcmd_t *zcmd_c;
321 zfs_cmd_edbp_t *edbp_c;
324 case ZFS_CMD_COMPAT_EDBP:
325 edbp_c = (void *)addr;
326 strlcpy(edbp_c->zc_name, zc->zc_name, MAXPATHLEN);
327 strlcpy(edbp_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
328 strlcpy(edbp_c->zc_string, zc->zc_string, MAXPATHLEN);
330 #define ZCMD_COPY(field) edbp_c->field = zc->field
331 ZCMD_COPY(zc_nvlist_src);
332 ZCMD_COPY(zc_nvlist_src_size);
333 ZCMD_COPY(zc_nvlist_dst);
334 ZCMD_COPY(zc_nvlist_dst_size);
335 ZCMD_COPY(zc_nvlist_dst_filled);
337 ZCMD_COPY(zc_history);
339 ZCMD_COPY(zc_nvlist_conf);
340 ZCMD_COPY(zc_nvlist_conf_size);
341 ZCMD_COPY(zc_cookie);
342 ZCMD_COPY(zc_objset_type);
343 ZCMD_COPY(zc_perm_action);
344 ZCMD_COPY(zc_history_len);
345 ZCMD_COPY(zc_history_offset);
347 ZCMD_COPY(zc_iflags);
349 ZCMD_COPY(zc_jailid);
350 ZCMD_COPY(zc_objset_stats);
351 edbp_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
352 ZCMD_COPY(zc_inject_record);
353 ZCMD_COPY(zc_defer_destroy);
355 ZCMD_COPY(zc_action_handle);
356 ZCMD_COPY(zc_cleanup_fd);
357 ZCMD_COPY(zc_simple);
358 ZCMD_COPY(zc_sendobj);
359 ZCMD_COPY(zc_fromobj);
360 ZCMD_COPY(zc_createtxg);
365 case ZFS_CMD_COMPAT_ZCMD:
366 zcmd_c = (void *)addr;
368 strlcpy(zcmd_c->zc_name, zc->zc_name, MAXPATHLEN);
369 strlcpy(zcmd_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
370 strlcpy(zcmd_c->zc_string, zc->zc_string, MAXPATHLEN);
372 #define ZCMD_COPY(field) zcmd_c->field = zc->field
373 ZCMD_COPY(zc_nvlist_src);
374 ZCMD_COPY(zc_nvlist_src_size);
375 ZCMD_COPY(zc_nvlist_dst);
376 ZCMD_COPY(zc_nvlist_dst_size);
377 ZCMD_COPY(zc_nvlist_dst_filled);
379 ZCMD_COPY(zc_history);
381 ZCMD_COPY(zc_nvlist_conf);
382 ZCMD_COPY(zc_nvlist_conf_size);
383 ZCMD_COPY(zc_cookie);
384 ZCMD_COPY(zc_objset_type);
385 ZCMD_COPY(zc_perm_action);
386 ZCMD_COPY(zc_history_len);
387 ZCMD_COPY(zc_history_offset);
389 ZCMD_COPY(zc_iflags);
391 ZCMD_COPY(zc_jailid);
392 ZCMD_COPY(zc_objset_stats);
393 zcmd_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
394 ZCMD_COPY(zc_inject_record);
396 /* boolean_t -> uint32_t */
397 zcmd_c->zc_defer_destroy = (uint32_t)(zc->zc_defer_destroy);
398 zcmd_c->zc_temphold = 0;
400 ZCMD_COPY(zc_action_handle);
401 ZCMD_COPY(zc_cleanup_fd);
402 ZCMD_COPY(zc_simple);
403 ZCMD_COPY(zc_sendobj);
404 ZCMD_COPY(zc_fromobj);
405 ZCMD_COPY(zc_createtxg);
411 case ZFS_CMD_COMPAT_DEADMAN:
412 zcdm_c = (void *)addr;
414 strlcpy(zcdm_c->zc_name, zc->zc_name, MAXPATHLEN);
415 strlcpy(zcdm_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
416 strlcpy(zcdm_c->zc_string, zc->zc_string, MAXPATHLEN);
417 zcdm_c->zc_guid = zc->zc_guid;
418 zcdm_c->zc_nvlist_conf = zc->zc_nvlist_conf;
419 zcdm_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
420 zcdm_c->zc_nvlist_src = zc->zc_nvlist_src;
421 zcdm_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
422 zcdm_c->zc_nvlist_dst = zc->zc_nvlist_dst;
423 zcdm_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
424 zcdm_c->zc_cookie = zc->zc_cookie;
425 zcdm_c->zc_objset_type = zc->zc_objset_type;
426 zcdm_c->zc_perm_action = zc->zc_perm_action;
427 zcdm_c->zc_history = zc->zc_history;
428 zcdm_c->zc_history_len = zc->zc_history_len;
429 zcdm_c->zc_history_offset = zc->zc_history_offset;
430 zcdm_c->zc_obj = zc->zc_obj;
431 zcdm_c->zc_iflags = zc->zc_iflags;
432 zcdm_c->zc_share = zc->zc_share;
433 zcdm_c->zc_jailid = zc->zc_jailid;
434 zcdm_c->zc_objset_stats = zc->zc_objset_stats;
435 zcdm_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
436 zcdm_c->zc_defer_destroy = zc->zc_defer_destroy;
437 zcdm_c->zc_temphold = 0;
438 zcdm_c->zc_action_handle = zc->zc_action_handle;
439 zcdm_c->zc_cleanup_fd = zc->zc_cleanup_fd;
440 zcdm_c->zc_simple = zc->zc_simple;
441 zcdm_c->zc_sendobj = zc->zc_sendobj;
442 zcdm_c->zc_fromobj = zc->zc_fromobj;
443 zcdm_c->zc_createtxg = zc->zc_createtxg;
444 zcdm_c->zc_stat = zc->zc_stat;
446 /* zc_inject_record doesn't change in libzfs_core */
447 zc->zc_inject_record = zcdm_c->zc_inject_record;
449 if (request == ZFS_IOC_RECV)
450 strlcpy(zcdm_c->zc_top_ds,
451 zc->zc_value + strlen(zc->zc_value) + 1,
452 (MAXPATHLEN * 2) - strlen(zc->zc_value) - 1);
456 case ZFS_CMD_COMPAT_V28:
457 zc28_c = (void *)addr;
459 strlcpy(zc28_c->zc_name, zc->zc_name, MAXPATHLEN);
460 strlcpy(zc28_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
461 strlcpy(zc28_c->zc_string, zc->zc_string, MAXPATHLEN);
462 zc28_c->zc_guid = zc->zc_guid;
463 zc28_c->zc_nvlist_conf = zc->zc_nvlist_conf;
464 zc28_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
465 zc28_c->zc_nvlist_src = zc->zc_nvlist_src;
466 zc28_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
467 zc28_c->zc_nvlist_dst = zc->zc_nvlist_dst;
468 zc28_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
469 zc28_c->zc_cookie = zc->zc_cookie;
470 zc28_c->zc_objset_type = zc->zc_objset_type;
471 zc28_c->zc_perm_action = zc->zc_perm_action;
472 zc28_c->zc_history = zc->zc_history;
473 zc28_c->zc_history_len = zc->zc_history_len;
474 zc28_c->zc_history_offset = zc->zc_history_offset;
475 zc28_c->zc_obj = zc->zc_obj;
476 zc28_c->zc_iflags = zc->zc_iflags;
477 zc28_c->zc_share = zc->zc_share;
478 zc28_c->zc_jailid = zc->zc_jailid;
479 zc28_c->zc_objset_stats = zc->zc_objset_stats;
480 zc28_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
481 zc28_c->zc_defer_destroy = zc->zc_defer_destroy;
482 zc28_c->zc_temphold = 0;
483 zc28_c->zc_action_handle = zc->zc_action_handle;
484 zc28_c->zc_cleanup_fd = zc->zc_cleanup_fd;
485 zc28_c->zc_simple = zc->zc_simple;
486 zc28_c->zc_sendobj = zc->zc_sendobj;
487 zc28_c->zc_fromobj = zc->zc_fromobj;
488 zc28_c->zc_createtxg = zc->zc_createtxg;
489 zc28_c->zc_stat = zc->zc_stat;
491 if (request == ZFS_IOC_RECV)
492 strlcpy(zc28_c->zc_top_ds,
493 zc->zc_value + strlen(zc->zc_value) + 1,
494 MAXPATHLEN * 2 - strlen(zc->zc_value) - 1);
496 /* zc_inject_record */
497 zc28_c->zc_inject_record.zi_objset =
498 zc->zc_inject_record.zi_objset;
499 zc28_c->zc_inject_record.zi_object =
500 zc->zc_inject_record.zi_object;
501 zc28_c->zc_inject_record.zi_start =
502 zc->zc_inject_record.zi_start;
503 zc28_c->zc_inject_record.zi_end =
504 zc->zc_inject_record.zi_end;
505 zc28_c->zc_inject_record.zi_guid =
506 zc->zc_inject_record.zi_guid;
507 zc28_c->zc_inject_record.zi_level =
508 zc->zc_inject_record.zi_level;
509 zc28_c->zc_inject_record.zi_error =
510 zc->zc_inject_record.zi_error;
511 zc28_c->zc_inject_record.zi_type =
512 zc->zc_inject_record.zi_type;
513 zc28_c->zc_inject_record.zi_freq =
514 zc->zc_inject_record.zi_freq;
515 zc28_c->zc_inject_record.zi_failfast =
516 zc->zc_inject_record.zi_failfast;
517 strlcpy(zc28_c->zc_inject_record.zi_func,
518 zc->zc_inject_record.zi_func, MAXNAMELEN);
519 zc28_c->zc_inject_record.zi_iotype =
520 zc->zc_inject_record.zi_iotype;
521 zc28_c->zc_inject_record.zi_duration =
522 zc->zc_inject_record.zi_duration;
523 zc28_c->zc_inject_record.zi_timer =
524 zc->zc_inject_record.zi_timer;
527 case ZFS_CMD_COMPAT_V15:
531 strlcpy(zc_c->zc_name, zc->zc_name, MAXPATHLEN);
532 strlcpy(zc_c->zc_value, zc->zc_value, MAXPATHLEN);
533 strlcpy(zc_c->zc_string, zc->zc_string, MAXPATHLEN);
534 zc_c->zc_guid = zc->zc_guid;
535 zc_c->zc_nvlist_conf = zc->zc_nvlist_conf;
536 zc_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
537 zc_c->zc_nvlist_src = zc->zc_nvlist_src;
538 zc_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
539 zc_c->zc_nvlist_dst = zc->zc_nvlist_dst;
540 zc_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
541 zc_c->zc_cookie = zc->zc_cookie;
542 zc_c->zc_objset_type = zc->zc_objset_type;
543 zc_c->zc_perm_action = zc->zc_perm_action;
544 zc_c->zc_history = zc->zc_history;
545 zc_c->zc_history_len = zc->zc_history_len;
546 zc_c->zc_history_offset = zc->zc_history_offset;
547 zc_c->zc_obj = zc->zc_obj;
548 zc_c->zc_share = zc->zc_share;
549 zc_c->zc_jailid = zc->zc_jailid;
550 zc_c->zc_objset_stats = zc->zc_objset_stats;
551 zc_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
553 /* zc_inject_record */
554 zc_c->zc_inject_record.zi_objset =
555 zc->zc_inject_record.zi_objset;
556 zc_c->zc_inject_record.zi_object =
557 zc->zc_inject_record.zi_object;
558 zc_c->zc_inject_record.zi_start =
559 zc->zc_inject_record.zi_start;
560 zc_c->zc_inject_record.zi_end =
561 zc->zc_inject_record.zi_end;
562 zc_c->zc_inject_record.zi_guid =
563 zc->zc_inject_record.zi_guid;
564 zc_c->zc_inject_record.zi_level =
565 zc->zc_inject_record.zi_level;
566 zc_c->zc_inject_record.zi_error =
567 zc->zc_inject_record.zi_error;
568 zc_c->zc_inject_record.zi_type =
569 zc->zc_inject_record.zi_type;
570 zc_c->zc_inject_record.zi_freq =
571 zc->zc_inject_record.zi_freq;
572 zc_c->zc_inject_record.zi_failfast =
573 zc->zc_inject_record.zi_failfast;
580 zfs_ioctl_compat_get_nvlist(uint64_t nvl, size_t size, int iflag,
585 nvlist_t *list = NULL;
588 * Read in and unpack the user-supplied nvlist.
594 packed = kmem_alloc(size, KM_SLEEP);
595 if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
597 kmem_free(packed, size);
601 packed = (void *)(uintptr_t)nvl;
604 error = nvlist_unpack(packed, size, &list, 0);
607 kmem_free(packed, size);
618 zfs_ioctl_compat_put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
624 VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0);
627 packed = kmem_alloc(size, KM_SLEEP);
628 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
631 if (ddi_copyout(packed,
632 (void *)(uintptr_t)zc->zc_nvlist_dst, size, zc->zc_iflags) != 0)
634 kmem_free(packed, size);
636 packed = (void *)(uintptr_t)zc->zc_nvlist_dst;
637 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
641 zc->zc_nvlist_dst_size = size;
646 zfs_ioctl_compat_fix_stats_nvlist(nvlist_t *nvl)
649 nvlist_t *nvroot = NULL;
651 uint_t c, children, nelem;
653 if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN,
654 &child, &children) == 0) {
655 for (c = 0; c < children; c++) {
656 zfs_ioctl_compat_fix_stats_nvlist(child[c]);
660 if (nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_VDEV_TREE,
662 zfs_ioctl_compat_fix_stats_nvlist(nvroot);
664 if ((nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_VDEV_STATS,
666 if ((nvlist_lookup_uint64_array(nvl, "stats",
669 (uint64_t **)&vs, &nelem) == 0)) {
670 nvlist_add_uint64_array(nvl,
674 ZPOOL_CONFIG_VDEV_STATS,
676 (uint64_t *)vs, nelem);
678 nvlist_remove(nvl, ZPOOL_CONFIG_VDEV_STATS,
680 nvlist_remove(nvl, "stats",
682 DATA_TYPE_UINT64_ARRAY);
687 zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int nc)
689 nvlist_t *nv, *nvp = NULL;
693 if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
694 zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
697 if (nc == 5) { /* ZFS_IOC_POOL_STATS */
699 while ((elem = nvlist_next_nvpair(nv, elem)) != NULL) {
700 if (nvpair_value_nvlist(elem, &nvp) == 0)
701 zfs_ioctl_compat_fix_stats_nvlist(nvp);
705 zfs_ioctl_compat_fix_stats_nvlist(nv);
707 error = zfs_ioctl_compat_put_nvlist(zc, nv);
715 zfs_ioctl_compat_pool_get_props(zfs_cmd_t *zc)
717 nvlist_t *nv, *nva = NULL;
720 if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
721 zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
725 if (nvlist_lookup_nvlist(nv, "allocated", &nva) == 0) {
726 nvlist_add_nvlist(nv, "used", nva);
727 nvlist_remove(nv, "allocated", DATA_TYPE_NVLIST);
730 if (nvlist_lookup_nvlist(nv, "free", &nva) == 0) {
731 nvlist_add_nvlist(nv, "available", nva);
732 nvlist_remove(nv, "free", DATA_TYPE_NVLIST);
735 if (nvlist_lookup_nvlist(nv, "used", &nva) == 0) {
736 nvlist_add_nvlist(nv, "allocated", nva);
737 nvlist_remove(nv, "used", DATA_TYPE_NVLIST);
740 if (nvlist_lookup_nvlist(nv, "available", &nva) == 0) {
741 nvlist_add_nvlist(nv, "free", nva);
742 nvlist_remove(nv, "available", DATA_TYPE_NVLIST);
746 error = zfs_ioctl_compat_put_nvlist(zc, nv);
755 zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
763 case ZFS_CMD_COMPAT_NONE:
764 ncmd = _IOWR('Z', request, struct zfs_iocparm);
765 zp.zfs_cmd = (uint64_t)zc;
766 zp.zfs_cmd_size = sizeof(zfs_cmd_t);
767 zp.zfs_ioctl_version = ZFS_IOCVER_CURRENT;
768 return (ioctl(fd, ncmd, &zp));
769 case ZFS_CMD_COMPAT_EDBP:
770 ncmd = _IOWR('Z', request, struct zfs_iocparm);
771 zp.zfs_cmd = (uint64_t)zc;
772 zp.zfs_cmd_size = sizeof(zfs_cmd_edbp_t);
773 zp.zfs_ioctl_version = ZFS_IOCVER_EDBP;
774 return (ioctl(fd, ncmd, &zp));
775 case ZFS_CMD_COMPAT_ZCMD:
776 ncmd = _IOWR('Z', request, struct zfs_iocparm);
777 zp.zfs_cmd = (uint64_t)zc;
778 zp.zfs_cmd_size = sizeof(zfs_cmd_zcmd_t);
779 zp.zfs_ioctl_version = ZFS_IOCVER_ZCMD;
780 return (ioctl(fd, ncmd, &zp));
781 case ZFS_CMD_COMPAT_LZC:
782 ncmd = _IOWR('Z', request, struct zfs_cmd);
783 return (ioctl(fd, ncmd, zc));
784 case ZFS_CMD_COMPAT_DEADMAN:
785 zc_c = malloc(sizeof(zfs_cmd_deadman_t));
786 ncmd = _IOWR('Z', request, struct zfs_cmd_deadman);
788 case ZFS_CMD_COMPAT_V28:
789 zc_c = malloc(sizeof(zfs_cmd_v28_t));
790 ncmd = _IOWR('Z', request, struct zfs_cmd_v28);
792 case ZFS_CMD_COMPAT_V15:
793 nc = zfs_ioctl_v28_to_v15[request];
794 zc_c = malloc(sizeof(zfs_cmd_v15_t));
795 ncmd = _IOWR('Z', nc, struct zfs_cmd_v15);
801 if (ZFS_IOCREQ(ncmd) == ZFS_IOC_COMPAT_FAIL)
804 zfs_cmd_compat_put(zc, (caddr_t)zc_c, request, cflag);
806 ret = ioctl(fd, ncmd, zc_c);
807 if (cflag == ZFS_CMD_COMPAT_V15 &&
808 nc == ZFS_IOC_POOL_IMPORT)
809 ret = ioctl(fd, _IOWR('Z', ZFS_IOC_POOL_CONFIGS,
810 struct zfs_cmd_v15), zc_c);
811 zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag);
814 if (cflag == ZFS_CMD_COMPAT_V15) {
816 case ZFS_IOC_POOL_IMPORT:
817 case ZFS_IOC_POOL_CONFIGS:
818 case ZFS_IOC_POOL_STATS:
819 case ZFS_IOC_POOL_TRYIMPORT:
820 zfs_ioctl_compat_fix_stats(zc, nc);
822 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
823 zfs_ioctl_compat_pool_get_props(zc);
832 zfs_ioctl_compat_pre(zfs_cmd_t *zc, int *vec, const int cflag)
836 /* are we creating a clone? */
837 if (*vec == ZFS_IOC_CREATE && zc->zc_value[0] != '\0')
838 *vec = ZFS_IOC_CLONE;
840 if (cflag == ZFS_CMD_COMPAT_V15) {
843 case 7: /* ZFS_IOC_POOL_SCRUB (v15) */
844 zc->zc_cookie = POOL_SCAN_SCRUB;
853 zfs_ioctl_compat_post(zfs_cmd_t *zc, int vec, const int cflag)
855 if (cflag == ZFS_CMD_COMPAT_V15) {
857 case ZFS_IOC_POOL_CONFIGS:
858 case ZFS_IOC_POOL_STATS:
859 case ZFS_IOC_POOL_TRYIMPORT:
860 zfs_ioctl_compat_fix_stats(zc, vec);
862 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
863 zfs_ioctl_compat_pool_get_props(zc);
870 zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec,
873 nvlist_t *nvl, *tmpnvl, *hnvl;
875 char *poolname, *snapname;
878 if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC ||
879 cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP)
884 nvl = fnvlist_alloc();
885 fnvlist_add_int32(nvl, "type", zc->zc_objset_type);
887 fnvlist_add_nvlist(nvl, "props", innvl);
893 nvl = fnvlist_alloc();
894 fnvlist_add_string(nvl, "origin", zc->zc_value);
896 fnvlist_add_nvlist(nvl, "props", innvl);
901 case ZFS_IOC_SNAPSHOT:
904 nvl = fnvlist_alloc();
905 fnvlist_add_nvlist(nvl, "props", innvl);
906 tmpnvl = fnvlist_alloc();
907 snapname = kmem_asprintf("%s@%s", zc->zc_name, zc->zc_value);
908 fnvlist_add_boolean(tmpnvl, snapname);
909 kmem_free(snapname, strlen(snapname + 1));
910 /* check if we are doing a recursive snapshot */
912 dmu_get_recursive_snaps_nvl(zc->zc_name, zc->zc_value,
914 fnvlist_add_nvlist(nvl, "snaps", tmpnvl);
915 fnvlist_free(tmpnvl);
917 /* strip dataset part from zc->zc_name */
918 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
921 case ZFS_IOC_SPACE_SNAPS:
922 nvl = fnvlist_alloc();
923 fnvlist_add_string(nvl, "firstsnap", zc->zc_value);
928 case ZFS_IOC_DESTROY_SNAPS:
929 if (innvl == NULL && cflag == ZFS_CMD_COMPAT_DEADMAN)
931 nvl = fnvlist_alloc();
933 fnvlist_add_nvlist(nvl, "snaps", innvl);
936 * We are probably called by even older binaries,
937 * allocate and populate nvlist with recursive
940 if (zfs_component_namecheck(zc->zc_value, NULL,
942 tmpnvl = fnvlist_alloc();
943 if (dmu_get_recursive_snaps_nvl(zc->zc_name,
944 zc->zc_value, tmpnvl) == 0)
945 fnvlist_add_nvlist(nvl, "snaps",
952 /* strip dataset part from zc->zc_name */
953 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
957 nvl = fnvlist_alloc();
958 tmpnvl = fnvlist_alloc();
959 if (zc->zc_cleanup_fd != -1)
960 fnvlist_add_int32(nvl, "cleanup_fd",
961 (int32_t)zc->zc_cleanup_fd);
963 hnvl = fnvlist_alloc();
964 if (dmu_get_recursive_snaps_nvl(zc->zc_name,
965 zc->zc_value, hnvl) == 0) {
967 while ((elem = nvlist_next_nvpair(hnvl,
969 nvlist_add_string(tmpnvl,
970 nvpair_name(elem), zc->zc_string);
975 snapname = kmem_asprintf("%s@%s", zc->zc_name,
977 nvlist_add_string(tmpnvl, snapname, zc->zc_string);
978 kmem_free(snapname, strlen(snapname + 1));
980 fnvlist_add_nvlist(nvl, "holds", tmpnvl);
984 /* strip dataset part from zc->zc_name */
985 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
988 case ZFS_IOC_RELEASE:
989 nvl = fnvlist_alloc();
990 tmpnvl = fnvlist_alloc();
992 hnvl = fnvlist_alloc();
993 if (dmu_get_recursive_snaps_nvl(zc->zc_name,
994 zc->zc_value, hnvl) == 0) {
996 while ((elem = nvlist_next_nvpair(hnvl,
998 fnvlist_add_boolean(tmpnvl,
1000 fnvlist_add_nvlist(nvl,
1001 nvpair_name(elem), tmpnvl);
1006 snapname = kmem_asprintf("%s@%s", zc->zc_name,
1008 fnvlist_add_boolean(tmpnvl, zc->zc_string);
1009 fnvlist_add_nvlist(nvl, snapname, tmpnvl);
1010 kmem_free(snapname, strlen(snapname + 1));
1012 nvlist_free(tmpnvl);
1015 /* strip dataset part from zc->zc_name */
1016 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1025 zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec,
1030 if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC ||
1031 cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP)
1035 case ZFS_IOC_SPACE_SNAPS:
1036 (void) nvlist_lookup_uint64(outnvl, "used", &zc->zc_cookie);
1037 (void) nvlist_lookup_uint64(outnvl, "compressed",
1038 &zc->zc_objset_type);
1039 (void) nvlist_lookup_uint64(outnvl, "uncompressed",
1040 &zc->zc_perm_action);
1041 nvlist_free(outnvl);
1042 /* return empty outnvl */
1043 tmpnvl = fnvlist_alloc();
1046 case ZFS_IOC_CREATE:
1049 case ZFS_IOC_RELEASE:
1050 nvlist_free(outnvl);
1051 /* return empty outnvl */
1052 tmpnvl = fnvlist_alloc();