]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / sys / cddl / contrib / opensolaris / common / zfs / zfs_ioctl_compat.c
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
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.
27  */
28
29 #include <sys/types.h>
30 #include <sys/param.h>
31 #include <sys/cred.h>
32 #include <sys/dmu.h>
33 #include <sys/zio.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"
39
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");
44
45 /*
46  * FreeBSD zfs_cmd compatibility with older binaries
47  * appropriately remap/extend the zfs_cmd_t structure
48  */
49 void
50 zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag)
51 {
52         zfs_cmd_v15_t *zc_c;
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;
59
60         switch (cflag) {
61         case ZFS_CMD_COMPAT_INLANES:
62                 inlanes_c = (void *)addr;
63                 /* zc */
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);
67
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);
74                 FIELD_COPY(zc_pad2);
75                 FIELD_COPY(zc_history);
76                 FIELD_COPY(zc_guid);
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);
84                 FIELD_COPY(zc_obj);
85                 FIELD_COPY(zc_iflags);
86                 FIELD_COPY(zc_share);
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);
92                 FIELD_COPY(zc_flags);
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);
100                 FIELD_COPY(zc_stat);
101 #undef FIELD_COPY
102                 break;
103
104         case ZFS_CMD_COMPAT_RESUME:
105                 resume_c = (void *)addr;
106                 /* zc */
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);
110
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);
117                 FIELD_COPY(zc_pad2);
118                 FIELD_COPY(zc_history);
119                 FIELD_COPY(zc_guid);
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);
127                 FIELD_COPY(zc_obj);
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);
160                 FIELD_COPY(zc_stat);
161 #undef FIELD_COPY
162                 break;
163
164         case ZFS_CMD_COMPAT_EDBP:
165                 edbp_c = (void *)addr;
166                 /* zc */
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);
170
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);
177                 FIELD_COPY(zc_pad2);
178                 FIELD_COPY(zc_history);
179                 FIELD_COPY(zc_guid);
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);
187                 FIELD_COPY(zc_obj);
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);
220                 FIELD_COPY(zc_stat);
221 #undef FIELD_COPY
222                 break;
223
224         case ZFS_CMD_COMPAT_ZCMD:
225                 zcmd_c = (void *)addr;
226                 /* zc */
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);
230
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);
237                 FIELD_COPY(zc_pad2);
238                 FIELD_COPY(zc_history);
239                 FIELD_COPY(zc_guid);
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);
247                 FIELD_COPY(zc_obj);
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);
271
272                 /* boolean_t -> uint32_t */
273                 zc->zc_defer_destroy = (uint32_t)(zcmd_c->zc_defer_destroy);
274                 zc->zc_flags = 0;
275
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);
283                 FIELD_COPY(zc_stat);
284 #undef FIELD_COPY
285
286                 break;
287
288         case ZFS_CMD_COMPAT_DEADMAN:
289                 zcdm_c = (void *)addr;
290                 /* zc */
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);
294
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);
343
344                 /* we always assume zc_nvlist_dst_filled is true */
345                 zc->zc_nvlist_dst_filled = B_TRUE;
346 #undef FIELD_COPY
347                 break;
348
349         case ZFS_CMD_COMPAT_V28:
350                 zc28_c = (void *)addr;
351
352                 /* zc */
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;
385
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;
418                 break;
419
420         case ZFS_CMD_COMPAT_V15:
421                 zc_c = (void *)addr;
422
423                 /* zc */
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;
445
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;
467                 break;
468         }
469 }
470
471 void
472 zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request,
473     const int cflag)
474 {
475         zfs_cmd_v15_t *zc_c;
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;
482
483         switch (cflag) {
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);
489
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);
496                 FIELD_COPY(zc_pad2);
497                 FIELD_COPY(zc_history);
498                 FIELD_COPY(zc_guid);
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);
506                 FIELD_COPY(zc_obj);
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);
521                 FIELD_COPY(zc_stat);
522 #undef FIELD_COPY
523                 break;
524
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);
530
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);
537                 FIELD_COPY(zc_pad2);
538                 FIELD_COPY(zc_history);
539                 FIELD_COPY(zc_guid);
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);
547                 FIELD_COPY(zc_obj);
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);
578                 FIELD_COPY(zc_stat);
579 #undef FIELD_COPY
580                 break;
581
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);
587
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);
594                 FIELD_COPY(zc_pad2);
595                 FIELD_COPY(zc_history);
596                 FIELD_COPY(zc_guid);
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);
604                 FIELD_COPY(zc_obj);
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);
635                 FIELD_COPY(zc_stat);
636 #undef FIELD_COPY
637                 break;
638
639         case ZFS_CMD_COMPAT_ZCMD:
640                 zcmd_c = (void *)addr;
641                 /* zc */
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);
645
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);
652                 FIELD_COPY(zc_pad2);
653                 FIELD_COPY(zc_history);
654                 FIELD_COPY(zc_guid);
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);
662                 FIELD_COPY(zc_obj);
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);
685
686                 /* boolean_t -> uint32_t */
687                 zcmd_c->zc_defer_destroy = (uint32_t)(zc->zc_defer_destroy);
688                 zcmd_c->zc_temphold = 0;
689
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);
696                 FIELD_COPY(zc_stat);
697 #undef FIELD_COPY
698
699                 break;
700
701         case ZFS_CMD_COMPAT_DEADMAN:
702                 zcdm_c = (void *)addr;
703
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);
707
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);
754 #undef FIELD_COPY
755 #ifndef _KERNEL
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);
760 #endif
761                 break;
762
763         case ZFS_CMD_COMPAT_V28:
764                 zc28_c = (void *)addr;
765
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;
797 #ifndef _KERNEL
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);
802 #endif
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;
832                 break;
833
834         case ZFS_CMD_COMPAT_V15:
835                 zc_c = (void *)addr;
836
837                 /* zc */
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;
859
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;
881
882                 break;
883         }
884 }
885
886 static int
887 zfs_ioctl_compat_get_nvlist(uint64_t nvl, size_t size, int iflag,
888     nvlist_t **nvp)
889 {
890         char *packed;
891         int error;
892         nvlist_t *list = NULL;
893
894         /*
895          * Read in and unpack the user-supplied nvlist.
896          */
897         if (size == 0)
898                 return (EINVAL);
899
900 #ifdef _KERNEL
901         packed = kmem_alloc(size, KM_SLEEP);
902         if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
903             iflag)) != 0) {
904                 kmem_free(packed, size);
905                 return (error);
906         }
907 #else
908         packed = (void *)(uintptr_t)nvl;
909 #endif
910
911         error = nvlist_unpack(packed, size, &list, 0);
912
913 #ifdef _KERNEL
914         kmem_free(packed, size);
915 #endif
916
917         if (error != 0)
918                 return (error);
919
920         *nvp = list;
921         return (0);
922 }
923
924 static int
925 zfs_ioctl_compat_put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
926 {
927         char *packed = NULL;
928         int error = 0;
929         size_t size;
930
931         VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0);
932
933 #ifdef _KERNEL
934         packed = kmem_alloc(size, KM_SLEEP);
935         VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
936             KM_SLEEP) == 0);
937
938         if (ddi_copyout(packed,
939             (void *)(uintptr_t)zc->zc_nvlist_dst, size, zc->zc_iflags) != 0)
940                 error = EFAULT;
941         kmem_free(packed, size);
942 #else
943         packed = (void *)(uintptr_t)zc->zc_nvlist_dst;
944         VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
945             0) == 0);
946 #endif
947
948         zc->zc_nvlist_dst_size = size;
949         return (error);
950 }
951
952 static void
953 zfs_ioctl_compat_fix_stats_nvlist(nvlist_t *nvl)
954 {
955         nvlist_t **child;
956         nvlist_t *nvroot = NULL;
957         vdev_stat_t *vs;
958         uint_t c, children, nelem;
959
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]);
964                 }
965         }
966
967         if (nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_VDEV_TREE,
968             &nvroot) == 0)
969                 zfs_ioctl_compat_fix_stats_nvlist(nvroot);
970 #ifdef _KERNEL
971         if ((nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_VDEV_STATS,
972 #else
973         if ((nvlist_lookup_uint64_array(nvl, "stats",
974 #endif
975
976             (uint64_t **)&vs, &nelem) == 0)) {
977                 nvlist_add_uint64_array(nvl,
978 #ifdef _KERNEL
979                     "stats",
980 #else
981                     ZPOOL_CONFIG_VDEV_STATS,
982 #endif
983                     (uint64_t *)vs, nelem);
984 #ifdef _KERNEL
985                 nvlist_remove(nvl, ZPOOL_CONFIG_VDEV_STATS,
986 #else
987                 nvlist_remove(nvl, "stats",
988 #endif
989                     DATA_TYPE_UINT64_ARRAY);
990         }
991 }
992
993 static int
994 zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int nc)
995 {
996         nvlist_t *nv, *nvp = NULL;
997         nvpair_t *elem;
998         int error;
999
1000         if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
1001             zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
1002                 return (error);
1003
1004         if (nc == 5) { /* ZFS_IOC_POOL_STATS */
1005                 elem = NULL;
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);
1009                 }
1010                 elem = NULL;
1011         } else
1012                 zfs_ioctl_compat_fix_stats_nvlist(nv);
1013
1014         error = zfs_ioctl_compat_put_nvlist(zc, nv);
1015
1016         nvlist_free(nv);
1017
1018         return (error);
1019 }
1020
1021 static int
1022 zfs_ioctl_compat_pool_get_props(zfs_cmd_t *zc)
1023 {
1024         nvlist_t *nv, *nva = NULL;
1025         int error;
1026
1027         if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
1028             zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
1029                 return (error);
1030
1031 #ifdef _KERNEL
1032         if (nvlist_lookup_nvlist(nv, "allocated", &nva) == 0) {
1033                 nvlist_add_nvlist(nv, "used", nva);
1034                 nvlist_remove(nv, "allocated", DATA_TYPE_NVLIST);
1035         }
1036
1037         if (nvlist_lookup_nvlist(nv, "free", &nva) == 0) {
1038                 nvlist_add_nvlist(nv, "available", nva);
1039                 nvlist_remove(nv, "free", DATA_TYPE_NVLIST);
1040         }
1041 #else
1042         if (nvlist_lookup_nvlist(nv, "used", &nva) == 0) {
1043                 nvlist_add_nvlist(nv, "allocated", nva);
1044                 nvlist_remove(nv, "used", DATA_TYPE_NVLIST);
1045         }
1046
1047         if (nvlist_lookup_nvlist(nv, "available", &nva) == 0) {
1048                 nvlist_add_nvlist(nv, "free", nva);
1049                 nvlist_remove(nv, "available", DATA_TYPE_NVLIST);
1050         }
1051 #endif
1052
1053         error = zfs_ioctl_compat_put_nvlist(zc, nv);
1054
1055         nvlist_free(nv);
1056
1057         return (error);
1058 }
1059
1060 #ifndef _KERNEL
1061 int
1062 zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
1063 {
1064         int nc, ret;
1065         void *zc_c;
1066         unsigned long ncmd;
1067         zfs_iocparm_t zp;
1068
1069         switch (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);
1106                 break;
1107         case ZFS_CMD_COMPAT_V28:
1108                 zc_c = malloc(sizeof(zfs_cmd_v28_t));
1109                 ncmd = _IOWR('Z', request, struct zfs_cmd_v28);
1110                 break;
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);
1115                 break;
1116         default:
1117                 return (EINVAL);
1118         }
1119
1120         if (ZFS_IOCREQ(ncmd) == ZFS_IOC_COMPAT_FAIL)
1121                 return (ENOTSUP);
1122
1123         zfs_cmd_compat_put(zc, (caddr_t)zc_c, request, cflag);
1124
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);
1131         free(zc_c);
1132
1133         if (cflag == ZFS_CMD_COMPAT_V15) {
1134                 switch (nc) {
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);
1140                         break;
1141                 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
1142                         zfs_ioctl_compat_pool_get_props(zc);
1143                         break;
1144                 }
1145         }
1146
1147         return (ret);
1148 }
1149 #else /* _KERNEL */
1150 int
1151 zfs_ioctl_compat_pre(zfs_cmd_t *zc, int *vec, const int cflag)
1152 {
1153         int error = 0;
1154
1155         /* are we creating a clone? */
1156         if (*vec == ZFS_IOC_CREATE && zc->zc_value[0] != '\0')
1157                 *vec = ZFS_IOC_CLONE;
1158
1159         if (cflag == ZFS_CMD_COMPAT_V15) {
1160                 switch (*vec) {
1161
1162                 case 7: /* ZFS_IOC_POOL_SCRUB (v15) */
1163                         zc->zc_cookie = POOL_SCAN_SCRUB;
1164                         break;
1165                 }
1166         }
1167
1168         return (error);
1169 }
1170
1171 void
1172 zfs_ioctl_compat_post(zfs_cmd_t *zc, int vec, const int cflag)
1173 {
1174         if (cflag == ZFS_CMD_COMPAT_V15) {
1175                 switch (vec) {
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);
1180                         break;
1181                 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
1182                         zfs_ioctl_compat_pool_get_props(zc);
1183                         break;
1184                 }
1185         }
1186 }
1187
1188 nvlist_t *
1189 zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec,
1190     const int cflag)
1191 {
1192         nvlist_t *nvl, *tmpnvl, *hnvl;
1193         nvpair_t *elem;
1194         char *poolname, *snapname;
1195         int err;
1196
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)
1200                 goto out;
1201
1202         switch (vec) {
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);
1208                         nvlist_free(innvl);
1209                 }
1210                 return (nvl);
1211         break;
1212         case ZFS_IOC_CLONE:
1213                 nvl = fnvlist_alloc();
1214                 fnvlist_add_string(nvl, "origin", zc->zc_value);
1215                 if (innvl != NULL) {
1216                         fnvlist_add_nvlist(nvl, "props", innvl);
1217                         nvlist_free(innvl);
1218                 }
1219                 return (nvl);
1220         break;
1221         case ZFS_IOC_SNAPSHOT:
1222                 if (innvl == NULL)
1223                         goto out;
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 */
1231                 if (zc->zc_cookie)
1232                         dmu_get_recursive_snaps_nvl(zc->zc_name, zc->zc_value,
1233                             tmpnvl);
1234                 fnvlist_add_nvlist(nvl, "snaps", tmpnvl);
1235                 fnvlist_free(tmpnvl);
1236                 nvlist_free(innvl);
1237                 /* strip dataset part from zc->zc_name */
1238                 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1239                 return (nvl);
1240         break;
1241         case ZFS_IOC_SPACE_SNAPS:
1242                 nvl = fnvlist_alloc();
1243                 fnvlist_add_string(nvl, "firstsnap", zc->zc_value);
1244                 if (innvl != NULL)
1245                         nvlist_free(innvl);
1246                 return (nvl);
1247         break;
1248         case ZFS_IOC_DESTROY_SNAPS:
1249                 if (innvl == NULL && cflag == ZFS_CMD_COMPAT_DEADMAN)
1250                         goto out;
1251                 nvl = fnvlist_alloc();
1252                 if (innvl != NULL) {
1253                         fnvlist_add_nvlist(nvl, "snaps", innvl);
1254                 } else {
1255                         /*
1256                          * We are probably called by even older binaries,
1257                          * allocate and populate nvlist with recursive
1258                          * snapshots
1259                          */
1260                         if (zfs_component_namecheck(zc->zc_value, NULL,
1261                             NULL) == 0) {
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",
1266                                             tmpnvl);
1267                                 nvlist_free(tmpnvl);
1268                         }
1269                 }
1270                 if (innvl != NULL)
1271                         nvlist_free(innvl);
1272                 /* strip dataset part from zc->zc_name */
1273                 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1274                 return (nvl);
1275         break;
1276         case ZFS_IOC_HOLD:
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) {
1286                                 elem = NULL;
1287                                 while ((elem = nvlist_next_nvpair(hnvl,
1288                                     elem)) != NULL) {
1289                                         nvlist_add_string(tmpnvl,
1290                                             nvpair_name(elem), zc->zc_string);
1291                                 }
1292                         }
1293                         nvlist_free(hnvl);
1294                 } else {
1295                         snapname = kmem_asprintf("%s@%s", zc->zc_name,
1296                             zc->zc_value);
1297                         nvlist_add_string(tmpnvl, snapname, zc->zc_string);
1298                         kmem_free(snapname, strlen(snapname + 1));
1299                 }
1300                 fnvlist_add_nvlist(nvl, "holds", tmpnvl);
1301                 nvlist_free(tmpnvl);
1302                 if (innvl != NULL)
1303                         nvlist_free(innvl);
1304                 /* strip dataset part from zc->zc_name */
1305                 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1306                 return (nvl);
1307         break;
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) {
1315                                 elem = NULL;
1316                                 while ((elem = nvlist_next_nvpair(hnvl,
1317                                     elem)) != NULL) {
1318                                         fnvlist_add_boolean(tmpnvl,
1319                                             zc->zc_string);
1320                                         fnvlist_add_nvlist(nvl,
1321                                             nvpair_name(elem), tmpnvl);
1322                                 }
1323                         }
1324                         nvlist_free(hnvl);
1325                 } else {
1326                         snapname = kmem_asprintf("%s@%s", zc->zc_name,
1327                             zc->zc_value);
1328                         fnvlist_add_boolean(tmpnvl, zc->zc_string);
1329                         fnvlist_add_nvlist(nvl, snapname, tmpnvl);
1330                         kmem_free(snapname, strlen(snapname + 1));
1331                 }
1332                 nvlist_free(tmpnvl);
1333                 if (innvl != NULL)
1334                         nvlist_free(innvl);
1335                 /* strip dataset part from zc->zc_name */
1336                 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
1337                 return (nvl);
1338         break;
1339         }
1340 out:
1341         return (innvl);
1342 }
1343
1344 nvlist_t *
1345 zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec,
1346     const int cflag)
1347 {
1348         nvlist_t *tmpnvl;
1349
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)
1353                 return (outnvl);
1354
1355         switch (vec) {
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();
1365                 return (tmpnvl);
1366         break;
1367         case ZFS_IOC_CREATE:
1368         case ZFS_IOC_CLONE:
1369         case ZFS_IOC_HOLD:
1370         case ZFS_IOC_RELEASE:
1371                 nvlist_free(outnvl);
1372                 /* return empty outnvl */
1373                 tmpnvl = fnvlist_alloc();
1374                 return (tmpnvl);
1375         break;
1376         }
1377
1378         return (outnvl);
1379 }
1380 #endif /* KERNEL */