zfs_ioctl_compat.c revision 307054
1279377Simp/* 2279377Simp * CDDL HEADER START 3279377Simp * 4279377Simp * The contents of this file are subject to the terms of the 5279377Simp * Common Development and Distribution License (the "License"). 6279377Simp * You may not use this file except in compliance with the License. 7279377Simp * 8279377Simp * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9279377Simp * or http://www.opensolaris.org/os/licensing. 10279377Simp * See the License for the specific language governing permissions 11279377Simp * and limitations under the License. 12279377Simp * 13279377Simp * When distributing Covered Code, include this CDDL HEADER in each 14279377Simp * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15279377Simp * If applicable, add the following below this CDDL HEADER, with the 16279377Simp * fields enclosed by brackets "[]" replaced with your own identifying 17279377Simp * information: Portions Copyright [yyyy] [name of copyright owner] 18279377Simp * 19279377Simp * CDDL HEADER END 20279377Simp */ 21279377Simp/* 22279377Simp * Copyright 2013 Xin Li <delphij@FreeBSD.org>. All rights reserved. 23279377Simp * Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved. 24279377Simp * Portions Copyright 2005, 2010, Oracle and/or its affiliates. 25279377Simp * All rights reserved. 26279377Simp * Use is subject to license terms. 27279377Simp */ 28279377Simp 29279377Simp#include <sys/types.h> 30279377Simp#include <sys/param.h> 31279377Simp#include <sys/cred.h> 32279377Simp#include <sys/dmu.h> 33279377Simp#include <sys/zio.h> 34279377Simp#include <sys/nvpair.h> 35279377Simp#include <sys/dsl_deleg.h> 36279377Simp#include <sys/zfs_ioctl.h> 37279377Simp#include "zfs_namecheck.h" 38279377Simp#include "zfs_ioctl_compat.h" 39279377Simp 40279377Simpstatic int zfs_version_ioctl = ZFS_IOCVER_CURRENT; 41279377SimpSYSCTL_DECL(_vfs_zfs_version); 42279377SimpSYSCTL_INT(_vfs_zfs_version, OID_AUTO, ioctl, CTLFLAG_RD, &zfs_version_ioctl, 43279377Simp 0, "ZFS_IOCTL_VERSION"); 44279377Simp 45279377Simp/* 46279377Simp * FreeBSD zfs_cmd compatibility with older binaries 47279377Simp * appropriately remap/extend the zfs_cmd_t structure 48279377Simp */ 49279377Simpvoid 50279377Simpzfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag) 51279377Simp{ 52279377Simp zfs_cmd_v15_t *zc_c; 53279377Simp zfs_cmd_v28_t *zc28_c; 54279377Simp zfs_cmd_deadman_t *zcdm_c; 55279377Simp zfs_cmd_zcmd_t *zcmd_c; 56279377Simp zfs_cmd_edbp_t *edbp_c; 57279377Simp zfs_cmd_resume_t *resume_c; 58279377Simp zfs_cmd_inlanes_t *inlanes_c; 59279377Simp 60279377Simp switch (cflag) { 61279377Simp case ZFS_CMD_COMPAT_INLANES: 62279377Simp inlanes_c = (void *)addr; 63279377Simp /* zc */ 64279377Simp strlcpy(zc->zc_name, inlanes_c->zc_name, MAXPATHLEN); 65279377Simp strlcpy(zc->zc_value, inlanes_c->zc_value, MAXPATHLEN * 2); 66279377Simp strlcpy(zc->zc_string, inlanes_c->zc_string, MAXPATHLEN); 67279377Simp 68279377Simp#define FIELD_COPY(field) zc->field = inlanes_c->field 69279377Simp FIELD_COPY(zc_nvlist_src); 70279377Simp FIELD_COPY(zc_nvlist_src_size); 71279377Simp FIELD_COPY(zc_nvlist_dst); 72279377Simp FIELD_COPY(zc_nvlist_dst_size); 73279377Simp FIELD_COPY(zc_nvlist_dst_filled); 74279377Simp FIELD_COPY(zc_pad2); 75279377Simp FIELD_COPY(zc_history); 76279377Simp FIELD_COPY(zc_guid); 77279377Simp FIELD_COPY(zc_nvlist_conf); 78279377Simp FIELD_COPY(zc_nvlist_conf_size); 79279377Simp FIELD_COPY(zc_cookie); 80279377Simp FIELD_COPY(zc_objset_type); 81279377Simp FIELD_COPY(zc_perm_action); 82279377Simp FIELD_COPY(zc_history_len); 83279377Simp FIELD_COPY(zc_history_offset); 84279377Simp FIELD_COPY(zc_obj); 85279377Simp FIELD_COPY(zc_iflags); 86279377Simp FIELD_COPY(zc_share); 87279377Simp FIELD_COPY(zc_jailid); 88279377Simp FIELD_COPY(zc_objset_stats); 89279377Simp FIELD_COPY(zc_begin_record); 90279377Simp FIELD_COPY(zc_inject_record); 91279377Simp FIELD_COPY(zc_defer_destroy); 92279377Simp FIELD_COPY(zc_flags); 93279377Simp FIELD_COPY(zc_action_handle); 94279377Simp FIELD_COPY(zc_cleanup_fd); 95279377Simp FIELD_COPY(zc_simple); 96279377Simp FIELD_COPY(zc_resumable); 97279377Simp FIELD_COPY(zc_sendobj); 98279377Simp FIELD_COPY(zc_fromobj); 99279377Simp FIELD_COPY(zc_createtxg); 100279377Simp FIELD_COPY(zc_stat); 101279377Simp#undef FIELD_COPY 102279377Simp break; 103279377Simp 104279377Simp case ZFS_CMD_COMPAT_RESUME: 105279377Simp resume_c = (void *)addr; 106279377Simp /* zc */ 107279377Simp strlcpy(zc->zc_name, resume_c->zc_name, MAXPATHLEN); 108279377Simp strlcpy(zc->zc_value, resume_c->zc_value, MAXPATHLEN * 2); 109279377Simp strlcpy(zc->zc_string, resume_c->zc_string, MAXPATHLEN); 110279377Simp 111279377Simp#define FIELD_COPY(field) zc->field = resume_c->field 112279377Simp FIELD_COPY(zc_nvlist_src); 113279377Simp FIELD_COPY(zc_nvlist_src_size); 114279377Simp FIELD_COPY(zc_nvlist_dst); 115279377Simp FIELD_COPY(zc_nvlist_dst_size); 116279377Simp FIELD_COPY(zc_nvlist_dst_filled); 117279377Simp FIELD_COPY(zc_pad2); 118279377Simp FIELD_COPY(zc_history); 119279377Simp FIELD_COPY(zc_guid); 120279377Simp FIELD_COPY(zc_nvlist_conf); 121279377Simp FIELD_COPY(zc_nvlist_conf_size); 122279377Simp FIELD_COPY(zc_cookie); 123279377Simp FIELD_COPY(zc_objset_type); 124279377Simp FIELD_COPY(zc_perm_action); 125279377Simp FIELD_COPY(zc_history_len); 126279377Simp FIELD_COPY(zc_history_offset); 127279377Simp FIELD_COPY(zc_obj); 128279377Simp FIELD_COPY(zc_iflags); 129279377Simp FIELD_COPY(zc_share); 130279377Simp FIELD_COPY(zc_jailid); 131279377Simp FIELD_COPY(zc_objset_stats); 132279377Simp FIELD_COPY(zc_begin_record); 133279377Simp FIELD_COPY(zc_inject_record.zi_objset); 134279377Simp FIELD_COPY(zc_inject_record.zi_object); 135279377Simp FIELD_COPY(zc_inject_record.zi_start); 136279377Simp FIELD_COPY(zc_inject_record.zi_end); 137279377Simp FIELD_COPY(zc_inject_record.zi_guid); 138279377Simp FIELD_COPY(zc_inject_record.zi_level); 139279377Simp FIELD_COPY(zc_inject_record.zi_error); 140279377Simp FIELD_COPY(zc_inject_record.zi_type); 141279377Simp FIELD_COPY(zc_inject_record.zi_freq); 142279377Simp FIELD_COPY(zc_inject_record.zi_failfast); 143279377Simp strlcpy(zc->zc_inject_record.zi_func, 144279377Simp resume_c->zc_inject_record.zi_func, MAXNAMELEN); 145279377Simp FIELD_COPY(zc_inject_record.zi_iotype); 146279377Simp FIELD_COPY(zc_inject_record.zi_duration); 147279377Simp FIELD_COPY(zc_inject_record.zi_timer); 148279377Simp zc->zc_inject_record.zi_nlanes = 1; 149279377Simp FIELD_COPY(zc_inject_record.zi_cmd); 150279377Simp FIELD_COPY(zc_inject_record.zi_pad); 151279377Simp FIELD_COPY(zc_defer_destroy); 152279377Simp FIELD_COPY(zc_flags); 153279377Simp FIELD_COPY(zc_action_handle); 154279377Simp FIELD_COPY(zc_cleanup_fd); 155279377Simp FIELD_COPY(zc_simple); 156279377Simp FIELD_COPY(zc_resumable); 157279377Simp FIELD_COPY(zc_sendobj); 158279377Simp FIELD_COPY(zc_fromobj); 159279377Simp FIELD_COPY(zc_createtxg); 160279377Simp FIELD_COPY(zc_stat); 161279377Simp#undef FIELD_COPY 162279377Simp break; 163279377Simp 164279377Simp case ZFS_CMD_COMPAT_EDBP: 165279377Simp edbp_c = (void *)addr; 166279377Simp /* zc */ 167279377Simp strlcpy(zc->zc_name, edbp_c->zc_name, MAXPATHLEN); 168279377Simp strlcpy(zc->zc_value, edbp_c->zc_value, MAXPATHLEN * 2); 169279377Simp strlcpy(zc->zc_string, edbp_c->zc_string, MAXPATHLEN); 170279377Simp 171279377Simp#define FIELD_COPY(field) zc->field = edbp_c->field 172279377Simp FIELD_COPY(zc_nvlist_src); 173279377Simp FIELD_COPY(zc_nvlist_src_size); 174279377Simp FIELD_COPY(zc_nvlist_dst); 175279377Simp FIELD_COPY(zc_nvlist_dst_size); 176279377Simp FIELD_COPY(zc_nvlist_dst_filled); 177279377Simp FIELD_COPY(zc_pad2); 178279377Simp FIELD_COPY(zc_history); 179279377Simp FIELD_COPY(zc_guid); 180279377Simp FIELD_COPY(zc_nvlist_conf); 181279377Simp FIELD_COPY(zc_nvlist_conf_size); 182279377Simp FIELD_COPY(zc_cookie); 183279377Simp FIELD_COPY(zc_objset_type); 184279377Simp FIELD_COPY(zc_perm_action); 185279377Simp FIELD_COPY(zc_history_len); 186279377Simp FIELD_COPY(zc_history_offset); 187279377Simp FIELD_COPY(zc_obj); 188279377Simp FIELD_COPY(zc_iflags); 189279377Simp FIELD_COPY(zc_share); 190279377Simp FIELD_COPY(zc_jailid); 191279377Simp FIELD_COPY(zc_objset_stats); 192279377Simp zc->zc_begin_record.drr_u.drr_begin = edbp_c->zc_begin_record; 193279377Simp FIELD_COPY(zc_inject_record.zi_objset); 194279377Simp FIELD_COPY(zc_inject_record.zi_object); 195279377Simp FIELD_COPY(zc_inject_record.zi_start); 196279377Simp FIELD_COPY(zc_inject_record.zi_end); 197279377Simp FIELD_COPY(zc_inject_record.zi_guid); 198279377Simp FIELD_COPY(zc_inject_record.zi_level); 199279377Simp FIELD_COPY(zc_inject_record.zi_error); 200279377Simp FIELD_COPY(zc_inject_record.zi_type); 201279377Simp FIELD_COPY(zc_inject_record.zi_freq); 202279377Simp FIELD_COPY(zc_inject_record.zi_failfast); 203279377Simp strlcpy(zc->zc_inject_record.zi_func, 204279377Simp edbp_c->zc_inject_record.zi_func, MAXNAMELEN); 205279377Simp FIELD_COPY(zc_inject_record.zi_iotype); 206279377Simp FIELD_COPY(zc_inject_record.zi_duration); 207279377Simp FIELD_COPY(zc_inject_record.zi_timer); 208279377Simp zc->zc_inject_record.zi_nlanes = 1; 209279377Simp FIELD_COPY(zc_inject_record.zi_cmd); 210279377Simp FIELD_COPY(zc_inject_record.zi_pad); 211279377Simp FIELD_COPY(zc_defer_destroy); 212279377Simp FIELD_COPY(zc_flags); 213279377Simp FIELD_COPY(zc_action_handle); 214279377Simp FIELD_COPY(zc_cleanup_fd); 215279377Simp FIELD_COPY(zc_simple); 216279377Simp zc->zc_resumable = B_FALSE; 217279377Simp FIELD_COPY(zc_sendobj); 218279377Simp FIELD_COPY(zc_fromobj); 219279377Simp FIELD_COPY(zc_createtxg); 220279377Simp FIELD_COPY(zc_stat); 221279377Simp#undef FIELD_COPY 222279377Simp break; 223279377Simp 224279377Simp case ZFS_CMD_COMPAT_ZCMD: 225279377Simp zcmd_c = (void *)addr; 226279377Simp /* zc */ 227279377Simp strlcpy(zc->zc_name, zcmd_c->zc_name, MAXPATHLEN); 228279377Simp strlcpy(zc->zc_value, zcmd_c->zc_value, MAXPATHLEN * 2); 229279377Simp strlcpy(zc->zc_string, zcmd_c->zc_string, MAXPATHLEN); 230279377Simp 231279377Simp#define FIELD_COPY(field) zc->field = zcmd_c->field 232279377Simp FIELD_COPY(zc_nvlist_src); 233279377Simp FIELD_COPY(zc_nvlist_src_size); 234279377Simp FIELD_COPY(zc_nvlist_dst); 235279377Simp FIELD_COPY(zc_nvlist_dst_size); 236279377Simp FIELD_COPY(zc_nvlist_dst_filled); 237279377Simp FIELD_COPY(zc_pad2); 238279377Simp FIELD_COPY(zc_history); 239279377Simp FIELD_COPY(zc_guid); 240279377Simp FIELD_COPY(zc_nvlist_conf); 241279377Simp FIELD_COPY(zc_nvlist_conf_size); 242279377Simp FIELD_COPY(zc_cookie); 243279377Simp FIELD_COPY(zc_objset_type); 244279377Simp FIELD_COPY(zc_perm_action); 245279377Simp FIELD_COPY(zc_history_len); 246279377Simp FIELD_COPY(zc_history_offset); 247279377Simp FIELD_COPY(zc_obj); 248279377Simp FIELD_COPY(zc_iflags); 249279377Simp FIELD_COPY(zc_share); 250279377Simp FIELD_COPY(zc_jailid); 251279377Simp FIELD_COPY(zc_objset_stats); 252279377Simp zc->zc_begin_record.drr_u.drr_begin = zcmd_c->zc_begin_record; 253279377Simp FIELD_COPY(zc_inject_record.zi_objset); 254279377Simp FIELD_COPY(zc_inject_record.zi_object); 255 FIELD_COPY(zc_inject_record.zi_start); 256 FIELD_COPY(zc_inject_record.zi_end); 257 FIELD_COPY(zc_inject_record.zi_guid); 258 FIELD_COPY(zc_inject_record.zi_level); 259 FIELD_COPY(zc_inject_record.zi_error); 260 FIELD_COPY(zc_inject_record.zi_type); 261 FIELD_COPY(zc_inject_record.zi_freq); 262 FIELD_COPY(zc_inject_record.zi_failfast); 263 strlcpy(zc->zc_inject_record.zi_func, 264 zcmd_c->zc_inject_record.zi_func, MAXNAMELEN); 265 FIELD_COPY(zc_inject_record.zi_iotype); 266 FIELD_COPY(zc_inject_record.zi_duration); 267 FIELD_COPY(zc_inject_record.zi_timer); 268 zc->zc_inject_record.zi_nlanes = 1; 269 FIELD_COPY(zc_inject_record.zi_cmd); 270 FIELD_COPY(zc_inject_record.zi_pad); 271 272 /* boolean_t -> uint32_t */ 273 zc->zc_defer_destroy = (uint32_t)(zcmd_c->zc_defer_destroy); 274 zc->zc_flags = 0; 275 276 FIELD_COPY(zc_action_handle); 277 FIELD_COPY(zc_cleanup_fd); 278 FIELD_COPY(zc_simple); 279 zc->zc_resumable = B_FALSE; 280 FIELD_COPY(zc_sendobj); 281 FIELD_COPY(zc_fromobj); 282 FIELD_COPY(zc_createtxg); 283 FIELD_COPY(zc_stat); 284#undef FIELD_COPY 285 286 break; 287 288 case ZFS_CMD_COMPAT_DEADMAN: 289 zcdm_c = (void *)addr; 290 /* zc */ 291 strlcpy(zc->zc_name, zcdm_c->zc_name, MAXPATHLEN); 292 strlcpy(zc->zc_value, zcdm_c->zc_value, MAXPATHLEN * 2); 293 strlcpy(zc->zc_string, zcdm_c->zc_string, MAXPATHLEN); 294 295#define FIELD_COPY(field) zc->field = zcdm_c->field 296 zc->zc_guid = zcdm_c->zc_guid; 297 zc->zc_nvlist_conf = zcdm_c->zc_nvlist_conf; 298 zc->zc_nvlist_conf_size = zcdm_c->zc_nvlist_conf_size; 299 zc->zc_nvlist_src = zcdm_c->zc_nvlist_src; 300 zc->zc_nvlist_src_size = zcdm_c->zc_nvlist_src_size; 301 zc->zc_nvlist_dst = zcdm_c->zc_nvlist_dst; 302 zc->zc_nvlist_dst_size = zcdm_c->zc_nvlist_dst_size; 303 zc->zc_cookie = zcdm_c->zc_cookie; 304 zc->zc_objset_type = zcdm_c->zc_objset_type; 305 zc->zc_perm_action = zcdm_c->zc_perm_action; 306 zc->zc_history = zcdm_c->zc_history; 307 zc->zc_history_len = zcdm_c->zc_history_len; 308 zc->zc_history_offset = zcdm_c->zc_history_offset; 309 zc->zc_obj = zcdm_c->zc_obj; 310 zc->zc_iflags = zcdm_c->zc_iflags; 311 zc->zc_share = zcdm_c->zc_share; 312 zc->zc_jailid = zcdm_c->zc_jailid; 313 zc->zc_objset_stats = zcdm_c->zc_objset_stats; 314 zc->zc_begin_record.drr_u.drr_begin = zcdm_c->zc_begin_record; 315 zc->zc_defer_destroy = zcdm_c->zc_defer_destroy; 316 (void)zcdm_c->zc_temphold; 317 zc->zc_action_handle = zcdm_c->zc_action_handle; 318 zc->zc_cleanup_fd = zcdm_c->zc_cleanup_fd; 319 zc->zc_simple = zcdm_c->zc_simple; 320 zc->zc_resumable = B_FALSE; 321 zc->zc_sendobj = zcdm_c->zc_sendobj; 322 zc->zc_fromobj = zcdm_c->zc_fromobj; 323 zc->zc_createtxg = zcdm_c->zc_createtxg; 324 zc->zc_stat = zcdm_c->zc_stat; 325 FIELD_COPY(zc_inject_record.zi_objset); 326 FIELD_COPY(zc_inject_record.zi_object); 327 FIELD_COPY(zc_inject_record.zi_start); 328 FIELD_COPY(zc_inject_record.zi_end); 329 FIELD_COPY(zc_inject_record.zi_guid); 330 FIELD_COPY(zc_inject_record.zi_level); 331 FIELD_COPY(zc_inject_record.zi_error); 332 FIELD_COPY(zc_inject_record.zi_type); 333 FIELD_COPY(zc_inject_record.zi_freq); 334 FIELD_COPY(zc_inject_record.zi_failfast); 335 strlcpy(zc->zc_inject_record.zi_func, 336 resume_c->zc_inject_record.zi_func, MAXNAMELEN); 337 FIELD_COPY(zc_inject_record.zi_iotype); 338 FIELD_COPY(zc_inject_record.zi_duration); 339 FIELD_COPY(zc_inject_record.zi_timer); 340 zc->zc_inject_record.zi_nlanes = 1; 341 FIELD_COPY(zc_inject_record.zi_cmd); 342 FIELD_COPY(zc_inject_record.zi_pad); 343 344 /* we always assume zc_nvlist_dst_filled is true */ 345 zc->zc_nvlist_dst_filled = B_TRUE; 346#undef FIELD_COPY 347 break; 348 349 case ZFS_CMD_COMPAT_V28: 350 zc28_c = (void *)addr; 351 352 /* zc */ 353 strlcpy(zc->zc_name, zc28_c->zc_name, MAXPATHLEN); 354 strlcpy(zc->zc_value, zc28_c->zc_value, MAXPATHLEN * 2); 355 strlcpy(zc->zc_string, zc28_c->zc_string, MAXPATHLEN); 356 zc->zc_guid = zc28_c->zc_guid; 357 zc->zc_nvlist_conf = zc28_c->zc_nvlist_conf; 358 zc->zc_nvlist_conf_size = zc28_c->zc_nvlist_conf_size; 359 zc->zc_nvlist_src = zc28_c->zc_nvlist_src; 360 zc->zc_nvlist_src_size = zc28_c->zc_nvlist_src_size; 361 zc->zc_nvlist_dst = zc28_c->zc_nvlist_dst; 362 zc->zc_nvlist_dst_size = zc28_c->zc_nvlist_dst_size; 363 zc->zc_cookie = zc28_c->zc_cookie; 364 zc->zc_objset_type = zc28_c->zc_objset_type; 365 zc->zc_perm_action = zc28_c->zc_perm_action; 366 zc->zc_history = zc28_c->zc_history; 367 zc->zc_history_len = zc28_c->zc_history_len; 368 zc->zc_history_offset = zc28_c->zc_history_offset; 369 zc->zc_obj = zc28_c->zc_obj; 370 zc->zc_iflags = zc28_c->zc_iflags; 371 zc->zc_share = zc28_c->zc_share; 372 zc->zc_jailid = zc28_c->zc_jailid; 373 zc->zc_objset_stats = zc28_c->zc_objset_stats; 374 zc->zc_begin_record.drr_u.drr_begin = zc28_c->zc_begin_record; 375 zc->zc_defer_destroy = zc28_c->zc_defer_destroy; 376 (void)zc28_c->zc_temphold; 377 zc->zc_action_handle = zc28_c->zc_action_handle; 378 zc->zc_cleanup_fd = zc28_c->zc_cleanup_fd; 379 zc->zc_simple = zc28_c->zc_simple; 380 zc->zc_resumable = B_FALSE; 381 zc->zc_sendobj = zc28_c->zc_sendobj; 382 zc->zc_fromobj = zc28_c->zc_fromobj; 383 zc->zc_createtxg = zc28_c->zc_createtxg; 384 zc->zc_stat = zc28_c->zc_stat; 385 386 /* zc->zc_inject_record */ 387 zc->zc_inject_record.zi_objset = 388 zc28_c->zc_inject_record.zi_objset; 389 zc->zc_inject_record.zi_object = 390 zc28_c->zc_inject_record.zi_object; 391 zc->zc_inject_record.zi_start = 392 zc28_c->zc_inject_record.zi_start; 393 zc->zc_inject_record.zi_end = 394 zc28_c->zc_inject_record.zi_end; 395 zc->zc_inject_record.zi_guid = 396 zc28_c->zc_inject_record.zi_guid; 397 zc->zc_inject_record.zi_level = 398 zc28_c->zc_inject_record.zi_level; 399 zc->zc_inject_record.zi_error = 400 zc28_c->zc_inject_record.zi_error; 401 zc->zc_inject_record.zi_type = 402 zc28_c->zc_inject_record.zi_type; 403 zc->zc_inject_record.zi_freq = 404 zc28_c->zc_inject_record.zi_freq; 405 zc->zc_inject_record.zi_failfast = 406 zc28_c->zc_inject_record.zi_failfast; 407 strlcpy(zc->zc_inject_record.zi_func, 408 zc28_c->zc_inject_record.zi_func, MAXNAMELEN); 409 zc->zc_inject_record.zi_iotype = 410 zc28_c->zc_inject_record.zi_iotype; 411 zc->zc_inject_record.zi_duration = 412 zc28_c->zc_inject_record.zi_duration; 413 zc->zc_inject_record.zi_timer = 414 zc28_c->zc_inject_record.zi_timer; 415 zc->zc_inject_record.zi_nlanes = 1; 416 zc->zc_inject_record.zi_cmd = ZINJECT_UNINITIALIZED; 417 zc->zc_inject_record.zi_pad = 0; 418 break; 419 420 case ZFS_CMD_COMPAT_V15: 421 zc_c = (void *)addr; 422 423 /* zc */ 424 strlcpy(zc->zc_name, zc_c->zc_name, MAXPATHLEN); 425 strlcpy(zc->zc_value, zc_c->zc_value, MAXPATHLEN); 426 strlcpy(zc->zc_string, zc_c->zc_string, MAXPATHLEN); 427 zc->zc_guid = zc_c->zc_guid; 428 zc->zc_nvlist_conf = zc_c->zc_nvlist_conf; 429 zc->zc_nvlist_conf_size = zc_c->zc_nvlist_conf_size; 430 zc->zc_nvlist_src = zc_c->zc_nvlist_src; 431 zc->zc_nvlist_src_size = zc_c->zc_nvlist_src_size; 432 zc->zc_nvlist_dst = zc_c->zc_nvlist_dst; 433 zc->zc_nvlist_dst_size = zc_c->zc_nvlist_dst_size; 434 zc->zc_cookie = zc_c->zc_cookie; 435 zc->zc_objset_type = zc_c->zc_objset_type; 436 zc->zc_perm_action = zc_c->zc_perm_action; 437 zc->zc_history = zc_c->zc_history; 438 zc->zc_history_len = zc_c->zc_history_len; 439 zc->zc_history_offset = zc_c->zc_history_offset; 440 zc->zc_obj = zc_c->zc_obj; 441 zc->zc_share = zc_c->zc_share; 442 zc->zc_jailid = zc_c->zc_jailid; 443 zc->zc_objset_stats = zc_c->zc_objset_stats; 444 zc->zc_begin_record.drr_u.drr_begin = zc_c->zc_begin_record; 445 446 /* zc->zc_inject_record */ 447 zc->zc_inject_record.zi_objset = 448 zc_c->zc_inject_record.zi_objset; 449 zc->zc_inject_record.zi_object = 450 zc_c->zc_inject_record.zi_object; 451 zc->zc_inject_record.zi_start = 452 zc_c->zc_inject_record.zi_start; 453 zc->zc_inject_record.zi_end = 454 zc_c->zc_inject_record.zi_end; 455 zc->zc_inject_record.zi_guid = 456 zc_c->zc_inject_record.zi_guid; 457 zc->zc_inject_record.zi_level = 458 zc_c->zc_inject_record.zi_level; 459 zc->zc_inject_record.zi_error = 460 zc_c->zc_inject_record.zi_error; 461 zc->zc_inject_record.zi_type = 462 zc_c->zc_inject_record.zi_type; 463 zc->zc_inject_record.zi_freq = 464 zc_c->zc_inject_record.zi_freq; 465 zc->zc_inject_record.zi_failfast = 466 zc_c->zc_inject_record.zi_failfast; 467 break; 468 } 469} 470 471void 472zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int request, 473 const int cflag) 474{ 475 zfs_cmd_v15_t *zc_c; 476 zfs_cmd_v28_t *zc28_c; 477 zfs_cmd_deadman_t *zcdm_c; 478 zfs_cmd_zcmd_t *zcmd_c; 479 zfs_cmd_edbp_t *edbp_c; 480 zfs_cmd_resume_t *resume_c; 481 zfs_cmd_inlanes_t *inlanes_c; 482 483 switch (cflag) { 484 case ZFS_CMD_COMPAT_INLANES: 485 inlanes_c = (void *)addr; 486 strlcpy(inlanes_c->zc_name, zc->zc_name, MAXPATHLEN); 487 strlcpy(inlanes_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 488 strlcpy(inlanes_c->zc_string, zc->zc_string, MAXPATHLEN); 489 490#define FIELD_COPY(field) inlanes_c->field = zc->field 491 FIELD_COPY(zc_nvlist_src); 492 FIELD_COPY(zc_nvlist_src_size); 493 FIELD_COPY(zc_nvlist_dst); 494 FIELD_COPY(zc_nvlist_dst_size); 495 FIELD_COPY(zc_nvlist_dst_filled); 496 FIELD_COPY(zc_pad2); 497 FIELD_COPY(zc_history); 498 FIELD_COPY(zc_guid); 499 FIELD_COPY(zc_nvlist_conf); 500 FIELD_COPY(zc_nvlist_conf_size); 501 FIELD_COPY(zc_cookie); 502 FIELD_COPY(zc_objset_type); 503 FIELD_COPY(zc_perm_action); 504 FIELD_COPY(zc_history_len); 505 FIELD_COPY(zc_history_offset); 506 FIELD_COPY(zc_obj); 507 FIELD_COPY(zc_iflags); 508 FIELD_COPY(zc_share); 509 FIELD_COPY(zc_jailid); 510 FIELD_COPY(zc_objset_stats); 511 FIELD_COPY(zc_begin_record); 512 FIELD_COPY(zc_inject_record); 513 FIELD_COPY(zc_defer_destroy); 514 FIELD_COPY(zc_flags); 515 FIELD_COPY(zc_action_handle); 516 FIELD_COPY(zc_cleanup_fd); 517 FIELD_COPY(zc_simple); 518 FIELD_COPY(zc_sendobj); 519 FIELD_COPY(zc_fromobj); 520 FIELD_COPY(zc_createtxg); 521 FIELD_COPY(zc_stat); 522#undef FIELD_COPY 523 break; 524 525 case ZFS_CMD_COMPAT_RESUME: 526 resume_c = (void *)addr; 527 strlcpy(resume_c->zc_name, zc->zc_name, MAXPATHLEN); 528 strlcpy(resume_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 529 strlcpy(resume_c->zc_string, zc->zc_string, MAXPATHLEN); 530 531#define FIELD_COPY(field) resume_c->field = zc->field 532 FIELD_COPY(zc_nvlist_src); 533 FIELD_COPY(zc_nvlist_src_size); 534 FIELD_COPY(zc_nvlist_dst); 535 FIELD_COPY(zc_nvlist_dst_size); 536 FIELD_COPY(zc_nvlist_dst_filled); 537 FIELD_COPY(zc_pad2); 538 FIELD_COPY(zc_history); 539 FIELD_COPY(zc_guid); 540 FIELD_COPY(zc_nvlist_conf); 541 FIELD_COPY(zc_nvlist_conf_size); 542 FIELD_COPY(zc_cookie); 543 FIELD_COPY(zc_objset_type); 544 FIELD_COPY(zc_perm_action); 545 FIELD_COPY(zc_history_len); 546 FIELD_COPY(zc_history_offset); 547 FIELD_COPY(zc_obj); 548 FIELD_COPY(zc_iflags); 549 FIELD_COPY(zc_share); 550 FIELD_COPY(zc_jailid); 551 FIELD_COPY(zc_objset_stats); 552 FIELD_COPY(zc_begin_record); 553 FIELD_COPY(zc_inject_record.zi_objset); 554 FIELD_COPY(zc_inject_record.zi_object); 555 FIELD_COPY(zc_inject_record.zi_start); 556 FIELD_COPY(zc_inject_record.zi_end); 557 FIELD_COPY(zc_inject_record.zi_guid); 558 FIELD_COPY(zc_inject_record.zi_level); 559 FIELD_COPY(zc_inject_record.zi_error); 560 FIELD_COPY(zc_inject_record.zi_type); 561 FIELD_COPY(zc_inject_record.zi_freq); 562 FIELD_COPY(zc_inject_record.zi_failfast); 563 strlcpy(resume_c->zc_inject_record.zi_func, 564 zc->zc_inject_record.zi_func, MAXNAMELEN); 565 FIELD_COPY(zc_inject_record.zi_iotype); 566 FIELD_COPY(zc_inject_record.zi_duration); 567 FIELD_COPY(zc_inject_record.zi_timer); 568 FIELD_COPY(zc_inject_record.zi_cmd); 569 FIELD_COPY(zc_inject_record.zi_pad); 570 FIELD_COPY(zc_defer_destroy); 571 FIELD_COPY(zc_flags); 572 FIELD_COPY(zc_action_handle); 573 FIELD_COPY(zc_cleanup_fd); 574 FIELD_COPY(zc_simple); 575 FIELD_COPY(zc_sendobj); 576 FIELD_COPY(zc_fromobj); 577 FIELD_COPY(zc_createtxg); 578 FIELD_COPY(zc_stat); 579#undef FIELD_COPY 580 break; 581 582 case ZFS_CMD_COMPAT_EDBP: 583 edbp_c = (void *)addr; 584 strlcpy(edbp_c->zc_name, zc->zc_name, MAXPATHLEN); 585 strlcpy(edbp_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 586 strlcpy(edbp_c->zc_string, zc->zc_string, MAXPATHLEN); 587 588#define FIELD_COPY(field) edbp_c->field = zc->field 589 FIELD_COPY(zc_nvlist_src); 590 FIELD_COPY(zc_nvlist_src_size); 591 FIELD_COPY(zc_nvlist_dst); 592 FIELD_COPY(zc_nvlist_dst_size); 593 FIELD_COPY(zc_nvlist_dst_filled); 594 FIELD_COPY(zc_pad2); 595 FIELD_COPY(zc_history); 596 FIELD_COPY(zc_guid); 597 FIELD_COPY(zc_nvlist_conf); 598 FIELD_COPY(zc_nvlist_conf_size); 599 FIELD_COPY(zc_cookie); 600 FIELD_COPY(zc_objset_type); 601 FIELD_COPY(zc_perm_action); 602 FIELD_COPY(zc_history_len); 603 FIELD_COPY(zc_history_offset); 604 FIELD_COPY(zc_obj); 605 FIELD_COPY(zc_iflags); 606 FIELD_COPY(zc_share); 607 FIELD_COPY(zc_jailid); 608 FIELD_COPY(zc_objset_stats); 609 edbp_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 610 FIELD_COPY(zc_inject_record.zi_objset); 611 FIELD_COPY(zc_inject_record.zi_object); 612 FIELD_COPY(zc_inject_record.zi_start); 613 FIELD_COPY(zc_inject_record.zi_end); 614 FIELD_COPY(zc_inject_record.zi_guid); 615 FIELD_COPY(zc_inject_record.zi_level); 616 FIELD_COPY(zc_inject_record.zi_error); 617 FIELD_COPY(zc_inject_record.zi_type); 618 FIELD_COPY(zc_inject_record.zi_freq); 619 FIELD_COPY(zc_inject_record.zi_failfast); 620 strlcpy(resume_c->zc_inject_record.zi_func, 621 zc->zc_inject_record.zi_func, MAXNAMELEN); 622 FIELD_COPY(zc_inject_record.zi_iotype); 623 FIELD_COPY(zc_inject_record.zi_duration); 624 FIELD_COPY(zc_inject_record.zi_timer); 625 FIELD_COPY(zc_inject_record.zi_cmd); 626 FIELD_COPY(zc_inject_record.zi_pad); 627 FIELD_COPY(zc_defer_destroy); 628 FIELD_COPY(zc_flags); 629 FIELD_COPY(zc_action_handle); 630 FIELD_COPY(zc_cleanup_fd); 631 FIELD_COPY(zc_simple); 632 FIELD_COPY(zc_sendobj); 633 FIELD_COPY(zc_fromobj); 634 FIELD_COPY(zc_createtxg); 635 FIELD_COPY(zc_stat); 636#undef FIELD_COPY 637 break; 638 639 case ZFS_CMD_COMPAT_ZCMD: 640 zcmd_c = (void *)addr; 641 /* zc */ 642 strlcpy(zcmd_c->zc_name, zc->zc_name, MAXPATHLEN); 643 strlcpy(zcmd_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 644 strlcpy(zcmd_c->zc_string, zc->zc_string, MAXPATHLEN); 645 646#define FIELD_COPY(field) zcmd_c->field = zc->field 647 FIELD_COPY(zc_nvlist_src); 648 FIELD_COPY(zc_nvlist_src_size); 649 FIELD_COPY(zc_nvlist_dst); 650 FIELD_COPY(zc_nvlist_dst_size); 651 FIELD_COPY(zc_nvlist_dst_filled); 652 FIELD_COPY(zc_pad2); 653 FIELD_COPY(zc_history); 654 FIELD_COPY(zc_guid); 655 FIELD_COPY(zc_nvlist_conf); 656 FIELD_COPY(zc_nvlist_conf_size); 657 FIELD_COPY(zc_cookie); 658 FIELD_COPY(zc_objset_type); 659 FIELD_COPY(zc_perm_action); 660 FIELD_COPY(zc_history_len); 661 FIELD_COPY(zc_history_offset); 662 FIELD_COPY(zc_obj); 663 FIELD_COPY(zc_iflags); 664 FIELD_COPY(zc_share); 665 FIELD_COPY(zc_jailid); 666 FIELD_COPY(zc_objset_stats); 667 zcmd_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 668 FIELD_COPY(zc_inject_record.zi_objset); 669 FIELD_COPY(zc_inject_record.zi_object); 670 FIELD_COPY(zc_inject_record.zi_start); 671 FIELD_COPY(zc_inject_record.zi_end); 672 FIELD_COPY(zc_inject_record.zi_guid); 673 FIELD_COPY(zc_inject_record.zi_level); 674 FIELD_COPY(zc_inject_record.zi_error); 675 FIELD_COPY(zc_inject_record.zi_type); 676 FIELD_COPY(zc_inject_record.zi_freq); 677 FIELD_COPY(zc_inject_record.zi_failfast); 678 strlcpy(resume_c->zc_inject_record.zi_func, 679 zc->zc_inject_record.zi_func, MAXNAMELEN); 680 FIELD_COPY(zc_inject_record.zi_iotype); 681 FIELD_COPY(zc_inject_record.zi_duration); 682 FIELD_COPY(zc_inject_record.zi_timer); 683 FIELD_COPY(zc_inject_record.zi_cmd); 684 FIELD_COPY(zc_inject_record.zi_pad); 685 686 /* boolean_t -> uint32_t */ 687 zcmd_c->zc_defer_destroy = (uint32_t)(zc->zc_defer_destroy); 688 zcmd_c->zc_temphold = 0; 689 690 FIELD_COPY(zc_action_handle); 691 FIELD_COPY(zc_cleanup_fd); 692 FIELD_COPY(zc_simple); 693 FIELD_COPY(zc_sendobj); 694 FIELD_COPY(zc_fromobj); 695 FIELD_COPY(zc_createtxg); 696 FIELD_COPY(zc_stat); 697#undef FIELD_COPY 698 699 break; 700 701 case ZFS_CMD_COMPAT_DEADMAN: 702 zcdm_c = (void *)addr; 703 704 strlcpy(zcdm_c->zc_name, zc->zc_name, MAXPATHLEN); 705 strlcpy(zcdm_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 706 strlcpy(zcdm_c->zc_string, zc->zc_string, MAXPATHLEN); 707 708#define FIELD_COPY(field) zcdm_c->field = zc->field 709 zcdm_c->zc_guid = zc->zc_guid; 710 zcdm_c->zc_nvlist_conf = zc->zc_nvlist_conf; 711 zcdm_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size; 712 zcdm_c->zc_nvlist_src = zc->zc_nvlist_src; 713 zcdm_c->zc_nvlist_src_size = zc->zc_nvlist_src_size; 714 zcdm_c->zc_nvlist_dst = zc->zc_nvlist_dst; 715 zcdm_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size; 716 zcdm_c->zc_cookie = zc->zc_cookie; 717 zcdm_c->zc_objset_type = zc->zc_objset_type; 718 zcdm_c->zc_perm_action = zc->zc_perm_action; 719 zcdm_c->zc_history = zc->zc_history; 720 zcdm_c->zc_history_len = zc->zc_history_len; 721 zcdm_c->zc_history_offset = zc->zc_history_offset; 722 zcdm_c->zc_obj = zc->zc_obj; 723 zcdm_c->zc_iflags = zc->zc_iflags; 724 zcdm_c->zc_share = zc->zc_share; 725 zcdm_c->zc_jailid = zc->zc_jailid; 726 zcdm_c->zc_objset_stats = zc->zc_objset_stats; 727 zcdm_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 728 zcdm_c->zc_defer_destroy = zc->zc_defer_destroy; 729 zcdm_c->zc_temphold = 0; 730 zcdm_c->zc_action_handle = zc->zc_action_handle; 731 zcdm_c->zc_cleanup_fd = zc->zc_cleanup_fd; 732 zcdm_c->zc_simple = zc->zc_simple; 733 zcdm_c->zc_sendobj = zc->zc_sendobj; 734 zcdm_c->zc_fromobj = zc->zc_fromobj; 735 zcdm_c->zc_createtxg = zc->zc_createtxg; 736 zcdm_c->zc_stat = zc->zc_stat; 737 FIELD_COPY(zc_inject_record.zi_objset); 738 FIELD_COPY(zc_inject_record.zi_object); 739 FIELD_COPY(zc_inject_record.zi_start); 740 FIELD_COPY(zc_inject_record.zi_end); 741 FIELD_COPY(zc_inject_record.zi_guid); 742 FIELD_COPY(zc_inject_record.zi_level); 743 FIELD_COPY(zc_inject_record.zi_error); 744 FIELD_COPY(zc_inject_record.zi_type); 745 FIELD_COPY(zc_inject_record.zi_freq); 746 FIELD_COPY(zc_inject_record.zi_failfast); 747 strlcpy(resume_c->zc_inject_record.zi_func, 748 zc->zc_inject_record.zi_func, MAXNAMELEN); 749 FIELD_COPY(zc_inject_record.zi_iotype); 750 FIELD_COPY(zc_inject_record.zi_duration); 751 FIELD_COPY(zc_inject_record.zi_timer); 752 FIELD_COPY(zc_inject_record.zi_cmd); 753 FIELD_COPY(zc_inject_record.zi_pad); 754#undef FIELD_COPY 755#ifndef _KERNEL 756 if (request == ZFS_IOC_RECV) 757 strlcpy(zcdm_c->zc_top_ds, 758 zc->zc_value + strlen(zc->zc_value) + 1, 759 (MAXPATHLEN * 2) - strlen(zc->zc_value) - 1); 760#endif 761 break; 762 763 case ZFS_CMD_COMPAT_V28: 764 zc28_c = (void *)addr; 765 766 strlcpy(zc28_c->zc_name, zc->zc_name, MAXPATHLEN); 767 strlcpy(zc28_c->zc_value, zc->zc_value, MAXPATHLEN * 2); 768 strlcpy(zc28_c->zc_string, zc->zc_string, MAXPATHLEN); 769 zc28_c->zc_guid = zc->zc_guid; 770 zc28_c->zc_nvlist_conf = zc->zc_nvlist_conf; 771 zc28_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size; 772 zc28_c->zc_nvlist_src = zc->zc_nvlist_src; 773 zc28_c->zc_nvlist_src_size = zc->zc_nvlist_src_size; 774 zc28_c->zc_nvlist_dst = zc->zc_nvlist_dst; 775 zc28_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size; 776 zc28_c->zc_cookie = zc->zc_cookie; 777 zc28_c->zc_objset_type = zc->zc_objset_type; 778 zc28_c->zc_perm_action = zc->zc_perm_action; 779 zc28_c->zc_history = zc->zc_history; 780 zc28_c->zc_history_len = zc->zc_history_len; 781 zc28_c->zc_history_offset = zc->zc_history_offset; 782 zc28_c->zc_obj = zc->zc_obj; 783 zc28_c->zc_iflags = zc->zc_iflags; 784 zc28_c->zc_share = zc->zc_share; 785 zc28_c->zc_jailid = zc->zc_jailid; 786 zc28_c->zc_objset_stats = zc->zc_objset_stats; 787 zc28_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 788 zc28_c->zc_defer_destroy = zc->zc_defer_destroy; 789 zc28_c->zc_temphold = 0; 790 zc28_c->zc_action_handle = zc->zc_action_handle; 791 zc28_c->zc_cleanup_fd = zc->zc_cleanup_fd; 792 zc28_c->zc_simple = zc->zc_simple; 793 zc28_c->zc_sendobj = zc->zc_sendobj; 794 zc28_c->zc_fromobj = zc->zc_fromobj; 795 zc28_c->zc_createtxg = zc->zc_createtxg; 796 zc28_c->zc_stat = zc->zc_stat; 797#ifndef _KERNEL 798 if (request == ZFS_IOC_RECV) 799 strlcpy(zc28_c->zc_top_ds, 800 zc->zc_value + strlen(zc->zc_value) + 1, 801 MAXPATHLEN * 2 - strlen(zc->zc_value) - 1); 802#endif 803 /* zc_inject_record */ 804 zc28_c->zc_inject_record.zi_objset = 805 zc->zc_inject_record.zi_objset; 806 zc28_c->zc_inject_record.zi_object = 807 zc->zc_inject_record.zi_object; 808 zc28_c->zc_inject_record.zi_start = 809 zc->zc_inject_record.zi_start; 810 zc28_c->zc_inject_record.zi_end = 811 zc->zc_inject_record.zi_end; 812 zc28_c->zc_inject_record.zi_guid = 813 zc->zc_inject_record.zi_guid; 814 zc28_c->zc_inject_record.zi_level = 815 zc->zc_inject_record.zi_level; 816 zc28_c->zc_inject_record.zi_error = 817 zc->zc_inject_record.zi_error; 818 zc28_c->zc_inject_record.zi_type = 819 zc->zc_inject_record.zi_type; 820 zc28_c->zc_inject_record.zi_freq = 821 zc->zc_inject_record.zi_freq; 822 zc28_c->zc_inject_record.zi_failfast = 823 zc->zc_inject_record.zi_failfast; 824 strlcpy(zc28_c->zc_inject_record.zi_func, 825 zc->zc_inject_record.zi_func, MAXNAMELEN); 826 zc28_c->zc_inject_record.zi_iotype = 827 zc->zc_inject_record.zi_iotype; 828 zc28_c->zc_inject_record.zi_duration = 829 zc->zc_inject_record.zi_duration; 830 zc28_c->zc_inject_record.zi_timer = 831 zc->zc_inject_record.zi_timer; 832 break; 833 834 case ZFS_CMD_COMPAT_V15: 835 zc_c = (void *)addr; 836 837 /* zc */ 838 strlcpy(zc_c->zc_name, zc->zc_name, MAXPATHLEN); 839 strlcpy(zc_c->zc_value, zc->zc_value, MAXPATHLEN); 840 strlcpy(zc_c->zc_string, zc->zc_string, MAXPATHLEN); 841 zc_c->zc_guid = zc->zc_guid; 842 zc_c->zc_nvlist_conf = zc->zc_nvlist_conf; 843 zc_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size; 844 zc_c->zc_nvlist_src = zc->zc_nvlist_src; 845 zc_c->zc_nvlist_src_size = zc->zc_nvlist_src_size; 846 zc_c->zc_nvlist_dst = zc->zc_nvlist_dst; 847 zc_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size; 848 zc_c->zc_cookie = zc->zc_cookie; 849 zc_c->zc_objset_type = zc->zc_objset_type; 850 zc_c->zc_perm_action = zc->zc_perm_action; 851 zc_c->zc_history = zc->zc_history; 852 zc_c->zc_history_len = zc->zc_history_len; 853 zc_c->zc_history_offset = zc->zc_history_offset; 854 zc_c->zc_obj = zc->zc_obj; 855 zc_c->zc_share = zc->zc_share; 856 zc_c->zc_jailid = zc->zc_jailid; 857 zc_c->zc_objset_stats = zc->zc_objset_stats; 858 zc_c->zc_begin_record = zc->zc_begin_record.drr_u.drr_begin; 859 860 /* zc_inject_record */ 861 zc_c->zc_inject_record.zi_objset = 862 zc->zc_inject_record.zi_objset; 863 zc_c->zc_inject_record.zi_object = 864 zc->zc_inject_record.zi_object; 865 zc_c->zc_inject_record.zi_start = 866 zc->zc_inject_record.zi_start; 867 zc_c->zc_inject_record.zi_end = 868 zc->zc_inject_record.zi_end; 869 zc_c->zc_inject_record.zi_guid = 870 zc->zc_inject_record.zi_guid; 871 zc_c->zc_inject_record.zi_level = 872 zc->zc_inject_record.zi_level; 873 zc_c->zc_inject_record.zi_error = 874 zc->zc_inject_record.zi_error; 875 zc_c->zc_inject_record.zi_type = 876 zc->zc_inject_record.zi_type; 877 zc_c->zc_inject_record.zi_freq = 878 zc->zc_inject_record.zi_freq; 879 zc_c->zc_inject_record.zi_failfast = 880 zc->zc_inject_record.zi_failfast; 881 882 break; 883 } 884} 885 886static int 887zfs_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 924static int 925zfs_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 952static void 953zfs_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 993static int 994zfs_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 1021static int 1022zfs_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 1061int 1062zcmd_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 */ 1150int 1151zfs_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 1171void 1172zfs_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 1188nvlist_t * 1189zfs_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 } 1340out: 1341 return (innvl); 1342} 1343 1344nvlist_t * 1345zfs_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