zfs_ioctl_compat.c revision 290756
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 40static int zfs_version_ioctl = ZFS_IOCVER_CURRENT; 41SYSCTL_DECL(_vfs_zfs_version); 42SYSCTL_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 */ 49void 50zfs_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 58 switch (cflag) { 59 case ZFS_CMD_COMPAT_EDBP: 60 edbp_c = (void *)addr; 61 /* zc */ 62 strlcpy(zc->zc_name, edbp_c->zc_name, MAXPATHLEN); 63 strlcpy(zc->zc_value, edbp_c->zc_value, MAXPATHLEN * 2); 64 strlcpy(zc->zc_string, edbp_c->zc_string, MAXPATHLEN); 65 66#define ZCMD_COPY(field) zc->field = edbp_c->field 67 ZCMD_COPY(zc_nvlist_src); 68 ZCMD_COPY(zc_nvlist_src_size); 69 ZCMD_COPY(zc_nvlist_dst); 70 ZCMD_COPY(zc_nvlist_dst_size); 71 ZCMD_COPY(zc_nvlist_dst_filled); 72 ZCMD_COPY(zc_pad2); 73 ZCMD_COPY(zc_history); 74 ZCMD_COPY(zc_guid); 75 ZCMD_COPY(zc_nvlist_conf); 76 ZCMD_COPY(zc_nvlist_conf_size); 77 ZCMD_COPY(zc_cookie); 78 ZCMD_COPY(zc_objset_type); 79 ZCMD_COPY(zc_perm_action); 80 ZCMD_COPY(zc_history_len); 81 ZCMD_COPY(zc_history_offset); 82 ZCMD_COPY(zc_obj); 83 ZCMD_COPY(zc_iflags); 84 ZCMD_COPY(zc_share); 85 ZCMD_COPY(zc_jailid); 86 ZCMD_COPY(zc_objset_stats); 87 zc->zc_begin_record.drr_u.drr_begin = edbp_c->zc_begin_record; 88 ZCMD_COPY(zc_inject_record); 89 ZCMD_COPY(zc_defer_destroy); 90 ZCMD_COPY(zc_flags); 91 ZCMD_COPY(zc_action_handle); 92 ZCMD_COPY(zc_cleanup_fd); 93 ZCMD_COPY(zc_simple); 94 zc->zc_resumable = B_FALSE; 95 ZCMD_COPY(zc_sendobj); 96 ZCMD_COPY(zc_fromobj); 97 ZCMD_COPY(zc_createtxg); 98 ZCMD_COPY(zc_stat); 99#undef ZCMD_COPY 100 break; 101 102 case ZFS_CMD_COMPAT_ZCMD: 103 zcmd_c = (void *)addr; 104 /* zc */ 105 strlcpy(zc->zc_name, zcmd_c->zc_name, MAXPATHLEN); 106 strlcpy(zc->zc_value, zcmd_c->zc_value, MAXPATHLEN * 2); 107 strlcpy(zc->zc_string, zcmd_c->zc_string, MAXPATHLEN); 108 109#define ZCMD_COPY(field) zc->field = zcmd_c->field 110 ZCMD_COPY(zc_nvlist_src); 111 ZCMD_COPY(zc_nvlist_src_size); 112 ZCMD_COPY(zc_nvlist_dst); 113 ZCMD_COPY(zc_nvlist_dst_size); 114 ZCMD_COPY(zc_nvlist_dst_filled); 115 ZCMD_COPY(zc_pad2); 116 ZCMD_COPY(zc_history); 117 ZCMD_COPY(zc_guid); 118 ZCMD_COPY(zc_nvlist_conf); 119 ZCMD_COPY(zc_nvlist_conf_size); 120 ZCMD_COPY(zc_cookie); 121 ZCMD_COPY(zc_objset_type); 122 ZCMD_COPY(zc_perm_action); 123 ZCMD_COPY(zc_history_len); 124 ZCMD_COPY(zc_history_offset); 125 ZCMD_COPY(zc_obj); 126 ZCMD_COPY(zc_iflags); 127 ZCMD_COPY(zc_share); 128 ZCMD_COPY(zc_jailid); 129 ZCMD_COPY(zc_objset_stats); 130 zc->zc_begin_record.drr_u.drr_begin = zcmd_c->zc_begin_record; 131 ZCMD_COPY(zc_inject_record); 132 133 /* boolean_t -> uint32_t */ 134 zc->zc_defer_destroy = (uint32_t)(zcmd_c->zc_defer_destroy); 135 zc->zc_flags = 0; 136 137 ZCMD_COPY(zc_action_handle); 138 ZCMD_COPY(zc_cleanup_fd); 139 ZCMD_COPY(zc_simple); 140 zc->zc_resumable = B_FALSE; 141 ZCMD_COPY(zc_sendobj); 142 ZCMD_COPY(zc_fromobj); 143 ZCMD_COPY(zc_createtxg); 144 ZCMD_COPY(zc_stat); 145#undef ZCMD_COPY 146 147 break; 148 149 case ZFS_CMD_COMPAT_DEADMAN: 150 zcdm_c = (void *)addr; 151 /* zc */ 152 strlcpy(zc->zc_name, zcdm_c->zc_name, MAXPATHLEN); 153 strlcpy(zc->zc_value, zcdm_c->zc_value, MAXPATHLEN * 2); 154 strlcpy(zc->zc_string, zcdm_c->zc_string, MAXPATHLEN); 155 zc->zc_guid = zcdm_c->zc_guid; 156 zc->zc_nvlist_conf = zcdm_c->zc_nvlist_conf; 157 zc->zc_nvlist_conf_size = zcdm_c->zc_nvlist_conf_size; 158 zc->zc_nvlist_src = zcdm_c->zc_nvlist_src; 159 zc->zc_nvlist_src_size = zcdm_c->zc_nvlist_src_size; 160 zc->zc_nvlist_dst = zcdm_c->zc_nvlist_dst; 161 zc->zc_nvlist_dst_size = zcdm_c->zc_nvlist_dst_size; 162 zc->zc_cookie = zcdm_c->zc_cookie; 163 zc->zc_objset_type = zcdm_c->zc_objset_type; 164 zc->zc_perm_action = zcdm_c->zc_perm_action; 165 zc->zc_history = zcdm_c->zc_history; 166 zc->zc_history_len = zcdm_c->zc_history_len; 167 zc->zc_history_offset = zcdm_c->zc_history_offset; 168 zc->zc_obj = zcdm_c->zc_obj; 169 zc->zc_iflags = zcdm_c->zc_iflags; 170 zc->zc_share = zcdm_c->zc_share; 171 zc->zc_jailid = zcdm_c->zc_jailid; 172 zc->zc_objset_stats = zcdm_c->zc_objset_stats; 173 zc->zc_begin_record.drr_u.drr_begin = zcdm_c->zc_begin_record; 174 zc->zc_defer_destroy = zcdm_c->zc_defer_destroy; 175 (void)zcdm_c->zc_temphold; 176 zc->zc_action_handle = zcdm_c->zc_action_handle; 177 zc->zc_cleanup_fd = zcdm_c->zc_cleanup_fd; 178 zc->zc_simple = zcdm_c->zc_simple; 179 zc->zc_resumable = B_FALSE; 180 zc->zc_sendobj = zcdm_c->zc_sendobj; 181 zc->zc_fromobj = zcdm_c->zc_fromobj; 182 zc->zc_createtxg = zcdm_c->zc_createtxg; 183 zc->zc_stat = zcdm_c->zc_stat; 184 185 /* zc_inject_record doesn't change in libzfs_core */ 186 zcdm_c->zc_inject_record = zc->zc_inject_record; 187 188 /* we always assume zc_nvlist_dst_filled is true */ 189 zc->zc_nvlist_dst_filled = B_TRUE; 190 break; 191 192 case ZFS_CMD_COMPAT_V28: 193 zc28_c = (void *)addr; 194 195 /* zc */ 196 strlcpy(zc->zc_name, zc28_c->zc_name, MAXPATHLEN); 197 strlcpy(zc->zc_value, zc28_c->zc_value, MAXPATHLEN * 2); 198 strlcpy(zc->zc_string, zc28_c->zc_string, MAXPATHLEN); 199 zc->zc_guid = zc28_c->zc_guid; 200 zc->zc_nvlist_conf = zc28_c->zc_nvlist_conf; 201 zc->zc_nvlist_conf_size = zc28_c->zc_nvlist_conf_size; 202 zc->zc_nvlist_src = zc28_c->zc_nvlist_src; 203 zc->zc_nvlist_src_size = zc28_c->zc_nvlist_src_size; 204 zc->zc_nvlist_dst = zc28_c->zc_nvlist_dst; 205 zc->zc_nvlist_dst_size = zc28_c->zc_nvlist_dst_size; 206 zc->zc_cookie = zc28_c->zc_cookie; 207 zc->zc_objset_type = zc28_c->zc_objset_type; 208 zc->zc_perm_action = zc28_c->zc_perm_action; 209 zc->zc_history = zc28_c->zc_history; 210 zc->zc_history_len = zc28_c->zc_history_len; 211 zc->zc_history_offset = zc28_c->zc_history_offset; 212 zc->zc_obj = zc28_c->zc_obj; 213 zc->zc_iflags = zc28_c->zc_iflags; 214 zc->zc_share = zc28_c->zc_share; 215 zc->zc_jailid = zc28_c->zc_jailid; 216 zc->zc_objset_stats = zc28_c->zc_objset_stats; 217 zc->zc_begin_record.drr_u.drr_begin = zc28_c->zc_begin_record; 218 zc->zc_defer_destroy = zc28_c->zc_defer_destroy; 219 (void)zc28_c->zc_temphold; 220 zc->zc_action_handle = zc28_c->zc_action_handle; 221 zc->zc_cleanup_fd = zc28_c->zc_cleanup_fd; 222 zc->zc_simple = zc28_c->zc_simple; 223 zc->zc_resumable = B_FALSE; 224 zc->zc_sendobj = zc28_c->zc_sendobj; 225 zc->zc_fromobj = zc28_c->zc_fromobj; 226 zc->zc_createtxg = zc28_c->zc_createtxg; 227 zc->zc_stat = zc28_c->zc_stat; 228 229 /* zc->zc_inject_record */ 230 zc->zc_inject_record.zi_objset = 231 zc28_c->zc_inject_record.zi_objset; 232 zc->zc_inject_record.zi_object = 233 zc28_c->zc_inject_record.zi_object; 234 zc->zc_inject_record.zi_start = 235 zc28_c->zc_inject_record.zi_start; 236 zc->zc_inject_record.zi_end = 237 zc28_c->zc_inject_record.zi_end; 238 zc->zc_inject_record.zi_guid = 239 zc28_c->zc_inject_record.zi_guid; 240 zc->zc_inject_record.zi_level = 241 zc28_c->zc_inject_record.zi_level; 242 zc->zc_inject_record.zi_error = 243 zc28_c->zc_inject_record.zi_error; 244 zc->zc_inject_record.zi_type = 245 zc28_c->zc_inject_record.zi_type; 246 zc->zc_inject_record.zi_freq = 247 zc28_c->zc_inject_record.zi_freq; 248 zc->zc_inject_record.zi_failfast = 249 zc28_c->zc_inject_record.zi_failfast; 250 strlcpy(zc->zc_inject_record.zi_func, 251 zc28_c->zc_inject_record.zi_func, MAXNAMELEN); 252 zc->zc_inject_record.zi_iotype = 253 zc28_c->zc_inject_record.zi_iotype; 254 zc->zc_inject_record.zi_duration = 255 zc28_c->zc_inject_record.zi_duration; 256 zc->zc_inject_record.zi_timer = 257 zc28_c->zc_inject_record.zi_timer; 258 zc->zc_inject_record.zi_cmd = ZINJECT_UNINITIALIZED; 259 zc->zc_inject_record.zi_pad = 0; 260 break; 261 262 case ZFS_CMD_COMPAT_V15: 263 zc_c = (void *)addr; 264 265 /* zc */ 266 strlcpy(zc->zc_name, zc_c->zc_name, MAXPATHLEN); 267 strlcpy(zc->zc_value, zc_c->zc_value, MAXPATHLEN); 268 strlcpy(zc->zc_string, zc_c->zc_string, MAXPATHLEN); 269 zc->zc_guid = zc_c->zc_guid; 270 zc->zc_nvlist_conf = zc_c->zc_nvlist_conf; 271 zc->zc_nvlist_conf_size = zc_c->zc_nvlist_conf_size; 272 zc->zc_nvlist_src = zc_c->zc_nvlist_src; 273 zc->zc_nvlist_src_size = zc_c->zc_nvlist_src_size; 274 zc->zc_nvlist_dst = zc_c->zc_nvlist_dst; 275 zc->zc_nvlist_dst_size = zc_c->zc_nvlist_dst_size; 276 zc->zc_cookie = zc_c->zc_cookie; 277 zc->zc_objset_type = zc_c->zc_objset_type; 278 zc->zc_perm_action = zc_c->zc_perm_action; 279 zc->zc_history = zc_c->zc_history; 280 zc->zc_history_len = zc_c->zc_history_len; 281 zc->zc_history_offset = zc_c->zc_history_offset; 282 zc->zc_obj = zc_c->zc_obj; 283 zc->zc_share = zc_c->zc_share; 284 zc->zc_jailid = zc_c->zc_jailid; 285 zc->zc_objset_stats = zc_c->zc_objset_stats; 286 zc->zc_begin_record.drr_u.drr_begin = zc_c->zc_begin_record; 287 288 /* zc->zc_inject_record */ 289 zc->zc_inject_record.zi_objset = 290 zc_c->zc_inject_record.zi_objset; 291 zc->zc_inject_record.zi_object = 292 zc_c->zc_inject_record.zi_object; 293 zc->zc_inject_record.zi_start = 294 zc_c->zc_inject_record.zi_start; 295 zc->zc_inject_record.zi_end = 296 zc_c->zc_inject_record.zi_end; 297 zc->zc_inject_record.zi_guid = 298 zc_c->zc_inject_record.zi_guid; 299 zc->zc_inject_record.zi_level = 300 zc_c->zc_inject_record.zi_level; 301 zc->zc_inject_record.zi_error = 302 zc_c->zc_inject_record.zi_error; 303 zc->zc_inject_record.zi_type = 304 zc_c->zc_inject_record.zi_type; 305 zc->zc_inject_record.zi_freq = 306 zc_c->zc_inject_record.zi_freq; 307 zc->zc_inject_record.zi_failfast = 308 zc_c->zc_inject_record.zi_failfast; 309 break; 310 } 311} 312 313void 314zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request, 315 const int cflag) 316{ 317 zfs_cmd_v15_t *zc_c; 318 zfs_cmd_v28_t *zc28_c; 319 zfs_cmd_deadman_t *zcdm_c; 320 zfs_cmd_zcmd_t *zcmd_c; 321 zfs_cmd_edbp_t *edbp_c; 322 323 switch (cflag) { 324 case ZFS_CMD_COMPAT_EDBP: 325 edbp_c = (void *)addr; 326 strlcpy(edbp_c->zc_name, zc->zc_name, MAXPATHLEN); 327 strlcpy(edbp_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 328 strlcpy(edbp_c->zc_string, zc->zc_string, MAXPATHLEN); 329 330#define ZCMD_COPY(field) edbp_c->field = zc->field 331 ZCMD_COPY(zc_nvlist_src); 332 ZCMD_COPY(zc_nvlist_src_size); 333 ZCMD_COPY(zc_nvlist_dst); 334 ZCMD_COPY(zc_nvlist_dst_size); 335 ZCMD_COPY(zc_nvlist_dst_filled); 336 ZCMD_COPY(zc_pad2); 337 ZCMD_COPY(zc_history); 338 ZCMD_COPY(zc_guid); 339 ZCMD_COPY(zc_nvlist_conf); 340 ZCMD_COPY(zc_nvlist_conf_size); 341 ZCMD_COPY(zc_cookie); 342 ZCMD_COPY(zc_objset_type); 343 ZCMD_COPY(zc_perm_action); 344 ZCMD_COPY(zc_history_len); 345 ZCMD_COPY(zc_history_offset); 346 ZCMD_COPY(zc_obj); 347 ZCMD_COPY(zc_iflags); 348 ZCMD_COPY(zc_share); 349 ZCMD_COPY(zc_jailid); 350 ZCMD_COPY(zc_objset_stats); 351 edbp_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 352 ZCMD_COPY(zc_inject_record); 353 ZCMD_COPY(zc_defer_destroy); 354 ZCMD_COPY(zc_flags); 355 ZCMD_COPY(zc_action_handle); 356 ZCMD_COPY(zc_cleanup_fd); 357 ZCMD_COPY(zc_simple); 358 ZCMD_COPY(zc_sendobj); 359 ZCMD_COPY(zc_fromobj); 360 ZCMD_COPY(zc_createtxg); 361 ZCMD_COPY(zc_stat); 362#undef ZCMD_COPY 363 break; 364 365 case ZFS_CMD_COMPAT_ZCMD: 366 zcmd_c = (void *)addr; 367 /* zc */ 368 strlcpy(zcmd_c->zc_name, zc->zc_name, MAXPATHLEN); 369 strlcpy(zcmd_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 370 strlcpy(zcmd_c->zc_string, zc->zc_string, MAXPATHLEN); 371 372#define ZCMD_COPY(field) zcmd_c->field = zc->field 373 ZCMD_COPY(zc_nvlist_src); 374 ZCMD_COPY(zc_nvlist_src_size); 375 ZCMD_COPY(zc_nvlist_dst); 376 ZCMD_COPY(zc_nvlist_dst_size); 377 ZCMD_COPY(zc_nvlist_dst_filled); 378 ZCMD_COPY(zc_pad2); 379 ZCMD_COPY(zc_history); 380 ZCMD_COPY(zc_guid); 381 ZCMD_COPY(zc_nvlist_conf); 382 ZCMD_COPY(zc_nvlist_conf_size); 383 ZCMD_COPY(zc_cookie); 384 ZCMD_COPY(zc_objset_type); 385 ZCMD_COPY(zc_perm_action); 386 ZCMD_COPY(zc_history_len); 387 ZCMD_COPY(zc_history_offset); 388 ZCMD_COPY(zc_obj); 389 ZCMD_COPY(zc_iflags); 390 ZCMD_COPY(zc_share); 391 ZCMD_COPY(zc_jailid); 392 ZCMD_COPY(zc_objset_stats); 393 zcmd_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 394 ZCMD_COPY(zc_inject_record); 395 396 /* boolean_t -> uint32_t */ 397 zcmd_c->zc_defer_destroy = (uint32_t)(zc->zc_defer_destroy); 398 zcmd_c->zc_temphold = 0; 399 400 ZCMD_COPY(zc_action_handle); 401 ZCMD_COPY(zc_cleanup_fd); 402 ZCMD_COPY(zc_simple); 403 ZCMD_COPY(zc_sendobj); 404 ZCMD_COPY(zc_fromobj); 405 ZCMD_COPY(zc_createtxg); 406 ZCMD_COPY(zc_stat); 407#undef ZCMD_COPY 408 409 break; 410 411 case ZFS_CMD_COMPAT_DEADMAN: 412 zcdm_c = (void *)addr; 413 414 strlcpy(zcdm_c->zc_name, zc->zc_name, MAXPATHLEN); 415 strlcpy(zcdm_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 416 strlcpy(zcdm_c->zc_string, zc->zc_string, MAXPATHLEN); 417 zcdm_c->zc_guid = zc->zc_guid; 418 zcdm_c->zc_nvlist_conf = zc->zc_nvlist_conf; 419 zcdm_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size; 420 zcdm_c->zc_nvlist_src = zc->zc_nvlist_src; 421 zcdm_c->zc_nvlist_src_size = zc->zc_nvlist_src_size; 422 zcdm_c->zc_nvlist_dst = zc->zc_nvlist_dst; 423 zcdm_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size; 424 zcdm_c->zc_cookie = zc->zc_cookie; 425 zcdm_c->zc_objset_type = zc->zc_objset_type; 426 zcdm_c->zc_perm_action = zc->zc_perm_action; 427 zcdm_c->zc_history = zc->zc_history; 428 zcdm_c->zc_history_len = zc->zc_history_len; 429 zcdm_c->zc_history_offset = zc->zc_history_offset; 430 zcdm_c->zc_obj = zc->zc_obj; 431 zcdm_c->zc_iflags = zc->zc_iflags; 432 zcdm_c->zc_share = zc->zc_share; 433 zcdm_c->zc_jailid = zc->zc_jailid; 434 zcdm_c->zc_objset_stats = zc->zc_objset_stats; 435 zcdm_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 436 zcdm_c->zc_defer_destroy = zc->zc_defer_destroy; 437 zcdm_c->zc_temphold = 0; 438 zcdm_c->zc_action_handle = zc->zc_action_handle; 439 zcdm_c->zc_cleanup_fd = zc->zc_cleanup_fd; 440 zcdm_c->zc_simple = zc->zc_simple; 441 zcdm_c->zc_sendobj = zc->zc_sendobj; 442 zcdm_c->zc_fromobj = zc->zc_fromobj; 443 zcdm_c->zc_createtxg = zc->zc_createtxg; 444 zcdm_c->zc_stat = zc->zc_stat; 445 446 /* zc_inject_record doesn't change in libzfs_core */ 447 zc->zc_inject_record = zcdm_c->zc_inject_record; 448#ifndef _KERNEL 449 if (request == ZFS_IOC_RECV) 450 strlcpy(zcdm_c->zc_top_ds, 451 zc->zc_value + strlen(zc->zc_value) + 1, 452 (MAXPATHLEN * 2) - strlen(zc->zc_value) - 1); 453#endif 454 break; 455 456 case ZFS_CMD_COMPAT_V28: 457 zc28_c = (void *)addr; 458 459 strlcpy(zc28_c->zc_name, zc->zc_name, MAXPATHLEN); 460 strlcpy(zc28_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 461 strlcpy(zc28_c->zc_string, zc->zc_string, MAXPATHLEN); 462 zc28_c->zc_guid = zc->zc_guid; 463 zc28_c->zc_nvlist_conf = zc->zc_nvlist_conf; 464 zc28_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size; 465 zc28_c->zc_nvlist_src = zc->zc_nvlist_src; 466 zc28_c->zc_nvlist_src_size = zc->zc_nvlist_src_size; 467 zc28_c->zc_nvlist_dst = zc->zc_nvlist_dst; 468 zc28_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size; 469 zc28_c->zc_cookie = zc->zc_cookie; 470 zc28_c->zc_objset_type = zc->zc_objset_type; 471 zc28_c->zc_perm_action = zc->zc_perm_action; 472 zc28_c->zc_history = zc->zc_history; 473 zc28_c->zc_history_len = zc->zc_history_len; 474 zc28_c->zc_history_offset = zc->zc_history_offset; 475 zc28_c->zc_obj = zc->zc_obj; 476 zc28_c->zc_iflags = zc->zc_iflags; 477 zc28_c->zc_share = zc->zc_share; 478 zc28_c->zc_jailid = zc->zc_jailid; 479 zc28_c->zc_objset_stats = zc->zc_objset_stats; 480 zc28_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 481 zc28_c->zc_defer_destroy = zc->zc_defer_destroy; 482 zc28_c->zc_temphold = 0; 483 zc28_c->zc_action_handle = zc->zc_action_handle; 484 zc28_c->zc_cleanup_fd = zc->zc_cleanup_fd; 485 zc28_c->zc_simple = zc->zc_simple; 486 zc28_c->zc_sendobj = zc->zc_sendobj; 487 zc28_c->zc_fromobj = zc->zc_fromobj; 488 zc28_c->zc_createtxg = zc->zc_createtxg; 489 zc28_c->zc_stat = zc->zc_stat; 490#ifndef _KERNEL 491 if (request == ZFS_IOC_RECV) 492 strlcpy(zc28_c->zc_top_ds, 493 zc->zc_value + strlen(zc->zc_value) + 1, 494 MAXPATHLEN * 2 - strlen(zc->zc_value) - 1); 495#endif 496 /* zc_inject_record */ 497 zc28_c->zc_inject_record.zi_objset = 498 zc->zc_inject_record.zi_objset; 499 zc28_c->zc_inject_record.zi_object = 500 zc->zc_inject_record.zi_object; 501 zc28_c->zc_inject_record.zi_start = 502 zc->zc_inject_record.zi_start; 503 zc28_c->zc_inject_record.zi_end = 504 zc->zc_inject_record.zi_end; 505 zc28_c->zc_inject_record.zi_guid = 506 zc->zc_inject_record.zi_guid; 507 zc28_c->zc_inject_record.zi_level = 508 zc->zc_inject_record.zi_level; 509 zc28_c->zc_inject_record.zi_error = 510 zc->zc_inject_record.zi_error; 511 zc28_c->zc_inject_record.zi_type = 512 zc->zc_inject_record.zi_type; 513 zc28_c->zc_inject_record.zi_freq = 514 zc->zc_inject_record.zi_freq; 515 zc28_c->zc_inject_record.zi_failfast = 516 zc->zc_inject_record.zi_failfast; 517 strlcpy(zc28_c->zc_inject_record.zi_func, 518 zc->zc_inject_record.zi_func, MAXNAMELEN); 519 zc28_c->zc_inject_record.zi_iotype = 520 zc->zc_inject_record.zi_iotype; 521 zc28_c->zc_inject_record.zi_duration = 522 zc->zc_inject_record.zi_duration; 523 zc28_c->zc_inject_record.zi_timer = 524 zc->zc_inject_record.zi_timer; 525 break; 526 527 case ZFS_CMD_COMPAT_V15: 528 zc_c = (void *)addr; 529 530 /* zc */ 531 strlcpy(zc_c->zc_name, zc->zc_name, MAXPATHLEN); 532 strlcpy(zc_c->zc_value, zc->zc_value, MAXPATHLEN); 533 strlcpy(zc_c->zc_string, zc->zc_string, MAXPATHLEN); 534 zc_c->zc_guid = zc->zc_guid; 535 zc_c->zc_nvlist_conf = zc->zc_nvlist_conf; 536 zc_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size; 537 zc_c->zc_nvlist_src = zc->zc_nvlist_src; 538 zc_c->zc_nvlist_src_size = zc->zc_nvlist_src_size; 539 zc_c->zc_nvlist_dst = zc->zc_nvlist_dst; 540 zc_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size; 541 zc_c->zc_cookie = zc->zc_cookie; 542 zc_c->zc_objset_type = zc->zc_objset_type; 543 zc_c->zc_perm_action = zc->zc_perm_action; 544 zc_c->zc_history = zc->zc_history; 545 zc_c->zc_history_len = zc->zc_history_len; 546 zc_c->zc_history_offset = zc->zc_history_offset; 547 zc_c->zc_obj = zc->zc_obj; 548 zc_c->zc_share = zc->zc_share; 549 zc_c->zc_jailid = zc->zc_jailid; 550 zc_c->zc_objset_stats = zc->zc_objset_stats; 551 zc_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 552 553 /* zc_inject_record */ 554 zc_c->zc_inject_record.zi_objset = 555 zc->zc_inject_record.zi_objset; 556 zc_c->zc_inject_record.zi_object = 557 zc->zc_inject_record.zi_object; 558 zc_c->zc_inject_record.zi_start = 559 zc->zc_inject_record.zi_start; 560 zc_c->zc_inject_record.zi_end = 561 zc->zc_inject_record.zi_end; 562 zc_c->zc_inject_record.zi_guid = 563 zc->zc_inject_record.zi_guid; 564 zc_c->zc_inject_record.zi_level = 565 zc->zc_inject_record.zi_level; 566 zc_c->zc_inject_record.zi_error = 567 zc->zc_inject_record.zi_error; 568 zc_c->zc_inject_record.zi_type = 569 zc->zc_inject_record.zi_type; 570 zc_c->zc_inject_record.zi_freq = 571 zc->zc_inject_record.zi_freq; 572 zc_c->zc_inject_record.zi_failfast = 573 zc->zc_inject_record.zi_failfast; 574 575 break; 576 } 577} 578 579static int 580zfs_ioctl_compat_get_nvlist(uint64_t nvl, size_t size, int iflag, 581 nvlist_t **nvp) 582{ 583 char *packed; 584 int error; 585 nvlist_t *list = NULL; 586 587 /* 588 * Read in and unpack the user-supplied nvlist. 589 */ 590 if (size == 0) 591 return (EINVAL); 592 593#ifdef _KERNEL 594 packed = kmem_alloc(size, KM_SLEEP); 595 if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size, 596 iflag)) != 0) { 597 kmem_free(packed, size); 598 return (error); 599 } 600#else 601 packed = (void *)(uintptr_t)nvl; 602#endif 603 604 error = nvlist_unpack(packed, size, &list, 0); 605 606#ifdef _KERNEL 607 kmem_free(packed, size); 608#endif 609 610 if (error != 0) 611 return (error); 612 613 *nvp = list; 614 return (0); 615} 616 617static int 618zfs_ioctl_compat_put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl) 619{ 620 char *packed = NULL; 621 int error = 0; 622 size_t size; 623 624 VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0); 625 626#ifdef _KERNEL 627 packed = kmem_alloc(size, KM_SLEEP); 628 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE, 629 KM_SLEEP) == 0); 630 631 if (ddi_copyout(packed, 632 (void *)(uintptr_t)zc->zc_nvlist_dst, size, zc->zc_iflags) != 0) 633 error = EFAULT; 634 kmem_free(packed, size); 635#else 636 packed = (void *)(uintptr_t)zc->zc_nvlist_dst; 637 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE, 638 0) == 0); 639#endif 640 641 zc->zc_nvlist_dst_size = size; 642 return (error); 643} 644 645static void 646zfs_ioctl_compat_fix_stats_nvlist(nvlist_t *nvl) 647{ 648 nvlist_t **child; 649 nvlist_t *nvroot = NULL; 650 vdev_stat_t *vs; 651 uint_t c, children, nelem; 652 653 if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN, 654 &child, &children) == 0) { 655 for (c = 0; c < children; c++) { 656 zfs_ioctl_compat_fix_stats_nvlist(child[c]); 657 } 658 } 659 660 if (nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_VDEV_TREE, 661 &nvroot) == 0) 662 zfs_ioctl_compat_fix_stats_nvlist(nvroot); 663#ifdef _KERNEL 664 if ((nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_VDEV_STATS, 665#else 666 if ((nvlist_lookup_uint64_array(nvl, "stats", 667#endif 668 669 (uint64_t **)&vs, &nelem) == 0)) { 670 nvlist_add_uint64_array(nvl, 671#ifdef _KERNEL 672 "stats", 673#else 674 ZPOOL_CONFIG_VDEV_STATS, 675#endif 676 (uint64_t *)vs, nelem); 677#ifdef _KERNEL 678 nvlist_remove(nvl, ZPOOL_CONFIG_VDEV_STATS, 679#else 680 nvlist_remove(nvl, "stats", 681#endif 682 DATA_TYPE_UINT64_ARRAY); 683 } 684} 685 686static int 687zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int nc) 688{ 689 nvlist_t *nv, *nvp = NULL; 690 nvpair_t *elem; 691 int error; 692 693 if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst, 694 zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0) 695 return (error); 696 697 if (nc == 5) { /* ZFS_IOC_POOL_STATS */ 698 elem = NULL; 699 while ((elem = nvlist_next_nvpair(nv, elem)) != NULL) { 700 if (nvpair_value_nvlist(elem, &nvp) == 0) 701 zfs_ioctl_compat_fix_stats_nvlist(nvp); 702 } 703 elem = NULL; 704 } else 705 zfs_ioctl_compat_fix_stats_nvlist(nv); 706 707 error = zfs_ioctl_compat_put_nvlist(zc, nv); 708 709 nvlist_free(nv); 710 711 return (error); 712} 713 714static int 715zfs_ioctl_compat_pool_get_props(zfs_cmd_t *zc) 716{ 717 nvlist_t *nv, *nva = NULL; 718 int error; 719 720 if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst, 721 zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0) 722 return (error); 723 724#ifdef _KERNEL 725 if (nvlist_lookup_nvlist(nv, "allocated", &nva) == 0) { 726 nvlist_add_nvlist(nv, "used", nva); 727 nvlist_remove(nv, "allocated", DATA_TYPE_NVLIST); 728 } 729 730 if (nvlist_lookup_nvlist(nv, "free", &nva) == 0) { 731 nvlist_add_nvlist(nv, "available", nva); 732 nvlist_remove(nv, "free", DATA_TYPE_NVLIST); 733 } 734#else 735 if (nvlist_lookup_nvlist(nv, "used", &nva) == 0) { 736 nvlist_add_nvlist(nv, "allocated", nva); 737 nvlist_remove(nv, "used", DATA_TYPE_NVLIST); 738 } 739 740 if (nvlist_lookup_nvlist(nv, "available", &nva) == 0) { 741 nvlist_add_nvlist(nv, "free", nva); 742 nvlist_remove(nv, "available", DATA_TYPE_NVLIST); 743 } 744#endif 745 746 error = zfs_ioctl_compat_put_nvlist(zc, nv); 747 748 nvlist_free(nv); 749 750 return (error); 751} 752 753#ifndef _KERNEL 754int 755zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag) 756{ 757 int nc, ret; 758 void *zc_c; 759 unsigned long ncmd; 760 zfs_iocparm_t zp; 761 762 switch (cflag) { 763 case ZFS_CMD_COMPAT_NONE: 764 ncmd = _IOWR('Z', request, struct zfs_iocparm); 765 zp.zfs_cmd = (uint64_t)zc; 766 zp.zfs_cmd_size = sizeof(zfs_cmd_t); 767 zp.zfs_ioctl_version = ZFS_IOCVER_CURRENT; 768 return (ioctl(fd, ncmd, &zp)); 769 case ZFS_CMD_COMPAT_EDBP: 770 ncmd = _IOWR('Z', request, struct zfs_iocparm); 771 zp.zfs_cmd = (uint64_t)zc; 772 zp.zfs_cmd_size = sizeof(zfs_cmd_edbp_t); 773 zp.zfs_ioctl_version = ZFS_IOCVER_EDBP; 774 return (ioctl(fd, ncmd, &zp)); 775 case ZFS_CMD_COMPAT_ZCMD: 776 ncmd = _IOWR('Z', request, struct zfs_iocparm); 777 zp.zfs_cmd = (uint64_t)zc; 778 zp.zfs_cmd_size = sizeof(zfs_cmd_zcmd_t); 779 zp.zfs_ioctl_version = ZFS_IOCVER_ZCMD; 780 return (ioctl(fd, ncmd, &zp)); 781 case ZFS_CMD_COMPAT_LZC: 782 ncmd = _IOWR('Z', request, struct zfs_cmd); 783 return (ioctl(fd, ncmd, zc)); 784 case ZFS_CMD_COMPAT_DEADMAN: 785 zc_c = malloc(sizeof(zfs_cmd_deadman_t)); 786 ncmd = _IOWR('Z', request, struct zfs_cmd_deadman); 787 break; 788 case ZFS_CMD_COMPAT_V28: 789 zc_c = malloc(sizeof(zfs_cmd_v28_t)); 790 ncmd = _IOWR('Z', request, struct zfs_cmd_v28); 791 break; 792 case ZFS_CMD_COMPAT_V15: 793 nc = zfs_ioctl_v28_to_v15[request]; 794 zc_c = malloc(sizeof(zfs_cmd_v15_t)); 795 ncmd = _IOWR('Z', nc, struct zfs_cmd_v15); 796 break; 797 default: 798 return (EINVAL); 799 } 800 801 if (ZFS_IOCREQ(ncmd) == ZFS_IOC_COMPAT_FAIL) 802 return (ENOTSUP); 803 804 zfs_cmd_compat_put(zc, (caddr_t)zc_c, request, cflag); 805 806 ret = ioctl(fd, ncmd, zc_c); 807 if (cflag == ZFS_CMD_COMPAT_V15 && 808 nc == ZFS_IOC_POOL_IMPORT) 809 ret = ioctl(fd, _IOWR('Z', ZFS_IOC_POOL_CONFIGS, 810 struct zfs_cmd_v15), zc_c); 811 zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag); 812 free(zc_c); 813 814 if (cflag == ZFS_CMD_COMPAT_V15) { 815 switch (nc) { 816 case ZFS_IOC_POOL_IMPORT: 817 case ZFS_IOC_POOL_CONFIGS: 818 case ZFS_IOC_POOL_STATS: 819 case ZFS_IOC_POOL_TRYIMPORT: 820 zfs_ioctl_compat_fix_stats(zc, nc); 821 break; 822 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */ 823 zfs_ioctl_compat_pool_get_props(zc); 824 break; 825 } 826 } 827 828 return (ret); 829} 830#else /* _KERNEL */ 831int 832zfs_ioctl_compat_pre(zfs_cmd_t *zc, int *vec, const int cflag) 833{ 834 int error = 0; 835 836 /* are we creating a clone? */ 837 if (*vec == ZFS_IOC_CREATE && zc->zc_value[0] != '\0') 838 *vec = ZFS_IOC_CLONE; 839 840 if (cflag == ZFS_CMD_COMPAT_V15) { 841 switch (*vec) { 842 843 case 7: /* ZFS_IOC_POOL_SCRUB (v15) */ 844 zc->zc_cookie = POOL_SCAN_SCRUB; 845 break; 846 } 847 } 848 849 return (error); 850} 851 852void 853zfs_ioctl_compat_post(zfs_cmd_t *zc, int vec, const int cflag) 854{ 855 if (cflag == ZFS_CMD_COMPAT_V15) { 856 switch (vec) { 857 case ZFS_IOC_POOL_CONFIGS: 858 case ZFS_IOC_POOL_STATS: 859 case ZFS_IOC_POOL_TRYIMPORT: 860 zfs_ioctl_compat_fix_stats(zc, vec); 861 break; 862 case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */ 863 zfs_ioctl_compat_pool_get_props(zc); 864 break; 865 } 866 } 867} 868 869nvlist_t * 870zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec, 871 const int cflag) 872{ 873 nvlist_t *nvl, *tmpnvl, *hnvl; 874 nvpair_t *elem; 875 char *poolname, *snapname; 876 int err; 877 878 if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC || 879 cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP) 880 goto out; 881 882 switch (vec) { 883 case ZFS_IOC_CREATE: 884 nvl = fnvlist_alloc(); 885 fnvlist_add_int32(nvl, "type", zc->zc_objset_type); 886 if (innvl != NULL) { 887 fnvlist_add_nvlist(nvl, "props", innvl); 888 nvlist_free(innvl); 889 } 890 return (nvl); 891 break; 892 case ZFS_IOC_CLONE: 893 nvl = fnvlist_alloc(); 894 fnvlist_add_string(nvl, "origin", zc->zc_value); 895 if (innvl != NULL) { 896 fnvlist_add_nvlist(nvl, "props", innvl); 897 nvlist_free(innvl); 898 } 899 return (nvl); 900 break; 901 case ZFS_IOC_SNAPSHOT: 902 if (innvl == NULL) 903 goto out; 904 nvl = fnvlist_alloc(); 905 fnvlist_add_nvlist(nvl, "props", innvl); 906 tmpnvl = fnvlist_alloc(); 907 snapname = kmem_asprintf("%s@%s", zc->zc_name, zc->zc_value); 908 fnvlist_add_boolean(tmpnvl, snapname); 909 kmem_free(snapname, strlen(snapname + 1)); 910 /* check if we are doing a recursive snapshot */ 911 if (zc->zc_cookie) 912 dmu_get_recursive_snaps_nvl(zc->zc_name, zc->zc_value, 913 tmpnvl); 914 fnvlist_add_nvlist(nvl, "snaps", tmpnvl); 915 fnvlist_free(tmpnvl); 916 nvlist_free(innvl); 917 /* strip dataset part from zc->zc_name */ 918 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0'; 919 return (nvl); 920 break; 921 case ZFS_IOC_SPACE_SNAPS: 922 nvl = fnvlist_alloc(); 923 fnvlist_add_string(nvl, "firstsnap", zc->zc_value); 924 if (innvl != NULL) 925 nvlist_free(innvl); 926 return (nvl); 927 break; 928 case ZFS_IOC_DESTROY_SNAPS: 929 if (innvl == NULL && cflag == ZFS_CMD_COMPAT_DEADMAN) 930 goto out; 931 nvl = fnvlist_alloc(); 932 if (innvl != NULL) { 933 fnvlist_add_nvlist(nvl, "snaps", innvl); 934 } else { 935 /* 936 * We are probably called by even older binaries, 937 * allocate and populate nvlist with recursive 938 * snapshots 939 */ 940 if (zfs_component_namecheck(zc->zc_value, NULL, 941 NULL) == 0) { 942 tmpnvl = fnvlist_alloc(); 943 if (dmu_get_recursive_snaps_nvl(zc->zc_name, 944 zc->zc_value, tmpnvl) == 0) 945 fnvlist_add_nvlist(nvl, "snaps", 946 tmpnvl); 947 nvlist_free(tmpnvl); 948 } 949 } 950 if (innvl != NULL) 951 nvlist_free(innvl); 952 /* strip dataset part from zc->zc_name */ 953 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0'; 954 return (nvl); 955 break; 956 case ZFS_IOC_HOLD: 957 nvl = fnvlist_alloc(); 958 tmpnvl = fnvlist_alloc(); 959 if (zc->zc_cleanup_fd != -1) 960 fnvlist_add_int32(nvl, "cleanup_fd", 961 (int32_t)zc->zc_cleanup_fd); 962 if (zc->zc_cookie) { 963 hnvl = fnvlist_alloc(); 964 if (dmu_get_recursive_snaps_nvl(zc->zc_name, 965 zc->zc_value, hnvl) == 0) { 966 elem = NULL; 967 while ((elem = nvlist_next_nvpair(hnvl, 968 elem)) != NULL) { 969 nvlist_add_string(tmpnvl, 970 nvpair_name(elem), zc->zc_string); 971 } 972 } 973 nvlist_free(hnvl); 974 } else { 975 snapname = kmem_asprintf("%s@%s", zc->zc_name, 976 zc->zc_value); 977 nvlist_add_string(tmpnvl, snapname, zc->zc_string); 978 kmem_free(snapname, strlen(snapname + 1)); 979 } 980 fnvlist_add_nvlist(nvl, "holds", tmpnvl); 981 nvlist_free(tmpnvl); 982 if (innvl != NULL) 983 nvlist_free(innvl); 984 /* strip dataset part from zc->zc_name */ 985 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0'; 986 return (nvl); 987 break; 988 case ZFS_IOC_RELEASE: 989 nvl = fnvlist_alloc(); 990 tmpnvl = fnvlist_alloc(); 991 if (zc->zc_cookie) { 992 hnvl = fnvlist_alloc(); 993 if (dmu_get_recursive_snaps_nvl(zc->zc_name, 994 zc->zc_value, hnvl) == 0) { 995 elem = NULL; 996 while ((elem = nvlist_next_nvpair(hnvl, 997 elem)) != NULL) { 998 fnvlist_add_boolean(tmpnvl, 999 zc->zc_string); 1000 fnvlist_add_nvlist(nvl, 1001 nvpair_name(elem), tmpnvl); 1002 } 1003 } 1004 nvlist_free(hnvl); 1005 } else { 1006 snapname = kmem_asprintf("%s@%s", zc->zc_name, 1007 zc->zc_value); 1008 fnvlist_add_boolean(tmpnvl, zc->zc_string); 1009 fnvlist_add_nvlist(nvl, snapname, tmpnvl); 1010 kmem_free(snapname, strlen(snapname + 1)); 1011 } 1012 nvlist_free(tmpnvl); 1013 if (innvl != NULL) 1014 nvlist_free(innvl); 1015 /* strip dataset part from zc->zc_name */ 1016 zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0'; 1017 return (nvl); 1018 break; 1019 } 1020out: 1021 return (innvl); 1022} 1023 1024nvlist_t * 1025zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec, 1026 const int cflag) 1027{ 1028 nvlist_t *tmpnvl; 1029 1030 if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC || 1031 cflag == ZFS_CMD_COMPAT_ZCMD || cflag == ZFS_CMD_COMPAT_EDBP) 1032 return (outnvl); 1033 1034 switch (vec) { 1035 case ZFS_IOC_SPACE_SNAPS: 1036 (void) nvlist_lookup_uint64(outnvl, "used", &zc->zc_cookie); 1037 (void) nvlist_lookup_uint64(outnvl, "compressed", 1038 &zc->zc_objset_type); 1039 (void) nvlist_lookup_uint64(outnvl, "uncompressed", 1040 &zc->zc_perm_action); 1041 nvlist_free(outnvl); 1042 /* return empty outnvl */ 1043 tmpnvl = fnvlist_alloc(); 1044 return (tmpnvl); 1045 break; 1046 case ZFS_IOC_CREATE: 1047 case ZFS_IOC_CLONE: 1048 case ZFS_IOC_HOLD: 1049 case ZFS_IOC_RELEASE: 1050 nvlist_free(outnvl); 1051 /* return empty outnvl */ 1052 tmpnvl = fnvlist_alloc(); 1053 return (tmpnvl); 1054 break; 1055 } 1056 1057 return (outnvl); 1058} 1059#endif /* KERNEL */ 1060