Home | History | Annotate | Line # | Download | only in zfs
      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 (at) FreeBSD.org>. All rights reserved.
     23  * Copyright 2013 Martin Matuska <mm (at) 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/ioctl.h>
     33 #include <sys/dmu.h>
     34 #include <sys/zio.h>
     35 #include <sys/nvpair.h>
     36 #include <sys/dsl_deleg.h>
     37 #include <sys/zfs_ioctl.h>
     38 #include "zfs_namecheck.h"
     39 #include "zfs_ioctl_compat.h"
     40 
     41 static int zfs_version_ioctl = ZFS_IOCVER_CURRENT;
     42 SYSCTL_DECL(_vfs_zfs_version);
     43 SYSCTL_INT(_vfs_zfs_version, OID_AUTO, ioctl, CTLFLAG_RD, &zfs_version_ioctl,
     44     0, "ZFS_IOCTL_VERSION");
     45 
     46 /*
     47  * FreeBSD zfs_cmd compatibility with older binaries
     48  * appropriately remap/extend the zfs_cmd_t structure
     49  */
     50 void
     51 zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag)
     52 {
     53 	zfs_cmd_v15_t *zc_c;
     54 	zfs_cmd_v28_t *zc28_c;
     55 	zfs_cmd_deadman_t *zcdm_c;
     56 	zfs_cmd_zcmd_t *zcmd_c;
     57 	zfs_cmd_edbp_t *edbp_c;
     58 	zfs_cmd_resume_t *resume_c;
     59 	zfs_cmd_inlanes_t *inlanes_c;
     60 
     61 	switch (cflag) {
     62 	case ZFS_CMD_COMPAT_INLANES:
     63 		inlanes_c = (void *)addr;
     64 		/* zc */
     65 		strlcpy(zc->zc_name, inlanes_c->zc_name, MAXPATHLEN);
     66 		strlcpy(zc->zc_value, inlanes_c->zc_value, MAXPATHLEN * 2);
     67 		strlcpy(zc->zc_string, inlanes_c->zc_string, MAXPATHLEN);
     68 
     69 #define FIELD_COPY(field) zc->field = inlanes_c->field
     70 		FIELD_COPY(zc_nvlist_src);
     71 		FIELD_COPY(zc_nvlist_src_size);
     72 		FIELD_COPY(zc_nvlist_dst);
     73 		FIELD_COPY(zc_nvlist_dst_size);
     74 		FIELD_COPY(zc_nvlist_dst_filled);
     75 		FIELD_COPY(zc_pad2);
     76 		FIELD_COPY(zc_history);
     77 		FIELD_COPY(zc_guid);
     78 		FIELD_COPY(zc_nvlist_conf);
     79 		FIELD_COPY(zc_nvlist_conf_size);
     80 		FIELD_COPY(zc_cookie);
     81 		FIELD_COPY(zc_objset_type);
     82 		FIELD_COPY(zc_perm_action);
     83 		FIELD_COPY(zc_history_len);
     84 		FIELD_COPY(zc_history_offset);
     85 		FIELD_COPY(zc_obj);
     86 		FIELD_COPY(zc_iflags);
     87 		FIELD_COPY(zc_share);
     88 		FIELD_COPY(zc_jailid);
     89 		FIELD_COPY(zc_objset_stats);
     90 		FIELD_COPY(zc_begin_record);
     91 		FIELD_COPY(zc_inject_record);
     92 		FIELD_COPY(zc_defer_destroy);
     93 		FIELD_COPY(zc_flags);
     94 		FIELD_COPY(zc_action_handle);
     95 		FIELD_COPY(zc_cleanup_fd);
     96 		FIELD_COPY(zc_simple);
     97 		FIELD_COPY(zc_resumable);
     98 		FIELD_COPY(zc_sendobj);
     99 		FIELD_COPY(zc_fromobj);
    100 		FIELD_COPY(zc_createtxg);
    101 		FIELD_COPY(zc_stat);
    102 #undef FIELD_COPY
    103 		break;
    104 
    105 	case ZFS_CMD_COMPAT_RESUME:
    106 		resume_c = (void *)addr;
    107 		/* zc */
    108 		strlcpy(zc->zc_name, resume_c->zc_name, MAXPATHLEN);
    109 		strlcpy(zc->zc_value, resume_c->zc_value, MAXPATHLEN * 2);
    110 		strlcpy(zc->zc_string, resume_c->zc_string, MAXPATHLEN);
    111 
    112 #define FIELD_COPY(field) zc->field = resume_c->field
    113 		FIELD_COPY(zc_nvlist_src);
    114 		FIELD_COPY(zc_nvlist_src_size);
    115 		FIELD_COPY(zc_nvlist_dst);
    116 		FIELD_COPY(zc_nvlist_dst_size);
    117 		FIELD_COPY(zc_nvlist_dst_filled);
    118 		FIELD_COPY(zc_pad2);
    119 		FIELD_COPY(zc_history);
    120 		FIELD_COPY(zc_guid);
    121 		FIELD_COPY(zc_nvlist_conf);
    122 		FIELD_COPY(zc_nvlist_conf_size);
    123 		FIELD_COPY(zc_cookie);
    124 		FIELD_COPY(zc_objset_type);
    125 		FIELD_COPY(zc_perm_action);
    126 		FIELD_COPY(zc_history_len);
    127 		FIELD_COPY(zc_history_offset);
    128 		FIELD_COPY(zc_obj);
    129 		FIELD_COPY(zc_iflags);
    130 		FIELD_COPY(zc_share);
    131 		FIELD_COPY(zc_jailid);
    132 		FIELD_COPY(zc_objset_stats);
    133 		FIELD_COPY(zc_begin_record);
    134 		FIELD_COPY(zc_inject_record.zi_objset);
    135 		FIELD_COPY(zc_inject_record.zi_object);
    136 		FIELD_COPY(zc_inject_record.zi_start);
    137 		FIELD_COPY(zc_inject_record.zi_end);
    138 		FIELD_COPY(zc_inject_record.zi_guid);
    139 		FIELD_COPY(zc_inject_record.zi_level);
    140 		FIELD_COPY(zc_inject_record.zi_error);
    141 		FIELD_COPY(zc_inject_record.zi_type);
    142 		FIELD_COPY(zc_inject_record.zi_freq);
    143 		FIELD_COPY(zc_inject_record.zi_failfast);
    144 		strlcpy(zc->zc_inject_record.zi_func,
    145 		    resume_c->zc_inject_record.zi_func, MAXNAMELEN);
    146 		FIELD_COPY(zc_inject_record.zi_iotype);
    147 		FIELD_COPY(zc_inject_record.zi_duration);
    148 		FIELD_COPY(zc_inject_record.zi_timer);
    149 		zc->zc_inject_record.zi_nlanes = 1;
    150 		FIELD_COPY(zc_inject_record.zi_cmd);
    151 		FIELD_COPY(zc_inject_record.zi_pad);
    152 		FIELD_COPY(zc_defer_destroy);
    153 		FIELD_COPY(zc_flags);
    154 		FIELD_COPY(zc_action_handle);
    155 		FIELD_COPY(zc_cleanup_fd);
    156 		FIELD_COPY(zc_simple);
    157 		FIELD_COPY(zc_resumable);
    158 		FIELD_COPY(zc_sendobj);
    159 		FIELD_COPY(zc_fromobj);
    160 		FIELD_COPY(zc_createtxg);
    161 		FIELD_COPY(zc_stat);
    162 #undef FIELD_COPY
    163 		break;
    164 
    165 	case ZFS_CMD_COMPAT_EDBP:
    166 		edbp_c = (void *)addr;
    167 		/* zc */
    168 		strlcpy(zc->zc_name, edbp_c->zc_name, MAXPATHLEN);
    169 		strlcpy(zc->zc_value, edbp_c->zc_value, MAXPATHLEN * 2);
    170 		strlcpy(zc->zc_string, edbp_c->zc_string, MAXPATHLEN);
    171 
    172 #define FIELD_COPY(field) zc->field = edbp_c->field
    173 		FIELD_COPY(zc_nvlist_src);
    174 		FIELD_COPY(zc_nvlist_src_size);
    175 		FIELD_COPY(zc_nvlist_dst);
    176 		FIELD_COPY(zc_nvlist_dst_size);
    177 		FIELD_COPY(zc_nvlist_dst_filled);
    178 		FIELD_COPY(zc_pad2);
    179 		FIELD_COPY(zc_history);
    180 		FIELD_COPY(zc_guid);
    181 		FIELD_COPY(zc_nvlist_conf);
    182 		FIELD_COPY(zc_nvlist_conf_size);
    183 		FIELD_COPY(zc_cookie);
    184 		FIELD_COPY(zc_objset_type);
    185 		FIELD_COPY(zc_perm_action);
    186 		FIELD_COPY(zc_history_len);
    187 		FIELD_COPY(zc_history_offset);
    188 		FIELD_COPY(zc_obj);
    189 		FIELD_COPY(zc_iflags);
    190 		FIELD_COPY(zc_share);
    191 		FIELD_COPY(zc_jailid);
    192 		FIELD_COPY(zc_objset_stats);
    193 		zc->zc_begin_record.drr_u.drr_begin = edbp_c->zc_begin_record;
    194 		FIELD_COPY(zc_inject_record.zi_objset);
    195 		FIELD_COPY(zc_inject_record.zi_object);
    196 		FIELD_COPY(zc_inject_record.zi_start);
    197 		FIELD_COPY(zc_inject_record.zi_end);
    198 		FIELD_COPY(zc_inject_record.zi_guid);
    199 		FIELD_COPY(zc_inject_record.zi_level);
    200 		FIELD_COPY(zc_inject_record.zi_error);
    201 		FIELD_COPY(zc_inject_record.zi_type);
    202 		FIELD_COPY(zc_inject_record.zi_freq);
    203 		FIELD_COPY(zc_inject_record.zi_failfast);
    204 		strlcpy(zc->zc_inject_record.zi_func,
    205 		    edbp_c->zc_inject_record.zi_func, MAXNAMELEN);
    206 		FIELD_COPY(zc_inject_record.zi_iotype);
    207 		FIELD_COPY(zc_inject_record.zi_duration);
    208 		FIELD_COPY(zc_inject_record.zi_timer);
    209 		zc->zc_inject_record.zi_nlanes = 1;
    210 		FIELD_COPY(zc_inject_record.zi_cmd);
    211 		FIELD_COPY(zc_inject_record.zi_pad);
    212 		FIELD_COPY(zc_defer_destroy);
    213 		FIELD_COPY(zc_flags);
    214 		FIELD_COPY(zc_action_handle);
    215 		FIELD_COPY(zc_cleanup_fd);
    216 		FIELD_COPY(zc_simple);
    217 		zc->zc_resumable = B_FALSE;
    218 		FIELD_COPY(zc_sendobj);
    219 		FIELD_COPY(zc_fromobj);
    220 		FIELD_COPY(zc_createtxg);
    221 		FIELD_COPY(zc_stat);
    222 #undef FIELD_COPY
    223 		break;
    224 
    225 	case ZFS_CMD_COMPAT_ZCMD:
    226 		zcmd_c = (void *)addr;
    227 		/* zc */
    228 		strlcpy(zc->zc_name, zcmd_c->zc_name, MAXPATHLEN);
    229 		strlcpy(zc->zc_value, zcmd_c->zc_value, MAXPATHLEN * 2);
    230 		strlcpy(zc->zc_string, zcmd_c->zc_string, MAXPATHLEN);
    231 
    232 #define FIELD_COPY(field) zc->field = zcmd_c->field
    233 		FIELD_COPY(zc_nvlist_src);
    234 		FIELD_COPY(zc_nvlist_src_size);
    235 		FIELD_COPY(zc_nvlist_dst);
    236 		FIELD_COPY(zc_nvlist_dst_size);
    237 		FIELD_COPY(zc_nvlist_dst_filled);
    238 		FIELD_COPY(zc_pad2);
    239 		FIELD_COPY(zc_history);
    240 		FIELD_COPY(zc_guid);
    241 		FIELD_COPY(zc_nvlist_conf);
    242 		FIELD_COPY(zc_nvlist_conf_size);
    243 		FIELD_COPY(zc_cookie);
    244 		FIELD_COPY(zc_objset_type);
    245 		FIELD_COPY(zc_perm_action);
    246 		FIELD_COPY(zc_history_len);
    247 		FIELD_COPY(zc_history_offset);
    248 		FIELD_COPY(zc_obj);
    249 		FIELD_COPY(zc_iflags);
    250 		FIELD_COPY(zc_share);
    251 		FIELD_COPY(zc_jailid);
    252 		FIELD_COPY(zc_objset_stats);
    253 		zc->zc_begin_record.drr_u.drr_begin = zcmd_c->zc_begin_record;
    254 		FIELD_COPY(zc_inject_record.zi_objset);
    255 		FIELD_COPY(zc_inject_record.zi_object);
    256 		FIELD_COPY(zc_inject_record.zi_start);
    257 		FIELD_COPY(zc_inject_record.zi_end);
    258 		FIELD_COPY(zc_inject_record.zi_guid);
    259 		FIELD_COPY(zc_inject_record.zi_level);
    260 		FIELD_COPY(zc_inject_record.zi_error);
    261 		FIELD_COPY(zc_inject_record.zi_type);
    262 		FIELD_COPY(zc_inject_record.zi_freq);
    263 		FIELD_COPY(zc_inject_record.zi_failfast);
    264 		strlcpy(zc->zc_inject_record.zi_func,
    265 		    zcmd_c->zc_inject_record.zi_func, MAXNAMELEN);
    266 		FIELD_COPY(zc_inject_record.zi_iotype);
    267 		FIELD_COPY(zc_inject_record.zi_duration);
    268 		FIELD_COPY(zc_inject_record.zi_timer);
    269 		zc->zc_inject_record.zi_nlanes = 1;
    270 		FIELD_COPY(zc_inject_record.zi_cmd);
    271 		FIELD_COPY(zc_inject_record.zi_pad);
    272 
    273 		/* boolean_t -> uint32_t */
    274 		zc->zc_defer_destroy = (uint32_t)(zcmd_c->zc_defer_destroy);
    275 		zc->zc_flags = 0;
    276 
    277 		FIELD_COPY(zc_action_handle);
    278 		FIELD_COPY(zc_cleanup_fd);
    279 		FIELD_COPY(zc_simple);
    280 		zc->zc_resumable = B_FALSE;
    281 		FIELD_COPY(zc_sendobj);
    282 		FIELD_COPY(zc_fromobj);
    283 		FIELD_COPY(zc_createtxg);
    284 		FIELD_COPY(zc_stat);
    285 #undef FIELD_COPY
    286 
    287 		break;
    288 
    289 	case ZFS_CMD_COMPAT_DEADMAN:
    290 		zcdm_c = (void *)addr;
    291 		/* zc */
    292 		strlcpy(zc->zc_name, zcdm_c->zc_name, MAXPATHLEN);
    293 		strlcpy(zc->zc_value, zcdm_c->zc_value, MAXPATHLEN * 2);
    294 		strlcpy(zc->zc_string, zcdm_c->zc_string, MAXPATHLEN);
    295 
    296 #define FIELD_COPY(field) zc->field = zcdm_c->field
    297 		zc->zc_guid = zcdm_c->zc_guid;
    298 		zc->zc_nvlist_conf = zcdm_c->zc_nvlist_conf;
    299 		zc->zc_nvlist_conf_size = zcdm_c->zc_nvlist_conf_size;
    300 		zc->zc_nvlist_src = zcdm_c->zc_nvlist_src;
    301 		zc->zc_nvlist_src_size = zcdm_c->zc_nvlist_src_size;
    302 		zc->zc_nvlist_dst = zcdm_c->zc_nvlist_dst;
    303 		zc->zc_nvlist_dst_size = zcdm_c->zc_nvlist_dst_size;
    304 		zc->zc_cookie = zcdm_c->zc_cookie;
    305 		zc->zc_objset_type = zcdm_c->zc_objset_type;
    306 		zc->zc_perm_action = zcdm_c->zc_perm_action;
    307 		zc->zc_history = zcdm_c->zc_history;
    308 		zc->zc_history_len = zcdm_c->zc_history_len;
    309 		zc->zc_history_offset = zcdm_c->zc_history_offset;
    310 		zc->zc_obj = zcdm_c->zc_obj;
    311 		zc->zc_iflags = zcdm_c->zc_iflags;
    312 		zc->zc_share = zcdm_c->zc_share;
    313 		zc->zc_jailid = zcdm_c->zc_jailid;
    314 		zc->zc_objset_stats = zcdm_c->zc_objset_stats;
    315 		zc->zc_begin_record.drr_u.drr_begin = zcdm_c->zc_begin_record;
    316 		zc->zc_defer_destroy = zcdm_c->zc_defer_destroy;
    317 		(void)zcdm_c->zc_temphold;
    318 		zc->zc_action_handle = zcdm_c->zc_action_handle;
    319 		zc->zc_cleanup_fd = zcdm_c->zc_cleanup_fd;
    320 		zc->zc_simple = zcdm_c->zc_simple;
    321 		zc->zc_resumable = B_FALSE;
    322 		zc->zc_sendobj = zcdm_c->zc_sendobj;
    323 		zc->zc_fromobj = zcdm_c->zc_fromobj;
    324 		zc->zc_createtxg = zcdm_c->zc_createtxg;
    325 		zc->zc_stat = zcdm_c->zc_stat;
    326 		FIELD_COPY(zc_inject_record.zi_objset);
    327 		FIELD_COPY(zc_inject_record.zi_object);
    328 		FIELD_COPY(zc_inject_record.zi_start);
    329 		FIELD_COPY(zc_inject_record.zi_end);
    330 		FIELD_COPY(zc_inject_record.zi_guid);
    331 		FIELD_COPY(zc_inject_record.zi_level);
    332 		FIELD_COPY(zc_inject_record.zi_error);
    333 		FIELD_COPY(zc_inject_record.zi_type);
    334 		FIELD_COPY(zc_inject_record.zi_freq);
    335 		FIELD_COPY(zc_inject_record.zi_failfast);
    336 		strlcpy(zc->zc_inject_record.zi_func,
    337 		    zcdm_c->zc_inject_record.zi_func, MAXNAMELEN);
    338 		FIELD_COPY(zc_inject_record.zi_iotype);
    339 		FIELD_COPY(zc_inject_record.zi_duration);
    340 		FIELD_COPY(zc_inject_record.zi_timer);
    341 		zc->zc_inject_record.zi_nlanes = 1;
    342 		FIELD_COPY(zc_inject_record.zi_cmd);
    343 		FIELD_COPY(zc_inject_record.zi_pad);
    344 
    345 		/* we always assume zc_nvlist_dst_filled is true */
    346 		zc->zc_nvlist_dst_filled = B_TRUE;
    347 #undef FIELD_COPY
    348 		break;
    349 
    350 	case ZFS_CMD_COMPAT_V28:
    351 		zc28_c = (void *)addr;
    352 
    353 		/* zc */
    354 		strlcpy(zc->zc_name, zc28_c->zc_name, MAXPATHLEN);
    355 		strlcpy(zc->zc_value, zc28_c->zc_value, MAXPATHLEN * 2);
    356 		strlcpy(zc->zc_string, zc28_c->zc_string, MAXPATHLEN);
    357 		zc->zc_guid = zc28_c->zc_guid;
    358 		zc->zc_nvlist_conf = zc28_c->zc_nvlist_conf;
    359 		zc->zc_nvlist_conf_size = zc28_c->zc_nvlist_conf_size;
    360 		zc->zc_nvlist_src = zc28_c->zc_nvlist_src;
    361 		zc->zc_nvlist_src_size = zc28_c->zc_nvlist_src_size;
    362 		zc->zc_nvlist_dst = zc28_c->zc_nvlist_dst;
    363 		zc->zc_nvlist_dst_size = zc28_c->zc_nvlist_dst_size;
    364 		zc->zc_cookie = zc28_c->zc_cookie;
    365 		zc->zc_objset_type = zc28_c->zc_objset_type;
    366 		zc->zc_perm_action = zc28_c->zc_perm_action;
    367 		zc->zc_history = zc28_c->zc_history;
    368 		zc->zc_history_len = zc28_c->zc_history_len;
    369 		zc->zc_history_offset = zc28_c->zc_history_offset;
    370 		zc->zc_obj = zc28_c->zc_obj;
    371 		zc->zc_iflags = zc28_c->zc_iflags;
    372 		zc->zc_share = zc28_c->zc_share;
    373 		zc->zc_jailid = zc28_c->zc_jailid;
    374 		zc->zc_objset_stats = zc28_c->zc_objset_stats;
    375 		zc->zc_begin_record.drr_u.drr_begin = zc28_c->zc_begin_record;
    376 		zc->zc_defer_destroy = zc28_c->zc_defer_destroy;
    377 		(void)zc28_c->zc_temphold;
    378 		zc->zc_action_handle = zc28_c->zc_action_handle;
    379 		zc->zc_cleanup_fd = zc28_c->zc_cleanup_fd;
    380 		zc->zc_simple = zc28_c->zc_simple;
    381 		zc->zc_resumable = B_FALSE;
    382 		zc->zc_sendobj = zc28_c->zc_sendobj;
    383 		zc->zc_fromobj = zc28_c->zc_fromobj;
    384 		zc->zc_createtxg = zc28_c->zc_createtxg;
    385 		zc->zc_stat = zc28_c->zc_stat;
    386 
    387 		/* zc->zc_inject_record */
    388 		zc->zc_inject_record.zi_objset =
    389 		    zc28_c->zc_inject_record.zi_objset;
    390 		zc->zc_inject_record.zi_object =
    391 		    zc28_c->zc_inject_record.zi_object;
    392 		zc->zc_inject_record.zi_start =
    393 		    zc28_c->zc_inject_record.zi_start;
    394 		zc->zc_inject_record.zi_end =
    395 		    zc28_c->zc_inject_record.zi_end;
    396 		zc->zc_inject_record.zi_guid =
    397 		    zc28_c->zc_inject_record.zi_guid;
    398 		zc->zc_inject_record.zi_level =
    399 		    zc28_c->zc_inject_record.zi_level;
    400 		zc->zc_inject_record.zi_error =
    401 		    zc28_c->zc_inject_record.zi_error;
    402 		zc->zc_inject_record.zi_type =
    403 		    zc28_c->zc_inject_record.zi_type;
    404 		zc->zc_inject_record.zi_freq =
    405 		    zc28_c->zc_inject_record.zi_freq;
    406 		zc->zc_inject_record.zi_failfast =
    407 		    zc28_c->zc_inject_record.zi_failfast;
    408 		strlcpy(zc->zc_inject_record.zi_func,
    409 		    zc28_c->zc_inject_record.zi_func, MAXNAMELEN);
    410 		zc->zc_inject_record.zi_iotype =
    411 		    zc28_c->zc_inject_record.zi_iotype;
    412 		zc->zc_inject_record.zi_duration =
    413 		    zc28_c->zc_inject_record.zi_duration;
    414 		zc->zc_inject_record.zi_timer =
    415 		    zc28_c->zc_inject_record.zi_timer;
    416 		zc->zc_inject_record.zi_nlanes = 1;
    417 		zc->zc_inject_record.zi_cmd = ZINJECT_UNINITIALIZED;
    418 		zc->zc_inject_record.zi_pad = 0;
    419 		break;
    420 
    421 	case ZFS_CMD_COMPAT_V15:
    422 		zc_c = (void *)addr;
    423 
    424 		/* zc */
    425 		strlcpy(zc->zc_name, zc_c->zc_name, MAXPATHLEN);
    426 		strlcpy(zc->zc_value, zc_c->zc_value, MAXPATHLEN);
    427 		strlcpy(zc->zc_string, zc_c->zc_string, MAXPATHLEN);
    428 		zc->zc_guid = zc_c->zc_guid;
    429 		zc->zc_nvlist_conf = zc_c->zc_nvlist_conf;
    430 		zc->zc_nvlist_conf_size = zc_c->zc_nvlist_conf_size;
    431 		zc->zc_nvlist_src = zc_c->zc_nvlist_src;
    432 		zc->zc_nvlist_src_size = zc_c->zc_nvlist_src_size;
    433 		zc->zc_nvlist_dst = zc_c->zc_nvlist_dst;
    434 		zc->zc_nvlist_dst_size = zc_c->zc_nvlist_dst_size;
    435 		zc->zc_cookie = zc_c->zc_cookie;
    436 		zc->zc_objset_type = zc_c->zc_objset_type;
    437 		zc->zc_perm_action = zc_c->zc_perm_action;
    438 		zc->zc_history = zc_c->zc_history;
    439 		zc->zc_history_len = zc_c->zc_history_len;
    440 		zc->zc_history_offset = zc_c->zc_history_offset;
    441 		zc->zc_obj = zc_c->zc_obj;
    442 		zc->zc_share = zc_c->zc_share;
    443 		zc->zc_jailid = zc_c->zc_jailid;
    444 		zc->zc_objset_stats = zc_c->zc_objset_stats;
    445 		zc->zc_begin_record.drr_u.drr_begin = zc_c->zc_begin_record;
    446 
    447 		/* zc->zc_inject_record */
    448 		zc->zc_inject_record.zi_objset =
    449 		    zc_c->zc_inject_record.zi_objset;
    450 		zc->zc_inject_record.zi_object =
    451 		    zc_c->zc_inject_record.zi_object;
    452 		zc->zc_inject_record.zi_start =
    453 		    zc_c->zc_inject_record.zi_start;
    454 		zc->zc_inject_record.zi_end =
    455 		    zc_c->zc_inject_record.zi_end;
    456 		zc->zc_inject_record.zi_guid =
    457 		    zc_c->zc_inject_record.zi_guid;
    458 		zc->zc_inject_record.zi_level =
    459 		    zc_c->zc_inject_record.zi_level;
    460 		zc->zc_inject_record.zi_error =
    461 		    zc_c->zc_inject_record.zi_error;
    462 		zc->zc_inject_record.zi_type =
    463 		    zc_c->zc_inject_record.zi_type;
    464 		zc->zc_inject_record.zi_freq =
    465 		    zc_c->zc_inject_record.zi_freq;
    466 		zc->zc_inject_record.zi_failfast =
    467 		    zc_c->zc_inject_record.zi_failfast;
    468 		break;
    469 	}
    470 }
    471 
    472 void
    473 zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request,
    474     const int cflag)
    475 {
    476 	zfs_cmd_v15_t *zc_c;
    477 	zfs_cmd_v28_t *zc28_c;
    478 	zfs_cmd_deadman_t *zcdm_c;
    479 	zfs_cmd_zcmd_t *zcmd_c;
    480 	zfs_cmd_edbp_t *edbp_c;
    481 	zfs_cmd_resume_t *resume_c;
    482 	zfs_cmd_inlanes_t *inlanes_c;
    483 
    484 	switch (cflag) {
    485 	case ZFS_CMD_COMPAT_INLANES:
    486 		inlanes_c = (void *)addr;
    487 		strlcpy(inlanes_c->zc_name, zc->zc_name, MAXPATHLEN);
    488 		strlcpy(inlanes_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
    489 		strlcpy(inlanes_c->zc_string, zc->zc_string, MAXPATHLEN);
    490 
    491 #define FIELD_COPY(field) inlanes_c->field = zc->field
    492 		FIELD_COPY(zc_nvlist_src);
    493 		FIELD_COPY(zc_nvlist_src_size);
    494 		FIELD_COPY(zc_nvlist_dst);
    495 		FIELD_COPY(zc_nvlist_dst_size);
    496 		FIELD_COPY(zc_nvlist_dst_filled);
    497 		FIELD_COPY(zc_pad2);
    498 		FIELD_COPY(zc_history);
    499 		FIELD_COPY(zc_guid);
    500 		FIELD_COPY(zc_nvlist_conf);
    501 		FIELD_COPY(zc_nvlist_conf_size);
    502 		FIELD_COPY(zc_cookie);
    503 		FIELD_COPY(zc_objset_type);
    504 		FIELD_COPY(zc_perm_action);
    505 		FIELD_COPY(zc_history_len);
    506 		FIELD_COPY(zc_history_offset);
    507 		FIELD_COPY(zc_obj);
    508 		FIELD_COPY(zc_iflags);
    509 		FIELD_COPY(zc_share);
    510 		FIELD_COPY(zc_jailid);
    511 		FIELD_COPY(zc_objset_stats);
    512 		FIELD_COPY(zc_begin_record);
    513 		FIELD_COPY(zc_inject_record);
    514 		FIELD_COPY(zc_defer_destroy);
    515 		FIELD_COPY(zc_flags);
    516 		FIELD_COPY(zc_action_handle);
    517 		FIELD_COPY(zc_cleanup_fd);
    518 		FIELD_COPY(zc_simple);
    519 		FIELD_COPY(zc_sendobj);
    520 		FIELD_COPY(zc_fromobj);
    521 		FIELD_COPY(zc_createtxg);
    522 		FIELD_COPY(zc_stat);
    523 #undef FIELD_COPY
    524 		break;
    525 
    526 	case ZFS_CMD_COMPAT_RESUME:
    527 		resume_c = (void *)addr;
    528 		strlcpy(resume_c->zc_name, zc->zc_name, MAXPATHLEN);
    529 		strlcpy(resume_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
    530 		strlcpy(resume_c->zc_string, zc->zc_string, MAXPATHLEN);
    531 
    532 #define FIELD_COPY(field) resume_c->field = zc->field
    533 		FIELD_COPY(zc_nvlist_src);
    534 		FIELD_COPY(zc_nvlist_src_size);
    535 		FIELD_COPY(zc_nvlist_dst);
    536 		FIELD_COPY(zc_nvlist_dst_size);
    537 		FIELD_COPY(zc_nvlist_dst_filled);
    538 		FIELD_COPY(zc_pad2);
    539 		FIELD_COPY(zc_history);
    540 		FIELD_COPY(zc_guid);
    541 		FIELD_COPY(zc_nvlist_conf);
    542 		FIELD_COPY(zc_nvlist_conf_size);
    543 		FIELD_COPY(zc_cookie);
    544 		FIELD_COPY(zc_objset_type);
    545 		FIELD_COPY(zc_perm_action);
    546 		FIELD_COPY(zc_history_len);
    547 		FIELD_COPY(zc_history_offset);
    548 		FIELD_COPY(zc_obj);
    549 		FIELD_COPY(zc_iflags);
    550 		FIELD_COPY(zc_share);
    551 		FIELD_COPY(zc_jailid);
    552 		FIELD_COPY(zc_objset_stats);
    553 		FIELD_COPY(zc_begin_record);
    554 		FIELD_COPY(zc_inject_record.zi_objset);
    555 		FIELD_COPY(zc_inject_record.zi_object);
    556 		FIELD_COPY(zc_inject_record.zi_start);
    557 		FIELD_COPY(zc_inject_record.zi_end);
    558 		FIELD_COPY(zc_inject_record.zi_guid);
    559 		FIELD_COPY(zc_inject_record.zi_level);
    560 		FIELD_COPY(zc_inject_record.zi_error);
    561 		FIELD_COPY(zc_inject_record.zi_type);
    562 		FIELD_COPY(zc_inject_record.zi_freq);
    563 		FIELD_COPY(zc_inject_record.zi_failfast);
    564 		strlcpy(resume_c->zc_inject_record.zi_func,
    565 		    zc->zc_inject_record.zi_func, MAXNAMELEN);
    566 		FIELD_COPY(zc_inject_record.zi_iotype);
    567 		FIELD_COPY(zc_inject_record.zi_duration);
    568 		FIELD_COPY(zc_inject_record.zi_timer);
    569 		FIELD_COPY(zc_inject_record.zi_cmd);
    570 		FIELD_COPY(zc_inject_record.zi_pad);
    571 		FIELD_COPY(zc_defer_destroy);
    572 		FIELD_COPY(zc_flags);
    573 		FIELD_COPY(zc_action_handle);
    574 		FIELD_COPY(zc_cleanup_fd);
    575 		FIELD_COPY(zc_simple);
    576 		FIELD_COPY(zc_sendobj);
    577 		FIELD_COPY(zc_fromobj);
    578 		FIELD_COPY(zc_createtxg);
    579 		FIELD_COPY(zc_stat);
    580 #undef FIELD_COPY
    581 		break;
    582 
    583 	case ZFS_CMD_COMPAT_EDBP:
    584 		edbp_c = (void *)addr;
    585 		strlcpy(edbp_c->zc_name, zc->zc_name, MAXPATHLEN);
    586 		strlcpy(edbp_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
    587 		strlcpy(edbp_c->zc_string, zc->zc_string, MAXPATHLEN);
    588 
    589 #define FIELD_COPY(field) edbp_c->field = zc->field
    590 		FIELD_COPY(zc_nvlist_src);
    591 		FIELD_COPY(zc_nvlist_src_size);
    592 		FIELD_COPY(zc_nvlist_dst);
    593 		FIELD_COPY(zc_nvlist_dst_size);
    594 		FIELD_COPY(zc_nvlist_dst_filled);
    595 		FIELD_COPY(zc_pad2);
    596 		FIELD_COPY(zc_history);
    597 		FIELD_COPY(zc_guid);
    598 		FIELD_COPY(zc_nvlist_conf);
    599 		FIELD_COPY(zc_nvlist_conf_size);
    600 		FIELD_COPY(zc_cookie);
    601 		FIELD_COPY(zc_objset_type);
    602 		FIELD_COPY(zc_perm_action);
    603 		FIELD_COPY(zc_history_len);
    604 		FIELD_COPY(zc_history_offset);
    605 		FIELD_COPY(zc_obj);
    606 		FIELD_COPY(zc_iflags);
    607 		FIELD_COPY(zc_share);
    608 		FIELD_COPY(zc_jailid);
    609 		FIELD_COPY(zc_objset_stats);
    610 		edbp_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
    611 		FIELD_COPY(zc_inject_record.zi_objset);
    612 		FIELD_COPY(zc_inject_record.zi_object);
    613 		FIELD_COPY(zc_inject_record.zi_start);
    614 		FIELD_COPY(zc_inject_record.zi_end);
    615 		FIELD_COPY(zc_inject_record.zi_guid);
    616 		FIELD_COPY(zc_inject_record.zi_level);
    617 		FIELD_COPY(zc_inject_record.zi_error);
    618 		FIELD_COPY(zc_inject_record.zi_type);
    619 		FIELD_COPY(zc_inject_record.zi_freq);
    620 		FIELD_COPY(zc_inject_record.zi_failfast);
    621 		strlcpy(edbp_c->zc_inject_record.zi_func,
    622 		    zc->zc_inject_record.zi_func, MAXNAMELEN);
    623 		FIELD_COPY(zc_inject_record.zi_iotype);
    624 		FIELD_COPY(zc_inject_record.zi_duration);
    625 		FIELD_COPY(zc_inject_record.zi_timer);
    626 		FIELD_COPY(zc_inject_record.zi_cmd);
    627 		FIELD_COPY(zc_inject_record.zi_pad);
    628 		FIELD_COPY(zc_defer_destroy);
    629 		FIELD_COPY(zc_flags);
    630 		FIELD_COPY(zc_action_handle);
    631 		FIELD_COPY(zc_cleanup_fd);
    632 		FIELD_COPY(zc_simple);
    633 		FIELD_COPY(zc_sendobj);
    634 		FIELD_COPY(zc_fromobj);
    635 		FIELD_COPY(zc_createtxg);
    636 		FIELD_COPY(zc_stat);
    637 #undef FIELD_COPY
    638 		break;
    639 
    640 	case ZFS_CMD_COMPAT_ZCMD:
    641 		zcmd_c = (void *)addr;
    642 		/* zc */
    643 		strlcpy(zcmd_c->zc_name, zc->zc_name, MAXPATHLEN);
    644 		strlcpy(zcmd_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
    645 		strlcpy(zcmd_c->zc_string, zc->zc_string, MAXPATHLEN);
    646 
    647 #define FIELD_COPY(field) zcmd_c->field = zc->field
    648 		FIELD_COPY(zc_nvlist_src);
    649 		FIELD_COPY(zc_nvlist_src_size);
    650 		FIELD_COPY(zc_nvlist_dst);
    651 		FIELD_COPY(zc_nvlist_dst_size);
    652 		FIELD_COPY(zc_nvlist_dst_filled);
    653 		FIELD_COPY(zc_pad2);
    654 		FIELD_COPY(zc_history);
    655 		FIELD_COPY(zc_guid);
    656 		FIELD_COPY(zc_nvlist_conf);
    657 		FIELD_COPY(zc_nvlist_conf_size);
    658 		FIELD_COPY(zc_cookie);
    659 		FIELD_COPY(zc_objset_type);
    660 		FIELD_COPY(zc_perm_action);
    661 		FIELD_COPY(zc_history_len);
    662 		FIELD_COPY(zc_history_offset);
    663 		FIELD_COPY(zc_obj);
    664 		FIELD_COPY(zc_iflags);
    665 		FIELD_COPY(zc_share);
    666 		FIELD_COPY(zc_jailid);
    667 		FIELD_COPY(zc_objset_stats);
    668 		zcmd_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
    669 		FIELD_COPY(zc_inject_record.zi_objset);
    670 		FIELD_COPY(zc_inject_record.zi_object);
    671 		FIELD_COPY(zc_inject_record.zi_start);
    672 		FIELD_COPY(zc_inject_record.zi_end);
    673 		FIELD_COPY(zc_inject_record.zi_guid);
    674 		FIELD_COPY(zc_inject_record.zi_level);
    675 		FIELD_COPY(zc_inject_record.zi_error);
    676 		FIELD_COPY(zc_inject_record.zi_type);
    677 		FIELD_COPY(zc_inject_record.zi_freq);
    678 		FIELD_COPY(zc_inject_record.zi_failfast);
    679 		strlcpy(zcmd_c->zc_inject_record.zi_func,
    680 		    zc->zc_inject_record.zi_func, MAXNAMELEN);
    681 		FIELD_COPY(zc_inject_record.zi_iotype);
    682 		FIELD_COPY(zc_inject_record.zi_duration);
    683 		FIELD_COPY(zc_inject_record.zi_timer);
    684 		FIELD_COPY(zc_inject_record.zi_cmd);
    685 		FIELD_COPY(zc_inject_record.zi_pad);
    686 
    687 		/* boolean_t -> uint32_t */
    688 		zcmd_c->zc_defer_destroy = (uint32_t)(zc->zc_defer_destroy);
    689 		zcmd_c->zc_temphold = 0;
    690 
    691 		FIELD_COPY(zc_action_handle);
    692 		FIELD_COPY(zc_cleanup_fd);
    693 		FIELD_COPY(zc_simple);
    694 		FIELD_COPY(zc_sendobj);
    695 		FIELD_COPY(zc_fromobj);
    696 		FIELD_COPY(zc_createtxg);
    697 		FIELD_COPY(zc_stat);
    698 #undef FIELD_COPY
    699 
    700 		break;
    701 
    702 	case ZFS_CMD_COMPAT_DEADMAN:
    703 		zcdm_c = (void *)addr;
    704 
    705 		strlcpy(zcdm_c->zc_name, zc->zc_name, MAXPATHLEN);
    706 		strlcpy(zcdm_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
    707 		strlcpy(zcdm_c->zc_string, zc->zc_string, MAXPATHLEN);
    708 
    709 #define FIELD_COPY(field) zcdm_c->field = zc->field
    710 		zcdm_c->zc_guid = zc->zc_guid;
    711 		zcdm_c->zc_nvlist_conf = zc->zc_nvlist_conf;
    712 		zcdm_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
    713 		zcdm_c->zc_nvlist_src = zc->zc_nvlist_src;
    714 		zcdm_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
    715 		zcdm_c->zc_nvlist_dst = zc->zc_nvlist_dst;
    716 		zcdm_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
    717 		zcdm_c->zc_cookie = zc->zc_cookie;
    718 		zcdm_c->zc_objset_type = zc->zc_objset_type;
    719 		zcdm_c->zc_perm_action = zc->zc_perm_action;
    720 		zcdm_c->zc_history = zc->zc_history;
    721 		zcdm_c->zc_history_len = zc->zc_history_len;
    722 		zcdm_c->zc_history_offset = zc->zc_history_offset;
    723 		zcdm_c->zc_obj = zc->zc_obj;
    724 		zcdm_c->zc_iflags = zc->zc_iflags;
    725 		zcdm_c->zc_share = zc->zc_share;
    726 		zcdm_c->zc_jailid = zc->zc_jailid;
    727 		zcdm_c->zc_objset_stats = zc->zc_objset_stats;
    728 		zcdm_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
    729 		zcdm_c->zc_defer_destroy = zc->zc_defer_destroy;
    730 		zcdm_c->zc_temphold = 0;
    731 		zcdm_c->zc_action_handle = zc->zc_action_handle;
    732 		zcdm_c->zc_cleanup_fd = zc->zc_cleanup_fd;
    733 		zcdm_c->zc_simple = zc->zc_simple;
    734 		zcdm_c->zc_sendobj = zc->zc_sendobj;
    735 		zcdm_c->zc_fromobj = zc->zc_fromobj;
    736 		zcdm_c->zc_createtxg = zc->zc_createtxg;
    737 		zcdm_c->zc_stat = zc->zc_stat;
    738 		FIELD_COPY(zc_inject_record.zi_objset);
    739 		FIELD_COPY(zc_inject_record.zi_object);
    740 		FIELD_COPY(zc_inject_record.zi_start);
    741 		FIELD_COPY(zc_inject_record.zi_end);
    742 		FIELD_COPY(zc_inject_record.zi_guid);
    743 		FIELD_COPY(zc_inject_record.zi_level);
    744 		FIELD_COPY(zc_inject_record.zi_error);
    745 		FIELD_COPY(zc_inject_record.zi_type);
    746 		FIELD_COPY(zc_inject_record.zi_freq);
    747 		FIELD_COPY(zc_inject_record.zi_failfast);
    748 		strlcpy(zcdm_c->zc_inject_record.zi_func,
    749 		    zc->zc_inject_record.zi_func, MAXNAMELEN);
    750 		FIELD_COPY(zc_inject_record.zi_iotype);
    751 		FIELD_COPY(zc_inject_record.zi_duration);
    752 		FIELD_COPY(zc_inject_record.zi_timer);
    753 		FIELD_COPY(zc_inject_record.zi_cmd);
    754 		FIELD_COPY(zc_inject_record.zi_pad);
    755 #undef FIELD_COPY
    756 #ifndef _KERNEL
    757 		if (request == ZFS_IOC_RECV)
    758 			strlcpy(zcdm_c->zc_top_ds,
    759 			    zc->zc_value + strlen(zc->zc_value) + 1,
    760 			    (MAXPATHLEN * 2) - strlen(zc->zc_value) - 1);
    761 #endif
    762 		break;
    763 
    764 	case ZFS_CMD_COMPAT_V28:
    765 		zc28_c = (void *)addr;
    766 
    767 		strlcpy(zc28_c->zc_name, zc->zc_name, MAXPATHLEN);
    768 		strlcpy(zc28_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
    769 		strlcpy(zc28_c->zc_string, zc->zc_string, MAXPATHLEN);
    770 		zc28_c->zc_guid = zc->zc_guid;
    771 		zc28_c->zc_nvlist_conf = zc->zc_nvlist_conf;
    772 		zc28_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
    773 		zc28_c->zc_nvlist_src = zc->zc_nvlist_src;
    774 		zc28_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
    775 		zc28_c->zc_nvlist_dst = zc->zc_nvlist_dst;
    776 		zc28_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
    777 		zc28_c->zc_cookie = zc->zc_cookie;
    778 		zc28_c->zc_objset_type = zc->zc_objset_type;
    779 		zc28_c->zc_perm_action = zc->zc_perm_action;
    780 		zc28_c->zc_history = zc->zc_history;
    781 		zc28_c->zc_history_len = zc->zc_history_len;
    782 		zc28_c->zc_history_offset = zc->zc_history_offset;
    783 		zc28_c->zc_obj = zc->zc_obj;
    784 		zc28_c->zc_iflags = zc->zc_iflags;
    785 		zc28_c->zc_share = zc->zc_share;
    786 		zc28_c->zc_jailid = zc->zc_jailid;
    787 		zc28_c->zc_objset_stats = zc->zc_objset_stats;
    788 		zc28_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
    789 		zc28_c->zc_defer_destroy = zc->zc_defer_destroy;
    790 		zc28_c->zc_temphold = 0;
    791 		zc28_c->zc_action_handle = zc->zc_action_handle;
    792 		zc28_c->zc_cleanup_fd = zc->zc_cleanup_fd;
    793 		zc28_c->zc_simple = zc->zc_simple;
    794 		zc28_c->zc_sendobj = zc->zc_sendobj;
    795 		zc28_c->zc_fromobj = zc->zc_fromobj;
    796 		zc28_c->zc_createtxg = zc->zc_createtxg;
    797 		zc28_c->zc_stat = zc->zc_stat;
    798 #ifndef _KERNEL
    799 		if (request == ZFS_IOC_RECV)
    800 			strlcpy(zc28_c->zc_top_ds,
    801 			    zc->zc_value + strlen(zc->zc_value) + 1,
    802 			    MAXPATHLEN * 2 - strlen(zc->zc_value) - 1);
    803 #endif
    804 		/* zc_inject_record */
    805 		zc28_c->zc_inject_record.zi_objset =
    806 		    zc->zc_inject_record.zi_objset;
    807 		zc28_c->zc_inject_record.zi_object =
    808 		    zc->zc_inject_record.zi_object;
    809 		zc28_c->zc_inject_record.zi_start =
    810 		    zc->zc_inject_record.zi_start;
    811 		zc28_c->zc_inject_record.zi_end =
    812 		    zc->zc_inject_record.zi_end;
    813 		zc28_c->zc_inject_record.zi_guid =
    814 		    zc->zc_inject_record.zi_guid;
    815 		zc28_c->zc_inject_record.zi_level =
    816 		    zc->zc_inject_record.zi_level;
    817 		zc28_c->zc_inject_record.zi_error =
    818 		    zc->zc_inject_record.zi_error;
    819 		zc28_c->zc_inject_record.zi_type =
    820 		    zc->zc_inject_record.zi_type;
    821 		zc28_c->zc_inject_record.zi_freq =
    822 		    zc->zc_inject_record.zi_freq;
    823 		zc28_c->zc_inject_record.zi_failfast =
    824 		    zc->zc_inject_record.zi_failfast;
    825 		strlcpy(zc28_c->zc_inject_record.zi_func,
    826 		    zc->zc_inject_record.zi_func, MAXNAMELEN);
    827 		zc28_c->zc_inject_record.zi_iotype =
    828 		    zc->zc_inject_record.zi_iotype;
    829 		zc28_c->zc_inject_record.zi_duration =
    830 		    zc->zc_inject_record.zi_duration;
    831 		zc28_c->zc_inject_record.zi_timer =
    832 		    zc->zc_inject_record.zi_timer;
    833 		break;
    834 
    835 	case ZFS_CMD_COMPAT_V15:
    836 		zc_c = (void *)addr;
    837 
    838 		/* zc */
    839 		strlcpy(zc_c->zc_name, zc->zc_name, MAXPATHLEN);
    840 		strlcpy(zc_c->zc_value, zc->zc_value, MAXPATHLEN);
    841 		strlcpy(zc_c->zc_string, zc->zc_string, MAXPATHLEN);
    842 		zc_c->zc_guid = zc->zc_guid;
    843 		zc_c->zc_nvlist_conf = zc->zc_nvlist_conf;
    844 		zc_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
    845 		zc_c->zc_nvlist_src = zc->zc_nvlist_src;
    846 		zc_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
    847 		zc_c->zc_nvlist_dst = zc->zc_nvlist_dst;
    848 		zc_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
    849 		zc_c->zc_cookie = zc->zc_cookie;
    850 		zc_c->zc_objset_type = zc->zc_objset_type;
    851 		zc_c->zc_perm_action = zc->zc_perm_action;
    852 		zc_c->zc_history = zc->zc_history;
    853 		zc_c->zc_history_len = zc->zc_history_len;
    854 		zc_c->zc_history_offset = zc->zc_history_offset;
    855 		zc_c->zc_obj = zc->zc_obj;
    856 		zc_c->zc_share = zc->zc_share;
    857 		zc_c->zc_jailid = zc->zc_jailid;
    858 		zc_c->zc_objset_stats = zc->zc_objset_stats;
    859 		zc_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin;
    860 
    861 		/* zc_inject_record */
    862 		zc_c->zc_inject_record.zi_objset =
    863 		    zc->zc_inject_record.zi_objset;
    864 		zc_c->zc_inject_record.zi_object =
    865 		    zc->zc_inject_record.zi_object;
    866 		zc_c->zc_inject_record.zi_start =
    867 		    zc->zc_inject_record.zi_start;
    868 		zc_c->zc_inject_record.zi_end =
    869 		    zc->zc_inject_record.zi_end;
    870 		zc_c->zc_inject_record.zi_guid =
    871 		    zc->zc_inject_record.zi_guid;
    872 		zc_c->zc_inject_record.zi_level =
    873 		    zc->zc_inject_record.zi_level;
    874 		zc_c->zc_inject_record.zi_error =
    875 		    zc->zc_inject_record.zi_error;
    876 		zc_c->zc_inject_record.zi_type =
    877 		    zc->zc_inject_record.zi_type;
    878 		zc_c->zc_inject_record.zi_freq =
    879 		    zc->zc_inject_record.zi_freq;
    880 		zc_c->zc_inject_record.zi_failfast =
    881 		    zc->zc_inject_record.zi_failfast;
    882 
    883 		break;
    884 	}
    885 }
    886 
    887 static int
    888 zfs_ioctl_compat_get_nvlist(uint64_t nvl, size_t size, int iflag,
    889     nvlist_t **nvp)
    890 {
    891 	char *packed;
    892 	int error;
    893 	nvlist_t *list = NULL;
    894 
    895 	/*
    896 	 * Read in and unpack the user-supplied nvlist.
    897 	 */
    898 	if (size == 0)
    899 		return (EINVAL);
    900 
    901 #ifdef _KERNEL
    902 	packed = kmem_alloc(size, KM_SLEEP);
    903 	if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
    904 	    iflag)) != 0) {
    905 		kmem_free(packed, size);
    906 		return (error);
    907 	}
    908 #else
    909 	packed = (void *)(uintptr_t)nvl;
    910 #endif
    911 
    912 	error = nvlist_unpack(packed, size, &list, 0);
    913 
    914 #ifdef _KERNEL
    915 	kmem_free(packed, size);
    916 #endif
    917 
    918 	if (error != 0)
    919 		return (error);
    920 
    921 	*nvp = list;
    922 	return (0);
    923 }
    924 
    925 static int
    926 zfs_ioctl_compat_put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
    927 {
    928 	char *packed = NULL;
    929 	int error = 0;
    930 	size_t size;
    931 
    932 	VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0);
    933 
    934 #ifdef _KERNEL
    935 	packed = kmem_alloc(size, KM_SLEEP);
    936 	VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
    937 	    KM_SLEEP) == 0);
    938 
    939 	if (ddi_copyout(packed,
    940 	    (void *)(uintptr_t)zc->zc_nvlist_dst, size, zc->zc_iflags) != 0)
    941 		error = EFAULT;
    942 	kmem_free(packed, size);
    943 #else
    944 	packed = (void *)(uintptr_t)zc->zc_nvlist_dst;
    945 	VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
    946 	    0) == 0);
    947 #endif
    948 
    949 	zc->zc_nvlist_dst_size = size;
    950 	return (error);
    951 }
    952 
    953 static void
    954 zfs_ioctl_compat_fix_stats_nvlist(nvlist_t *nvl)
    955 {
    956 	nvlist_t **child;
    957 	nvlist_t *nvroot = NULL;
    958 	vdev_stat_t *vs;
    959 	uint_t c, children, nelem;
    960 
    961 	if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN,
    962 	    &child, &children) == 0) {
    963 		for (c = 0; c < children; c++) {
    964 			zfs_ioctl_compat_fix_stats_nvlist(child[c]);
    965 		}
    966 	}
    967 
    968 	if (nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_VDEV_TREE,
    969 	    &nvroot) == 0)
    970 		zfs_ioctl_compat_fix_stats_nvlist(nvroot);
    971 #ifdef _KERNEL
    972 	if ((nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_VDEV_STATS,
    973 #else
    974 	if ((nvlist_lookup_uint64_array(nvl, "stats",
    975 #endif
    976 
    977 	    (uint64_t **)&vs, &nelem) == 0)) {
    978 		nvlist_add_uint64_array(nvl,
    979 #ifdef _KERNEL
    980 		    "stats",
    981 #else
    982 		    ZPOOL_CONFIG_VDEV_STATS,
    983 #endif
    984 		    (uint64_t *)vs, nelem);
    985 #ifdef _KERNEL
    986 		nvlist_remove(nvl, ZPOOL_CONFIG_VDEV_STATS,
    987 #else
    988 		nvlist_remove(nvl, "stats",
    989 #endif
    990 		    DATA_TYPE_UINT64_ARRAY);
    991 	}
    992 }
    993 
    994 static int
    995 zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int nc)
    996 {
    997 	nvlist_t *nv, *nvp = NULL;
    998 	nvpair_t *elem;
    999 	int error;
   1000 
   1001 	if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
   1002 	    zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
   1003 		return (error);
   1004 
   1005 	if (nc == 5) { /* ZFS_IOC_POOL_STATS */
   1006 		elem = NULL;
   1007 		while ((elem = nvlist_next_nvpair(nv, elem)) != NULL) {
   1008 			if (nvpair_value_nvlist(elem, &nvp) == 0)
   1009 				zfs_ioctl_compat_fix_stats_nvlist(nvp);
   1010 		}
   1011 		elem = NULL;
   1012 	} else
   1013 		zfs_ioctl_compat_fix_stats_nvlist(nv);
   1014 
   1015 	error = zfs_ioctl_compat_put_nvlist(zc, nv);
   1016 
   1017 	nvlist_free(nv);
   1018 
   1019 	return (error);
   1020 }
   1021 
   1022 static int
   1023 zfs_ioctl_compat_pool_get_props(zfs_cmd_t *zc)
   1024 {
   1025 	nvlist_t *nv, *nva = NULL;
   1026 	int error;
   1027 
   1028 	if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
   1029 	    zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
   1030 		return (error);
   1031 
   1032 #ifdef _KERNEL
   1033 	if (nvlist_lookup_nvlist(nv, "allocated", &nva) == 0) {
   1034 		nvlist_add_nvlist(nv, "used", nva);
   1035 		nvlist_remove(nv, "allocated", DATA_TYPE_NVLIST);
   1036 	}
   1037 
   1038 	if (nvlist_lookup_nvlist(nv, "free", &nva) == 0) {
   1039 		nvlist_add_nvlist(nv, "available", nva);
   1040 		nvlist_remove(nv, "free", DATA_TYPE_NVLIST);
   1041 	}
   1042 #else
   1043 	if (nvlist_lookup_nvlist(nv, "used", &nva) == 0) {
   1044 		nvlist_add_nvlist(nv, "allocated", nva);
   1045 		nvlist_remove(nv, "used", DATA_TYPE_NVLIST);
   1046 	}
   1047 
   1048 	if (nvlist_lookup_nvlist(nv, "available", &nva) == 0) {
   1049 		nvlist_add_nvlist(nv, "free", nva);
   1050 		nvlist_remove(nv, "available", DATA_TYPE_NVLIST);
   1051 	}
   1052 #endif
   1053 
   1054 	error = zfs_ioctl_compat_put_nvlist(zc, nv);
   1055 
   1056 	nvlist_free(nv);
   1057 
   1058 	return (error);
   1059 }
   1060 
   1061 #ifndef _KERNEL
   1062 int
   1063 zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
   1064 {
   1065 	int nc, ret;
   1066 	void *zc_c;
   1067 	unsigned long ncmd;
   1068 	zfs_iocparm_t zp;
   1069 
   1070 	switch (cflag) {
   1071 	case ZFS_CMD_COMPAT_NONE:
   1072 		ncmd = _IOWR('Z', request, struct zfs_iocparm);
   1073 		zp.zfs_cmd = (uint64_t)zc;
   1074 		zp.zfs_cmd_size = sizeof(zfs_cmd_t);
   1075 		zp.zfs_ioctl_version = ZFS_IOCVER_CURRENT;
   1076 		return (ioctl(fd, ncmd, &zp));
   1077 	case ZFS_CMD_COMPAT_INLANES:
   1078 		ncmd = _IOWR('Z', request, struct zfs_iocparm);
   1079 		zp.zfs_cmd = (uint64_t)zc;
   1080 		zp.zfs_cmd_size = sizeof(zfs_cmd_inlanes_t);
   1081 		zp.zfs_ioctl_version = ZFS_IOCVER_INLANES;
   1082 		return (ioctl(fd, ncmd, &zp));
   1083 	case ZFS_CMD_COMPAT_RESUME:
   1084 		ncmd = _IOWR('Z', request, struct zfs_iocparm);
   1085 		zp.zfs_cmd = (uint64_t)zc;
   1086 		zp.zfs_cmd_size = sizeof(zfs_cmd_resume_t);
   1087 		zp.zfs_ioctl_version = ZFS_IOCVER_RESUME;
   1088 		return (ioctl(fd, ncmd, &zp));
   1089 	case ZFS_CMD_COMPAT_EDBP:
   1090 		ncmd = _IOWR('Z', request, struct zfs_iocparm);
   1091 		zp.zfs_cmd = (uint64_t)zc;
   1092 		zp.zfs_cmd_size = sizeof(zfs_cmd_edbp_t);
   1093 		zp.zfs_ioctl_version = ZFS_IOCVER_EDBP;
   1094 		return (ioctl(fd, ncmd, &zp));
   1095 	case ZFS_CMD_COMPAT_ZCMD:
   1096 		ncmd = _IOWR('Z', request, struct zfs_iocparm);
   1097 		zp.zfs_cmd = (uint64_t)zc;
   1098 		zp.zfs_cmd_size = sizeof(zfs_cmd_zcmd_t);
   1099 		zp.zfs_ioctl_version = ZFS_IOCVER_ZCMD;
   1100 		return (ioctl(fd, ncmd, &zp));
   1101 	case ZFS_CMD_COMPAT_LZC:
   1102 		ncmd = _IOWR('Z', request, struct zfs_cmd);
   1103 		return (ioctl(fd, ncmd, zc));
   1104 	case ZFS_CMD_COMPAT_DEADMAN:
   1105 		zc_c = malloc(sizeof(zfs_cmd_deadman_t));
   1106 		ncmd = _IOWR('Z', request, struct zfs_cmd_deadman);
   1107 		break;
   1108 	case ZFS_CMD_COMPAT_V28:
   1109 		zc_c = malloc(sizeof(zfs_cmd_v28_t));
   1110 		ncmd = _IOWR('Z', request, struct zfs_cmd_v28);
   1111 		break;
   1112 	case ZFS_CMD_COMPAT_V15:
   1113 		nc = zfs_ioctl_v28_to_v15[request];
   1114 		zc_c = malloc(sizeof(zfs_cmd_v15_t));
   1115 		ncmd = _IOWR('Z', nc, struct zfs_cmd_v15);
   1116 		break;
   1117 	default:
   1118 		return (EINVAL);
   1119 	}
   1120 
   1121 	if (ZFS_IOCREQ(ncmd) == ZFS_IOC_COMPAT_FAIL)
   1122 		return (ENOTSUP);
   1123 
   1124 	zfs_cmd_compat_put(zc, (caddr_t)zc_c, request, cflag);
   1125 
   1126 	ret = ioctl(fd, ncmd, zc_c);
   1127 	if (cflag == ZFS_CMD_COMPAT_V15 &&
   1128 	    nc == ZFS_IOC_POOL_IMPORT)
   1129 		ret = ioctl(fd, _IOWR('Z', ZFS_IOC_POOL_CONFIGS,
   1130 		    struct zfs_cmd_v15), zc_c);
   1131 	zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag);
   1132 	free(zc_c);
   1133 
   1134 	if (cflag == ZFS_CMD_COMPAT_V15) {
   1135 		switch (nc) {
   1136 		case ZFS_IOC_POOL_IMPORT:
   1137 		case ZFS_IOC_POOL_CONFIGS:
   1138 		case ZFS_IOC_POOL_STATS:
   1139 		case ZFS_IOC_POOL_TRYIMPORT:
   1140 			zfs_ioctl_compat_fix_stats(zc, nc);
   1141 			break;
   1142 		case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
   1143 			zfs_ioctl_compat_pool_get_props(zc);
   1144 			break;
   1145 		}
   1146 	}
   1147 
   1148 	return (ret);
   1149 }
   1150 #else /* _KERNEL */
   1151 int
   1152 zfs_ioctl_compat_pre(zfs_cmd_t *zc, int *vec, const int cflag)
   1153 {
   1154 	int error = 0;
   1155 
   1156 	/* are we creating a clone? */
   1157 	if (*vec == ZFS_IOC_CREATE && zc->zc_value[0] != '\0')
   1158 		*vec = ZFS_IOC_CLONE;
   1159 
   1160 	if (cflag == ZFS_CMD_COMPAT_V15) {
   1161 		switch (*vec) {
   1162 
   1163 		case 7: /* ZFS_IOC_POOL_SCRUB (v15) */
   1164 			zc->zc_cookie = POOL_SCAN_SCRUB;
   1165 			break;
   1166 		}
   1167 	}
   1168 
   1169 	return (error);
   1170 }
   1171 
   1172 void
   1173 zfs_ioctl_compat_post(zfs_cmd_t *zc, int vec, const int cflag)
   1174 {
   1175 	if (cflag == ZFS_CMD_COMPAT_V15) {
   1176 		switch (vec) {
   1177 		case ZFS_IOC_POOL_CONFIGS:
   1178 		case ZFS_IOC_POOL_STATS:
   1179 		case ZFS_IOC_POOL_TRYIMPORT:
   1180 			zfs_ioctl_compat_fix_stats(zc, vec);
   1181 			break;
   1182 		case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
   1183 			zfs_ioctl_compat_pool_get_props(zc);
   1184 			break;
   1185 		}
   1186 	}
   1187 }
   1188 
   1189 nvlist_t *
   1190 zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec,
   1191     const int cflag)
   1192 {
   1193 	nvlist_t *nvl, *tmpnvl, *hnvl;
   1194 	nvpair_t *elem;
   1195 	char *poolname, *snapname;
   1196 	int err;
   1197 
   1198 	if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC ||
   1199 	    cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP ||
   1200 	    cflag == ZFS_CMD_COMPAT_RESUME || cflag == ZFS_CMD_COMPAT_INLANES)
   1201 		goto out;
   1202 
   1203 	switch (vec) {
   1204 	case ZFS_IOC_CREATE:
   1205 		nvl = fnvlist_alloc();
   1206 		fnvlist_add_int32(nvl, "type", zc->zc_objset_type);
   1207 		if (innvl != NULL) {
   1208 			fnvlist_add_nvlist(nvl, "props", innvl);
   1209 			nvlist_free(innvl);
   1210 		}
   1211 		return (nvl);
   1212 	break;
   1213 	case ZFS_IOC_CLONE:
   1214 		nvl = fnvlist_alloc();
   1215 		fnvlist_add_string(nvl, "origin", zc->zc_value);
   1216 		if (innvl != NULL) {
   1217 			fnvlist_add_nvlist(nvl, "props", innvl);
   1218 			nvlist_free(innvl);
   1219 		}
   1220 		return (nvl);
   1221 	break;
   1222 	case ZFS_IOC_SNAPSHOT:
   1223 		if (innvl == NULL)
   1224 			goto out;
   1225 		nvl = fnvlist_alloc();
   1226 		fnvlist_add_nvlist(nvl, "props", innvl);
   1227 		tmpnvl = fnvlist_alloc();
   1228 		snapname = kmem_asprintf("%s@%s", zc->zc_name, zc->zc_value);
   1229 		fnvlist_add_boolean(tmpnvl, snapname);
   1230 		kmem_free(snapname, strlen(snapname + 1));
   1231 		/* check if we are doing a recursive snapshot */
   1232 		if (zc->zc_cookie)
   1233 			dmu_get_recursive_snaps_nvl(zc->zc_name, zc->zc_value,
   1234 			    tmpnvl);
   1235 		fnvlist_add_nvlist(nvl, "snaps", tmpnvl);
   1236 		fnvlist_free(tmpnvl);
   1237 		nvlist_free(innvl);
   1238 		/* strip dataset part from zc->zc_name */
   1239 		zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
   1240 		return (nvl);
   1241 	break;
   1242 	case ZFS_IOC_SPACE_SNAPS:
   1243 		nvl = fnvlist_alloc();
   1244 		fnvlist_add_string(nvl, "firstsnap", zc->zc_value);
   1245 		if (innvl != NULL)
   1246 			nvlist_free(innvl);
   1247 		return (nvl);
   1248 	break;
   1249 	case ZFS_IOC_DESTROY_SNAPS:
   1250 		if (innvl == NULL && cflag == ZFS_CMD_COMPAT_DEADMAN)
   1251 			goto out;
   1252 		nvl = fnvlist_alloc();
   1253 		if (innvl != NULL) {
   1254 			fnvlist_add_nvlist(nvl, "snaps", innvl);
   1255 		} else {
   1256 			/*
   1257 			 * We are probably called by even older binaries,
   1258 			 * allocate and populate nvlist with recursive
   1259 			 * snapshots
   1260 			 */
   1261 			if (zfs_component_namecheck(zc->zc_value, NULL,
   1262 			    NULL) == 0) {
   1263 				tmpnvl = fnvlist_alloc();
   1264 				if (dmu_get_recursive_snaps_nvl(zc->zc_name,
   1265 				    zc->zc_value, tmpnvl) == 0)
   1266 					fnvlist_add_nvlist(nvl, "snaps",
   1267 					    tmpnvl);
   1268 				nvlist_free(tmpnvl);
   1269 			}
   1270 		}
   1271 		if (innvl != NULL)
   1272 			nvlist_free(innvl);
   1273 		/* strip dataset part from zc->zc_name */
   1274 		zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
   1275 		return (nvl);
   1276 	break;
   1277 	case ZFS_IOC_HOLD:
   1278 		nvl = fnvlist_alloc();
   1279 		tmpnvl = fnvlist_alloc();
   1280 		if (zc->zc_cleanup_fd != -1)
   1281 			fnvlist_add_int32(nvl, "cleanup_fd",
   1282 			    (int32_t)zc->zc_cleanup_fd);
   1283 		if (zc->zc_cookie) {
   1284 			hnvl = fnvlist_alloc();
   1285 			if (dmu_get_recursive_snaps_nvl(zc->zc_name,
   1286 			    zc->zc_value, hnvl) == 0) {
   1287 				elem = NULL;
   1288 				while ((elem = nvlist_next_nvpair(hnvl,
   1289 				    elem)) != NULL) {
   1290 					nvlist_add_string(tmpnvl,
   1291 					    nvpair_name(elem), zc->zc_string);
   1292 				}
   1293 			}
   1294 			nvlist_free(hnvl);
   1295 		} else {
   1296 			snapname = kmem_asprintf("%s@%s", zc->zc_name,
   1297 			    zc->zc_value);
   1298 			nvlist_add_string(tmpnvl, snapname, zc->zc_string);
   1299 			kmem_free(snapname, strlen(snapname + 1));
   1300 		}
   1301 		fnvlist_add_nvlist(nvl, "holds", tmpnvl);
   1302 		nvlist_free(tmpnvl);
   1303 		if (innvl != NULL)
   1304 			nvlist_free(innvl);
   1305 		/* strip dataset part from zc->zc_name */
   1306 		zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
   1307 		return (nvl);
   1308 	break;
   1309 	case ZFS_IOC_RELEASE:
   1310 		nvl = fnvlist_alloc();
   1311 		tmpnvl = fnvlist_alloc();
   1312 		if (zc->zc_cookie) {
   1313 			hnvl = fnvlist_alloc();
   1314 			if (dmu_get_recursive_snaps_nvl(zc->zc_name,
   1315 			    zc->zc_value, hnvl) == 0) {
   1316 				elem = NULL;
   1317 				while ((elem = nvlist_next_nvpair(hnvl,
   1318 				    elem)) != NULL) {
   1319 					fnvlist_add_boolean(tmpnvl,
   1320 					    zc->zc_string);
   1321 					fnvlist_add_nvlist(nvl,
   1322 					    nvpair_name(elem), tmpnvl);
   1323 				}
   1324 			}
   1325 			nvlist_free(hnvl);
   1326 		} else {
   1327 			snapname = kmem_asprintf("%s@%s", zc->zc_name,
   1328 			    zc->zc_value);
   1329 			fnvlist_add_boolean(tmpnvl, zc->zc_string);
   1330 			fnvlist_add_nvlist(nvl, snapname, tmpnvl);
   1331 			kmem_free(snapname, strlen(snapname + 1));
   1332 		}
   1333 		nvlist_free(tmpnvl);
   1334 		if (innvl != NULL)
   1335 			nvlist_free(innvl);
   1336 		/* strip dataset part from zc->zc_name */
   1337 		zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0';
   1338 		return (nvl);
   1339 	break;
   1340 	}
   1341 out:
   1342 	return (innvl);
   1343 }
   1344 
   1345 nvlist_t *
   1346 zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec,
   1347     const int cflag)
   1348 {
   1349 	nvlist_t *tmpnvl;
   1350 
   1351 	if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC ||
   1352 	    cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP ||
   1353 	    cflag == ZFS_CMD_COMPAT_RESUME || cflag == ZFS_CMD_COMPAT_INLANES)
   1354 		return (outnvl);
   1355 
   1356 	switch (vec) {
   1357 	case ZFS_IOC_SPACE_SNAPS:
   1358 		(void) nvlist_lookup_uint64(outnvl, "used", &zc->zc_cookie);
   1359 		(void) nvlist_lookup_uint64(outnvl, "compressed",
   1360 		    &zc->zc_objset_type);
   1361 		(void) nvlist_lookup_uint64(outnvl, "uncompressed",
   1362 		    &zc->zc_perm_action);
   1363 		nvlist_free(outnvl);
   1364 		/* return empty outnvl */
   1365 		tmpnvl = fnvlist_alloc();
   1366 		return (tmpnvl);
   1367 	break;
   1368 	case ZFS_IOC_CREATE:
   1369 	case ZFS_IOC_CLONE:
   1370 	case ZFS_IOC_HOLD:
   1371 	case ZFS_IOC_RELEASE:
   1372 		nvlist_free(outnvl);
   1373 		/* return empty outnvl */
   1374 		tmpnvl = fnvlist_alloc();
   1375 		return (tmpnvl);
   1376 	break;
   1377 	}
   1378 
   1379 	return (outnvl);
   1380 }
   1381 #endif /* KERNEL */
   1382