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
zfs_cmd_compat_get(zfs_cmd_t * zc,caddr_t addr,const int cflag)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                         zcdm_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
zfs_cmd_compat_put(zfs_cmd_t * zc,caddr_t addr,const int request,const int cflag)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(edbp_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(zcmd_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(zcdm_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
zfs_ioctl_compat_get_nvlist(uint64_t nvl,size_t size,int iflag,nvlist_t ** nvp)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
zfs_ioctl_compat_put_nvlist(zfs_cmd_t * zc,nvlist_t * nvl)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
zfs_ioctl_compat_fix_stats_nvlist(nvlist_t * nvl)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
zfs_ioctl_compat_fix_stats(zfs_cmd_t * zc,const int nc)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
zfs_ioctl_compat_pool_get_props(zfs_cmd_t * zc)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
zcmd_ioctl_compat(int fd,int request,zfs_cmd_t * zc,const int cflag)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
zfs_ioctl_compat_pre(zfs_cmd_t * zc,int * vec,const int cflag)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
zfs_ioctl_compat_post(zfs_cmd_t * zc,int vec,const int cflag)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 *
zfs_ioctl_compat_innvl(zfs_cmd_t * zc,nvlist_t * innvl,const int vec,const int cflag)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 *
zfs_ioctl_compat_outnvl(zfs_cmd_t * zc,nvlist_t * outnvl,const int vec,const int cflag)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 */
1381