From 23c871671c7bc2c79ad6ec1804715f405058cdb6 Mon Sep 17 00:00:00 2001 From: Matthew Macy Date: Wed, 15 Jul 2020 21:32:50 -0700 Subject: [PATCH] FreeBSD: zfs commands backward compatibility Update the zfs commands such that they're backwards compatible with the version of ZFS is the base FreeBSD. Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Signed-off-by: Matt Macy Closes #10542 --- include/os/freebsd/zfs/sys/zfs_ioctl_compat.h | 545 +----------------- lib/libzutil/Makefile.am | 6 + lib/libzutil/os/freebsd/zutil_compat.c | 66 ++- module/Makefile.bsd | 1 + module/os/freebsd/zfs/kmod_core.c | 40 +- module/os/freebsd/zfs/zfs_ioctl_compat.c | 364 ++++++++++++ 6 files changed, 451 insertions(+), 571 deletions(-) create mode 100644 module/os/freebsd/zfs/zfs_ioctl_compat.c diff --git a/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h b/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h index a8db8bee52..91bc48effe 100644 --- a/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h +++ b/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h @@ -55,8 +55,8 @@ extern "C" { #define ZFS_IOCVER_RESUME 5 #define ZFS_IOCVER_INLANES 6 #define ZFS_IOCVER_PAD 7 -#define ZFS_IOCVER_FREEBSD ZFS_IOCVER_PAD -#define ZFS_IOCVER_ZOF 15 +#define ZFS_IOCVER_LEGACY ZFS_IOCVER_PAD +#define ZFS_IOCVER_OZFS 15 /* compatibility conversion flag */ #define ZFS_CMD_COMPAT_NONE 0 @@ -68,6 +68,7 @@ extern "C" { #define ZFS_CMD_COMPAT_EDBP 6 #define ZFS_CMD_COMPAT_RESUME 7 #define ZFS_CMD_COMPAT_INLANES 8 +#define ZFS_CMD_COMPAT_LEGACY 9 #define ZFS_IOC_COMPAT_PASS 254 #define ZFS_IOC_COMPAT_FAIL 255 @@ -80,328 +81,10 @@ typedef struct zfs_iocparm { uint64_t zfs_cmd_size; } zfs_iocparm_t; -typedef struct zinject_record_v15 { - uint64_t zi_objset; - uint64_t zi_object; - uint64_t zi_start; - uint64_t zi_end; - uint64_t zi_guid; - uint32_t zi_level; - uint32_t zi_error; - uint64_t zi_type; - uint32_t zi_freq; - uint32_t zi_failfast; -} zinject_record_v15_t; -typedef struct zfs_cmd_v15 { - char zc_name[MAXPATHLEN]; - char zc_value[MAXPATHLEN]; - char zc_string[MAXNAMELEN]; - uint64_t zc_guid; - uint64_t zc_nvlist_conf; /* really (char *) */ - uint64_t zc_nvlist_conf_size; - uint64_t zc_nvlist_src; /* really (char *) */ - uint64_t zc_nvlist_src_size; - uint64_t zc_nvlist_dst; /* really (char *) */ - uint64_t zc_nvlist_dst_size; - uint64_t zc_cookie; - uint64_t zc_objset_type; - uint64_t zc_perm_action; - uint64_t zc_history; /* really (char *) */ - uint64_t zc_history_len; - uint64_t zc_history_offset; - uint64_t zc_obj; - zfs_share_t zc_share; - uint64_t zc_jailid; - dmu_objset_stats_t zc_objset_stats; - struct drr_begin zc_begin_record; - zinject_record_v15_t zc_inject_record; -} zfs_cmd_v15_t; +#define LEGACY_MAXPATHLEN 1024 +#define LEGACY_MAXNAMELEN 256 -typedef struct zinject_record_v28 { - uint64_t zi_objset; - uint64_t zi_object; - uint64_t zi_start; - uint64_t zi_end; - uint64_t zi_guid; - uint32_t zi_level; - uint32_t zi_error; - uint64_t zi_type; - uint32_t zi_freq; - uint32_t zi_failfast; - char zi_func[MAXNAMELEN]; - uint32_t zi_iotype; - int32_t zi_duration; - uint64_t zi_timer; -} zinject_record_v28_t; - -typedef struct zfs_cmd_v28 { - char zc_name[MAXPATHLEN]; - char zc_value[MAXPATHLEN * 2]; - char zc_string[MAXNAMELEN]; - char zc_top_ds[MAXPATHLEN]; - uint64_t zc_guid; - uint64_t zc_nvlist_conf; /* really (char *) */ - uint64_t zc_nvlist_conf_size; - uint64_t zc_nvlist_src; /* really (char *) */ - uint64_t zc_nvlist_src_size; - uint64_t zc_nvlist_dst; /* really (char *) */ - uint64_t zc_nvlist_dst_size; - uint64_t zc_cookie; - uint64_t zc_objset_type; - uint64_t zc_perm_action; - uint64_t zc_history; /* really (char *) */ - uint64_t zc_history_len; - uint64_t zc_history_offset; - uint64_t zc_obj; - uint64_t zc_iflags; /* internal to zfs(7fs) */ - zfs_share_t zc_share; - uint64_t zc_jailid; - dmu_objset_stats_t zc_objset_stats; - struct drr_begin zc_begin_record; - zinject_record_v28_t zc_inject_record; - boolean_t zc_defer_destroy; - boolean_t zc_temphold; - uint64_t zc_action_handle; - int zc_cleanup_fd; - uint8_t zc_simple; - uint8_t zc_pad[3]; /* alignment */ - uint64_t zc_sendobj; - uint64_t zc_fromobj; - uint64_t zc_createtxg; - zfs_stat_t zc_stat; -} zfs_cmd_v28_t; - -typedef struct zinject_record_deadman { - uint64_t zi_objset; - uint64_t zi_object; - uint64_t zi_start; - uint64_t zi_end; - uint64_t zi_guid; - uint32_t zi_level; - uint32_t zi_error; - uint64_t zi_type; - uint32_t zi_freq; - uint32_t zi_failfast; - char zi_func[MAXNAMELEN]; - uint32_t zi_iotype; - int32_t zi_duration; - uint64_t zi_timer; - uint32_t zi_cmd; - uint32_t zi_pad; -} zinject_record_deadman_t; - -typedef struct zfs_cmd_deadman { - char zc_name[MAXPATHLEN]; - char zc_value[MAXPATHLEN * 2]; - char zc_string[MAXNAMELEN]; - char zc_top_ds[MAXPATHLEN]; - uint64_t zc_guid; - uint64_t zc_nvlist_conf; /* really (char *) */ - uint64_t zc_nvlist_conf_size; - uint64_t zc_nvlist_src; /* really (char *) */ - uint64_t zc_nvlist_src_size; - uint64_t zc_nvlist_dst; /* really (char *) */ - uint64_t zc_nvlist_dst_size; - uint64_t zc_cookie; - uint64_t zc_objset_type; - uint64_t zc_perm_action; - uint64_t zc_history; /* really (char *) */ - uint64_t zc_history_len; - uint64_t zc_history_offset; - uint64_t zc_obj; - uint64_t zc_iflags; /* internal to zfs(7fs) */ - zfs_share_t zc_share; - uint64_t zc_jailid; - dmu_objset_stats_t zc_objset_stats; - struct drr_begin zc_begin_record; - /* zc_inject_record doesn't change in libzfs_core */ - zinject_record_deadman_t zc_inject_record; - boolean_t zc_defer_destroy; - boolean_t zc_temphold; - uint64_t zc_action_handle; - int zc_cleanup_fd; - uint8_t zc_simple; - uint8_t zc_pad[3]; /* alignment */ - uint64_t zc_sendobj; - uint64_t zc_fromobj; - uint64_t zc_createtxg; - zfs_stat_t zc_stat; -} zfs_cmd_deadman_t; - -typedef struct zfs_cmd_zcmd { - char zc_name[MAXPATHLEN]; /* name of pool or dataset */ - uint64_t zc_nvlist_src; /* really (char *) */ - uint64_t zc_nvlist_src_size; - uint64_t zc_nvlist_dst; /* really (char *) */ - uint64_t zc_nvlist_dst_size; - boolean_t zc_nvlist_dst_filled; /* put an nvlist in dst? */ - int zc_pad2; - - /* - * The following members are for legacy ioctls which haven't been - * converted to the new method. - */ - uint64_t zc_history; /* really (char *) */ - char zc_value[MAXPATHLEN * 2]; - char zc_string[MAXNAMELEN]; - uint64_t zc_guid; - uint64_t zc_nvlist_conf; /* really (char *) */ - uint64_t zc_nvlist_conf_size; - uint64_t zc_cookie; - uint64_t zc_objset_type; - uint64_t zc_perm_action; - uint64_t zc_history_len; - uint64_t zc_history_offset; - uint64_t zc_obj; - uint64_t zc_iflags; /* internal to zfs(7fs) */ - zfs_share_t zc_share; - uint64_t zc_jailid; - dmu_objset_stats_t zc_objset_stats; - struct drr_begin zc_begin_record; - zinject_record_deadman_t zc_inject_record; - boolean_t zc_defer_destroy; - boolean_t zc_temphold; - uint64_t zc_action_handle; - int zc_cleanup_fd; - uint8_t zc_simple; - uint8_t zc_pad[3]; /* alignment */ - uint64_t zc_sendobj; - uint64_t zc_fromobj; - uint64_t zc_createtxg; - zfs_stat_t zc_stat; -} zfs_cmd_zcmd_t; - -typedef struct zfs_cmd_edbp { - char zc_name[MAXPATHLEN]; /* name of pool or dataset */ - uint64_t zc_nvlist_src; /* really (char *) */ - uint64_t zc_nvlist_src_size; - uint64_t zc_nvlist_dst; /* really (char *) */ - uint64_t zc_nvlist_dst_size; - boolean_t zc_nvlist_dst_filled; /* put an nvlist in dst? */ - int zc_pad2; - - /* - * The following members are for legacy ioctls which haven't been - * converted to the new method. - */ - uint64_t zc_history; /* really (char *) */ - char zc_value[MAXPATHLEN * 2]; - char zc_string[MAXNAMELEN]; - uint64_t zc_guid; - uint64_t zc_nvlist_conf; /* really (char *) */ - uint64_t zc_nvlist_conf_size; - uint64_t zc_cookie; - uint64_t zc_objset_type; - uint64_t zc_perm_action; - uint64_t zc_history_len; - uint64_t zc_history_offset; - uint64_t zc_obj; - uint64_t zc_iflags; /* internal to zfs(7fs) */ - zfs_share_t zc_share; - uint64_t zc_jailid; - dmu_objset_stats_t zc_objset_stats; - struct drr_begin zc_begin_record; - zinject_record_deadman_t zc_inject_record; - uint32_t zc_defer_destroy; - uint32_t zc_flags; - uint64_t zc_action_handle; - int zc_cleanup_fd; - uint8_t zc_simple; - uint8_t zc_pad[3]; /* alignment */ - uint64_t zc_sendobj; - uint64_t zc_fromobj; - uint64_t zc_createtxg; - zfs_stat_t zc_stat; -} zfs_cmd_edbp_t; - -typedef struct zfs_cmd_resume { - char zc_name[MAXPATHLEN]; /* name of pool or dataset */ - uint64_t zc_nvlist_src; /* really (char *) */ - uint64_t zc_nvlist_src_size; - uint64_t zc_nvlist_dst; /* really (char *) */ - uint64_t zc_nvlist_dst_size; - boolean_t zc_nvlist_dst_filled; /* put an nvlist in dst? */ - int zc_pad2; - - /* - * The following members are for legacy ioctls which haven't been - * converted to the new method. - */ - uint64_t zc_history; /* really (char *) */ - char zc_value[MAXPATHLEN * 2]; - char zc_string[MAXNAMELEN]; - uint64_t zc_guid; - uint64_t zc_nvlist_conf; /* really (char *) */ - uint64_t zc_nvlist_conf_size; - uint64_t zc_cookie; - uint64_t zc_objset_type; - uint64_t zc_perm_action; - uint64_t zc_history_len; - uint64_t zc_history_offset; - uint64_t zc_obj; - uint64_t zc_iflags; /* internal to zfs(7fs) */ - zfs_share_t zc_share; - uint64_t zc_jailid; - dmu_objset_stats_t zc_objset_stats; - dmu_replay_record_t zc_begin_record; - zinject_record_deadman_t zc_inject_record; - uint32_t zc_defer_destroy; - uint32_t zc_flags; - uint64_t zc_action_handle; - int zc_cleanup_fd; - uint8_t zc_simple; - boolean_t zc_resumable; - uint64_t zc_sendobj; - uint64_t zc_fromobj; - uint64_t zc_createtxg; - zfs_stat_t zc_stat; -} zfs_cmd_resume_t; - -typedef struct zfs_cmd_inlanes { - char zc_name[MAXPATHLEN]; /* name of pool or dataset */ - uint64_t zc_nvlist_src; /* really (char *) */ - uint64_t zc_nvlist_src_size; - uint64_t zc_nvlist_dst; /* really (char *) */ - uint64_t zc_nvlist_dst_size; - boolean_t zc_nvlist_dst_filled; /* put an nvlist in dst? */ - int zc_pad2; - - /* - * The following members are for legacy ioctls which haven't been - * converted to the new method. - */ - uint64_t zc_history; /* really (char *) */ - char zc_value[MAXPATHLEN * 2]; - char zc_string[MAXNAMELEN]; - uint64_t zc_guid; - uint64_t zc_nvlist_conf; /* really (char *) */ - uint64_t zc_nvlist_conf_size; - uint64_t zc_cookie; - uint64_t zc_objset_type; - uint64_t zc_perm_action; - uint64_t zc_history_len; - uint64_t zc_history_offset; - uint64_t zc_obj; - uint64_t zc_iflags; /* internal to zfs(7fs) */ - zfs_share_t zc_share; - uint64_t zc_jailid; - dmu_objset_stats_t zc_objset_stats; - dmu_replay_record_t zc_begin_record; - zinject_record_t zc_inject_record; - uint32_t zc_defer_destroy; - uint32_t zc_flags; - uint64_t zc_action_handle; - int zc_cleanup_fd; - uint8_t zc_simple; - boolean_t zc_resumable; - uint64_t zc_sendobj; - uint64_t zc_fromobj; - uint64_t zc_createtxg; - zfs_stat_t zc_stat; -} zfs_cmd_inlanes_t; - -#ifdef _KERNEL /* * Note: this struct must have the same layout in 32-bit and 64-bit, so * that 32-bit processes (like /sbin/zfs) can pass it to the 64-bit @@ -409,7 +92,7 @@ typedef struct zfs_cmd_inlanes { * is automatically added on 64-bit (but not on 32-bit). */ typedef struct zfs_cmd_legacy { - char zc_name[MAXPATHLEN]; /* name of pool or dataset */ + char zc_name[LEGACY_MAXPATHLEN]; /* pool|dataset name */ uint64_t zc_nvlist_src; /* really (char *) */ uint64_t zc_nvlist_src_size; uint64_t zc_nvlist_dst; /* really (char *) */ @@ -422,8 +105,8 @@ typedef struct zfs_cmd_legacy { * converted to the new method. */ uint64_t zc_history; /* really (char *) */ - char zc_value[MAXPATHLEN * 2]; - char zc_string[MAXNAMELEN]; + char zc_value[LEGACY_MAXPATHLEN * 2]; + char zc_string[LEGACY_MAXNAMELEN]; uint64_t zc_guid; uint64_t zc_nvlist_conf; /* really (char *) */ uint64_t zc_nvlist_conf_size; @@ -436,10 +119,8 @@ typedef struct zfs_cmd_legacy { uint64_t zc_iflags; /* internal to zfs(7fs) */ zfs_share_t zc_share; uint64_t zc_jailid; - dmu_objset_stats_t zc_objset_stats; - uint64_t zc_freebsd_drr_pad; - struct drr_begin zc_begin_record; + dmu_replay_record_t zc_begin_record; zinject_record_t zc_inject_record; uint32_t zc_defer_destroy; uint32_t zc_flags; @@ -455,209 +136,6 @@ typedef struct zfs_cmd_legacy { zfs_stat_t zc_stat; } zfs_cmd_legacy_t; -unsigned static long zfs_ioctl_bsd12_to_zof[] = { - ZFS_IOC_POOL_CREATE, /* 0x00 */ - ZFS_IOC_POOL_DESTROY, /* 0x01 */ - ZFS_IOC_POOL_IMPORT, /* 0x02 */ - ZFS_IOC_POOL_EXPORT, /* 0x03 */ - ZFS_IOC_POOL_CONFIGS, /* 0x04 */ - ZFS_IOC_POOL_STATS, /* 0x05 */ - ZFS_IOC_POOL_TRYIMPORT, /* 0x06 */ - ZFS_IOC_POOL_SCAN, /* 0x07 */ - ZFS_IOC_POOL_FREEZE, /* 0x08 */ - ZFS_IOC_POOL_UPGRADE, /* 0x09 */ - ZFS_IOC_POOL_GET_HISTORY, /* 0x0a */ - ZFS_IOC_VDEV_ADD, /* 0x0b */ - ZFS_IOC_VDEV_REMOVE, /* 0x0c */ - ZFS_IOC_VDEV_SET_STATE, /* 0x0d */ - ZFS_IOC_VDEV_ATTACH, /* 0x0e */ - ZFS_IOC_VDEV_DETACH, /* 0x0f */ - ZFS_IOC_VDEV_SETPATH, /* 0x10 */ - ZFS_IOC_VDEV_SETFRU, /* 0x11 */ - ZFS_IOC_OBJSET_STATS, /* 0x12 */ - ZFS_IOC_OBJSET_ZPLPROPS, /* 0x13 */ - ZFS_IOC_DATASET_LIST_NEXT, /* 0x14 */ - ZFS_IOC_SNAPSHOT_LIST_NEXT, /* 0x15 */ - ZFS_IOC_SET_PROP, /* 0x16 */ - ZFS_IOC_CREATE, /* 0x17 */ - ZFS_IOC_DESTROY, /* 0x18 */ - ZFS_IOC_ROLLBACK, /* 0x19 */ - ZFS_IOC_RENAME, /* 0x1a */ - ZFS_IOC_RECV, /* 0x1b */ - ZFS_IOC_SEND, /* 0x1c */ - ZFS_IOC_INJECT_FAULT, /* 0x1d */ - ZFS_IOC_CLEAR_FAULT, /* 0x1e */ - ZFS_IOC_INJECT_LIST_NEXT, /* 0x1f */ - ZFS_IOC_ERROR_LOG, /* 0x20 */ - ZFS_IOC_CLEAR, /* 0x21 */ - ZFS_IOC_PROMOTE, /* 0x22 */ - /* start of mismatch */ - ZFS_IOC_DESTROY_SNAPS, /* 0x23:0x3b */ - ZFS_IOC_SNAPSHOT, /* 0x24:0x23 */ - ZFS_IOC_DSOBJ_TO_DSNAME, /* 0x25:0x24 */ - ZFS_IOC_OBJ_TO_PATH, /* 0x26:0x25 */ - ZFS_IOC_POOL_SET_PROPS, /* 0x27:0x26 */ - ZFS_IOC_POOL_GET_PROPS, /* 0x28:0x27 */ - ZFS_IOC_SET_FSACL, /* 0x29:0x28 */ - ZFS_IOC_GET_FSACL, /* 0x30:0x29 */ - ZFS_IOC_SHARE, /* 0x2b:0x2a */ - ZFS_IOC_INHERIT_PROP, /* 0x2c:0x2b */ - ZFS_IOC_SMB_ACL, /* 0x2d:0x2c */ - ZFS_IOC_USERSPACE_ONE, /* 0x2e:0x2d */ - ZFS_IOC_USERSPACE_MANY, /* 0x2f:0x2e */ - ZFS_IOC_USERSPACE_UPGRADE, /* 0x30:0x2f */ - ZFS_IOC_HOLD, /* 0x31:0x30 */ - ZFS_IOC_RELEASE, /* 0x32:0x31 */ - ZFS_IOC_GET_HOLDS, /* 0x33:0x32 */ - ZFS_IOC_OBJSET_RECVD_PROPS, /* 0x34:0x33 */ - ZFS_IOC_VDEV_SPLIT, /* 0x35:0x34 */ - ZFS_IOC_NEXT_OBJ, /* 0x36:0x35 */ - ZFS_IOC_DIFF, /* 0x37:0x36 */ - ZFS_IOC_TMP_SNAPSHOT, /* 0x38:0x37 */ - ZFS_IOC_OBJ_TO_STATS, /* 0x39:0x38 */ - ZFS_IOC_JAIL, /* 0x3a:0xc2 */ - ZFS_IOC_UNJAIL, /* 0x3b:0xc3 */ - ZFS_IOC_POOL_REGUID, /* 0x3c:0x3c */ - ZFS_IOC_SPACE_WRITTEN, /* 0x3d:0x39 */ - ZFS_IOC_SPACE_SNAPS, /* 0x3e:0x3a */ - ZFS_IOC_SEND_PROGRESS, /* 0x3f:0x3e */ - ZFS_IOC_POOL_REOPEN, /* 0x40:0x3d */ - ZFS_IOC_LOG_HISTORY, /* 0x41:0x3f */ - ZFS_IOC_SEND_NEW, /* 0x42:0x40 */ - ZFS_IOC_SEND_SPACE, /* 0x43:0x41 */ - ZFS_IOC_CLONE, /* 0x44:0x42 */ - ZFS_IOC_BOOKMARK, /* 0x45:0x43 */ - ZFS_IOC_GET_BOOKMARKS, /* 0x46:0x44 */ - ZFS_IOC_DESTROY_BOOKMARKS, /* 0x47:0x45 */ - ZFS_IOC_NEXTBOOT, /* 0x48:0xc1 */ - ZFS_IOC_CHANNEL_PROGRAM, /* 0x49:0x48 */ - ZFS_IOC_REMAP, /* 0x4a:0x4c */ - ZFS_IOC_POOL_CHECKPOINT, /* 0x4b:0x4d */ - ZFS_IOC_POOL_DISCARD_CHECKPOINT, /* 0x4c:0x4e */ - ZFS_IOC_POOL_INITIALIZE, /* 0x4d:0x4f */ -}; - -unsigned static long zfs_ioctl_v15_to_v28[] = { - 0, /* 0 ZFS_IOC_POOL_CREATE */ - 1, /* 1 ZFS_IOC_POOL_DESTROY */ - 2, /* 2 ZFS_IOC_POOL_IMPORT */ - 3, /* 3 ZFS_IOC_POOL_EXPORT */ - 4, /* 4 ZFS_IOC_POOL_CONFIGS */ - 5, /* 5 ZFS_IOC_POOL_STATS */ - 6, /* 6 ZFS_IOC_POOL_TRYIMPORT */ - 7, /* 7 ZFS_IOC_POOL_SCRUB */ - 8, /* 8 ZFS_IOC_POOL_FREEZE */ - 9, /* 9 ZFS_IOC_POOL_UPGRADE */ - 10, /* 10 ZFS_IOC_POOL_GET_HISTORY */ - 11, /* 11 ZFS_IOC_VDEV_ADD */ - 12, /* 12 ZFS_IOC_VDEV_REMOVE */ - 13, /* 13 ZFS_IOC_VDEV_SET_STATE */ - 14, /* 14 ZFS_IOC_VDEV_ATTACH */ - 15, /* 15 ZFS_IOC_VDEV_DETACH */ - 16, /* 16 ZFS_IOC_VDEV_SETPATH */ - 18, /* 17 ZFS_IOC_OBJSET_STATS */ - 19, /* 18 ZFS_IOC_OBJSET_ZPLPROPS */ - 20, /* 19 ZFS_IOC_DATASET_LIST_NEXT */ - 21, /* 20 ZFS_IOC_SNAPSHOT_LIST_NEXT */ - 22, /* 21 ZFS_IOC_SET_PROP */ - ZFS_IOC_COMPAT_PASS, /* 22 ZFS_IOC_CREATE_MINOR */ - ZFS_IOC_COMPAT_PASS, /* 23 ZFS_IOC_REMOVE_MINOR */ - 23, /* 24 ZFS_IOC_CREATE */ - 24, /* 25 ZFS_IOC_DESTROY */ - 25, /* 26 ZFS_IOC_ROLLBACK */ - 26, /* 27 ZFS_IOC_RENAME */ - 27, /* 28 ZFS_IOC_RECV */ - 28, /* 29 ZFS_IOC_SEND */ - 29, /* 30 ZFS_IOC_INJECT_FAULT */ - 30, /* 31 ZFS_IOC_CLEAR_FAULT */ - 31, /* 32 ZFS_IOC_INJECT_LIST_NEXT */ - 32, /* 33 ZFS_IOC_ERROR_LOG */ - 33, /* 34 ZFS_IOC_CLEAR */ - 34, /* 35 ZFS_IOC_PROMOTE */ - 35, /* 36 ZFS_IOC_DESTROY_SNAPS */ - 36, /* 37 ZFS_IOC_SNAPSHOT */ - 37, /* 38 ZFS_IOC_DSOBJ_TO_DSNAME */ - 38, /* 39 ZFS_IOC_OBJ_TO_PATH */ - 39, /* 40 ZFS_IOC_POOL_SET_PROPS */ - 40, /* 41 ZFS_IOC_POOL_GET_PROPS */ - 41, /* 42 ZFS_IOC_SET_FSACL */ - 42, /* 43 ZFS_IOC_GET_FSACL */ - ZFS_IOC_COMPAT_PASS, /* 44 ZFS_IOC_ISCSI_PERM_CHECK */ - 43, /* 45 ZFS_IOC_SHARE */ - 44, /* 46 ZFS_IOC_IHNERIT_PROP */ - 58, /* 47 ZFS_IOC_JAIL */ - 59, /* 48 ZFS_IOC_UNJAIL */ - 45, /* 49 ZFS_IOC_SMB_ACL */ - 46, /* 50 ZFS_IOC_USERSPACE_ONE */ - 47, /* 51 ZFS_IOC_USERSPACE_MANY */ - 48, /* 52 ZFS_IOC_USERSPACE_UPGRADE */ - 17, /* 53 ZFS_IOC_SETFRU */ -}; - -#else /* KERNEL */ -unsigned static long zfs_ioctl_v28_to_v15[] = { - 0, /* 0 ZFS_IOC_POOL_CREATE */ - 1, /* 1 ZFS_IOC_POOL_DESTROY */ - 2, /* 2 ZFS_IOC_POOL_IMPORT */ - 3, /* 3 ZFS_IOC_POOL_EXPORT */ - 4, /* 4 ZFS_IOC_POOL_CONFIGS */ - 5, /* 5 ZFS_IOC_POOL_STATS */ - 6, /* 6 ZFS_IOC_POOL_TRYIMPORT */ - 7, /* 7 ZFS_IOC_POOL_SCAN */ - 8, /* 8 ZFS_IOC_POOL_FREEZE */ - 9, /* 9 ZFS_IOC_POOL_UPGRADE */ - 10, /* 10 ZFS_IOC_POOL_GET_HISTORY */ - 11, /* 11 ZFS_IOC_VDEV_ADD */ - 12, /* 12 ZFS_IOC_VDEV_REMOVE */ - 13, /* 13 ZFS_IOC_VDEV_SET_STATE */ - 14, /* 14 ZFS_IOC_VDEV_ATTACH */ - 15, /* 15 ZFS_IOC_VDEV_DETACH */ - 16, /* 16 ZFS_IOC_VDEV_SETPATH */ - 53, /* 17 ZFS_IOC_VDEV_SETFRU */ - 17, /* 18 ZFS_IOC_OBJSET_STATS */ - 18, /* 19 ZFS_IOC_OBJSET_ZPLPROPS */ - 19, /* 20 ZFS_IOC_DATASET_LIST_NEXT */ - 20, /* 21 ZFS_IOC_SNAPSHOT_LIST_NEXT */ - 21, /* 22 ZFS_IOC_SET_PROP */ - 24, /* 23 ZFS_IOC_CREATE */ - 25, /* 24 ZFS_IOC_DESTROY */ - 26, /* 25 ZFS_IOC_ROLLBACK */ - 27, /* 26 ZFS_IOC_RENAME */ - 28, /* 27 ZFS_IOC_RECV */ - 29, /* 28 ZFS_IOC_SEND */ - 30, /* 39 ZFS_IOC_INJECT_FAULT */ - 31, /* 30 ZFS_IOC_CLEAR_FAULT */ - 32, /* 31 ZFS_IOC_INJECT_LIST_NEXT */ - 33, /* 32 ZFS_IOC_ERROR_LOG */ - 34, /* 33 ZFS_IOC_CLEAR */ - 35, /* 34 ZFS_IOC_PROMOTE */ - 36, /* 35 ZFS_IOC_DESTROY_SNAPS */ - 37, /* 36 ZFS_IOC_SNAPSHOT */ - 38, /* 37 ZFS_IOC_DSOBJ_TO_DSNAME */ - 39, /* 38 ZFS_IOC_OBJ_TO_PATH */ - 40, /* 39 ZFS_IOC_POOL_SET_PROPS */ - 41, /* 40 ZFS_IOC_POOL_GET_PROPS */ - 42, /* 41 ZFS_IOC_SET_FSACL */ - 43, /* 42 ZFS_IOC_GET_FSACL */ - 45, /* 43 ZFS_IOC_SHARE */ - 46, /* 44 ZFS_IOC_IHNERIT_PROP */ - 49, /* 45 ZFS_IOC_SMB_ACL */ - 50, /* 46 ZFS_IOC_USERSPACE_ONE */ - 51, /* 47 ZFS_IOC_USERSPACE_MANY */ - 52, /* 48 ZFS_IOC_USERSPACE_UPGRADE */ - ZFS_IOC_COMPAT_FAIL, /* 49 ZFS_IOC_HOLD */ - ZFS_IOC_COMPAT_FAIL, /* 50 ZFS_IOC_RELEASE */ - ZFS_IOC_COMPAT_FAIL, /* 51 ZFS_IOC_GET_HOLDS */ - ZFS_IOC_COMPAT_FAIL, /* 52 ZFS_IOC_OBJSET_RECVD_PROPS */ - ZFS_IOC_COMPAT_FAIL, /* 53 ZFS_IOC_VDEV_SPLIT */ - ZFS_IOC_COMPAT_FAIL, /* 54 ZFS_IOC_NEXT_OBJ */ - ZFS_IOC_COMPAT_FAIL, /* 55 ZFS_IOC_DIFF */ - ZFS_IOC_COMPAT_FAIL, /* 56 ZFS_IOC_TMP_SNAPSHOT */ - ZFS_IOC_COMPAT_FAIL, /* 57 ZFS_IOC_OBJ_TO_STATS */ - 47, /* 58 ZFS_IOC_JAIL */ - 48, /* 59 ZFS_IOC_UNJAIL */ -}; -#endif /* ! _KERNEL */ #ifdef _KERNEL int zfs_ioctl_compat_pre(zfs_cmd_t *, int *, const int); @@ -667,7 +145,12 @@ nvlist_t *zfs_ioctl_compat_innvl(zfs_cmd_t *, nvlist_t *, const int, nvlist_t *zfs_ioctl_compat_outnvl(zfs_cmd_t *, nvlist_t *, const int, const int); #endif /* _KERNEL */ +int zfs_ioctl_legacy_to_ozfs(int request); +int zfs_ioctl_ozfs_to_legacy(int request); +void zfs_cmd_legacy_to_ozfs(zfs_cmd_legacy_t *src, zfs_cmd_t *dst); void zfs_cmd_compat_get(zfs_cmd_t *, caddr_t, const int); +void zfs_cmd_ozfs_to_legacy(zfs_cmd_t *src, zfs_cmd_legacy_t *dst); + void zfs_cmd_compat_put(zfs_cmd_t *, caddr_t, const int, const int); #ifdef __cplusplus diff --git a/lib/libzutil/Makefile.am b/lib/libzutil/Makefile.am index bbd69b780f..cd03ba19d5 100644 --- a/lib/libzutil/Makefile.am +++ b/lib/libzutil/Makefile.am @@ -23,10 +23,16 @@ USER_C += \ endif if BUILD_FREEBSD +DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/freebsd/zfs + USER_C += \ os/freebsd/zutil_device_path_os.c \ os/freebsd/zutil_import_os.c \ os/freebsd/zutil_compat.c + +VPATH += $(top_srcdir)/module/os/freebsd/zfs + +nodist_libzutil_la_SOURCES = zfs_ioctl_compat.c endif libzutil_la_SOURCES = $(USER_C) diff --git a/lib/libzutil/os/freebsd/zutil_compat.c b/lib/libzutil/os/freebsd/zutil_compat.c index 5b0fe85485..3e70fef1ec 100644 --- a/lib/libzutil/os/freebsd/zutil_compat.c +++ b/lib/libzutil/os/freebsd/zutil_compat.c @@ -20,15 +20,35 @@ */ #include #include +#include #include #include #include +#include + +int zfs_ioctl_version = ZFS_IOCVER_UNDEF; + +/* + * Get zfs_ioctl_version + */ +static int +get_zfs_ioctl_version(void) +{ + size_t ver_size; + int ver = ZFS_IOCVER_NONE; + + ver_size = sizeof (ver); + sysctlbyname("vfs.zfs.version.ioctl", &ver, &ver_size, NULL, 0); + + return (ver); +} + static int zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag) { - int ret; - void *zc_c; + int newrequest, ret; + void *zc_c = NULL; unsigned long ncmd; zfs_iocparm_t zp; @@ -37,17 +57,32 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag) ncmd = _IOWR('Z', request, zfs_iocparm_t); zp.zfs_cmd = (uint64_t)zc; zp.zfs_cmd_size = sizeof (zfs_cmd_t); - zp.zfs_ioctl_version = ZFS_IOCVER_ZOF; - return (ioctl(fd, ncmd, &zp)); + zp.zfs_ioctl_version = ZFS_IOCVER_OZFS; + break; + case ZFS_CMD_COMPAT_LEGACY: + newrequest = zfs_ioctl_ozfs_to_legacy(request); + ncmd = _IOWR('Z', newrequest, zfs_iocparm_t); + zc_c = malloc(sizeof (zfs_cmd_legacy_t)); + zfs_cmd_ozfs_to_legacy(zc, zc_c); + zp.zfs_cmd = (uint64_t)zc_c; + zp.zfs_cmd_size = sizeof (zfs_cmd_legacy_t); + zp.zfs_ioctl_version = ZFS_IOCVER_LEGACY; + break; default: abort(); return (EINVAL); } - ret = ioctl(fd, ncmd, zc_c); - zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag); - free(zc_c); - + ret = ioctl(fd, ncmd, &zp); + if (ret) { + if (zc_c) + free(zc_c); + return (ret); + } + if (zc_c) { + zfs_cmd_legacy_to_ozfs(zc_c, zc); + free(zc_c); + } return (ret); } @@ -62,6 +97,21 @@ zfs_ioctl_fd(int fd, unsigned long request, zfs_cmd_t *zc) size_t oldsize; int ret, cflag = ZFS_CMD_COMPAT_NONE; + if (zfs_ioctl_version == ZFS_IOCVER_UNDEF) + zfs_ioctl_version = get_zfs_ioctl_version(); + + switch (zfs_ioctl_version) { + case ZFS_IOCVER_LEGACY: + cflag = ZFS_CMD_COMPAT_LEGACY; + break; + case ZFS_IOCVER_OZFS: + cflag = ZFS_CMD_COMPAT_NONE; + break; + default: + errx(1, "unrecognized zfs ioctl version %d", + zfs_ioctl_version); + } + oldsize = zc->zc_nvlist_dst_size; ret = zcmd_ioctl_compat(fd, request, zc, cflag); diff --git a/module/Makefile.bsd b/module/Makefile.bsd index 1ac9d00e7b..6fd00f4746 100644 --- a/module/Makefile.bsd +++ b/module/Makefile.bsd @@ -141,6 +141,7 @@ SRCS+= abd_os.c \ zfs_acl.c \ zfs_ctldir.c \ zfs_dir.c \ + zfs_ioctl_compat.c \ zfs_ioctl_os.c \ zfs_log.c \ zfs_replay.c \ diff --git a/module/os/freebsd/zfs/kmod_core.c b/module/os/freebsd/zfs/kmod_core.c index 4a4f55ea6d..e6eceacb22 100644 --- a/module/os/freebsd/zfs/kmod_core.c +++ b/module/os/freebsd/zfs/kmod_core.c @@ -99,7 +99,7 @@ SYSCTL_DECL(_vfs_zfs); SYSCTL_DECL(_vfs_zfs_vdev); -static int zfs_version_ioctl = ZFS_IOCVER_ZOF; +static int zfs_version_ioctl = ZFS_IOCVER_OZFS; SYSCTL_DECL(_vfs_zfs_version); SYSCTL_INT(_vfs_zfs_version, OID_AUTO, ioctl, CTLFLAG_RD, &zfs_version_ioctl, 0, "ZFS_IOCTL_VERSION"); @@ -121,37 +121,13 @@ extern zfsdev_state_t *zfsdev_state_list; #define ZFS_MIN_KSTACK_PAGES 4 -static void -zfs_cmd_bsd12_to_zof(zfs_cmd_legacy_t *src, zfs_cmd_t *dst) -{ - memcpy(dst, src, offsetof(zfs_cmd_t, zc_objset_stats)); - *&dst->zc_objset_stats = *&src->zc_objset_stats; - memcpy(&dst->zc_begin_record, &src->zc_begin_record, - offsetof(zfs_cmd_t, zc_sendobj) - - offsetof(zfs_cmd_t, zc_begin_record)); - memcpy(&dst->zc_sendobj, &src->zc_sendobj, - sizeof (zfs_cmd_t) - 8 - offsetof(zfs_cmd_t, zc_sendobj)); - dst->zc_zoneid = src->zc_jailid; -} - -static void -zfs_cmd_zof_to_bsd12(zfs_cmd_t *src, zfs_cmd_legacy_t *dst) -{ - memcpy(dst, src, offsetof(zfs_cmd_t, zc_objset_stats)); - *&dst->zc_objset_stats = *&src->zc_objset_stats; - memcpy(&dst->zc_begin_record, &src->zc_begin_record, - offsetof(zfs_cmd_t, zc_sendobj) - - offsetof(zfs_cmd_t, zc_begin_record)); - memcpy(&dst->zc_sendobj, &src->zc_sendobj, - sizeof (zfs_cmd_t) - 8 - offsetof(zfs_cmd_t, zc_sendobj)); - dst->zc_jailid = src->zc_zoneid; -} static int zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag, struct thread *td) { - uint_t len, vecnum; + uint_t len; + int vecnum; zfs_iocparm_t *zp; zfs_cmd_t *zc; zfs_cmd_legacy_t *zcl; @@ -175,25 +151,25 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag, /* * Remap ioctl code for legacy user binaries */ - if (zp->zfs_ioctl_version == ZFS_IOCVER_FREEBSD) { - if (vecnum >= sizeof (zfs_ioctl_bsd12_to_zof)/sizeof (long)) { + if (zp->zfs_ioctl_version == ZFS_IOCVER_LEGACY) { + vecnum = zfs_ioctl_legacy_to_ozfs(vecnum); + if (vecnum < 0) { kmem_free(zc, sizeof (zfs_cmd_t)); return (ENOTSUP); } zcl = kmem_zalloc(sizeof (zfs_cmd_legacy_t), KM_SLEEP); - vecnum = zfs_ioctl_bsd12_to_zof[vecnum]; if (copyin(uaddr, zcl, sizeof (zfs_cmd_legacy_t))) { error = SET_ERROR(EFAULT); goto out; } - zfs_cmd_bsd12_to_zof(zcl, zc); + zfs_cmd_legacy_to_ozfs(zcl, zc); } else if (copyin(uaddr, zc, sizeof (zfs_cmd_t))) { error = SET_ERROR(EFAULT); goto out; } error = zfsdev_ioctl_common(vecnum, zc, 0); if (zcl) { - zfs_cmd_zof_to_bsd12(zc, zcl); + zfs_cmd_ozfs_to_legacy(zc, zcl); rc = copyout(zcl, uaddr, sizeof (*zcl)); } else { rc = copyout(zc, uaddr, sizeof (*zc)); diff --git a/module/os/freebsd/zfs/zfs_ioctl_compat.c b/module/os/freebsd/zfs/zfs_ioctl_compat.c new file mode 100644 index 0000000000..18ab587563 --- /dev/null +++ b/module/os/freebsd/zfs/zfs_ioctl_compat.c @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2020 iXsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum zfs_ioc_legacy { + ZFS_IOC_LEGACY_NONE = -1, + ZFS_IOC_LEGACY_FIRST = 0, + ZFS_LEGACY_IOC = ZFS_IOC_LEGACY_FIRST, + ZFS_IOC_LEGACY_POOL_CREATE = ZFS_IOC_LEGACY_FIRST, + ZFS_IOC_LEGACY_POOL_DESTROY, + ZFS_IOC_LEGACY_POOL_IMPORT, + ZFS_IOC_LEGACY_POOL_EXPORT, + ZFS_IOC_LEGACY_POOL_CONFIGS, + ZFS_IOC_LEGACY_POOL_STATS, + ZFS_IOC_LEGACY_POOL_TRYIMPORT, + ZFS_IOC_LEGACY_POOL_SCAN, + ZFS_IOC_LEGACY_POOL_FREEZE, + ZFS_IOC_LEGACY_POOL_UPGRADE, + ZFS_IOC_LEGACY_POOL_GET_HISTORY, + ZFS_IOC_LEGACY_VDEV_ADD, + ZFS_IOC_LEGACY_VDEV_REMOVE, + ZFS_IOC_LEGACY_VDEV_SET_STATE, + ZFS_IOC_LEGACY_VDEV_ATTACH, + ZFS_IOC_LEGACY_VDEV_DETACH, + ZFS_IOC_LEGACY_VDEV_SETPATH, + ZFS_IOC_LEGACY_VDEV_SETFRU, + ZFS_IOC_LEGACY_OBJSET_STATS, + ZFS_IOC_LEGACY_OBJSET_ZPLPROPS, + ZFS_IOC_LEGACY_DATASET_LIST_NEXT, + ZFS_IOC_LEGACY_SNAPSHOT_LIST_NEXT, + ZFS_IOC_LEGACY_SET_PROP, + ZFS_IOC_LEGACY_CREATE, + ZFS_IOC_LEGACY_DESTROY, + ZFS_IOC_LEGACY_ROLLBACK, + ZFS_IOC_LEGACY_RENAME, + ZFS_IOC_LEGACY_RECV, + ZFS_IOC_LEGACY_SEND, + ZFS_IOC_LEGACY_INJECT_FAULT, + ZFS_IOC_LEGACY_CLEAR_FAULT, + ZFS_IOC_LEGACY_INJECT_LIST_NEXT, + ZFS_IOC_LEGACY_ERROR_LOG, + ZFS_IOC_LEGACY_CLEAR, + ZFS_IOC_LEGACY_PROMOTE, + ZFS_IOC_LEGACY_DESTROY_SNAPS, + ZFS_IOC_LEGACY_SNAPSHOT, + ZFS_IOC_LEGACY_DSOBJ_TO_DSNAME, + ZFS_IOC_LEGACY_OBJ_TO_PATH, + ZFS_IOC_LEGACY_POOL_SET_PROPS, + ZFS_IOC_LEGACY_POOL_GET_PROPS, + ZFS_IOC_LEGACY_SET_FSACL, + ZFS_IOC_LEGACY_GET_FSACL, + ZFS_IOC_LEGACY_SHARE, + ZFS_IOC_LEGACY_INHERIT_PROP, + ZFS_IOC_LEGACY_SMB_ACL, + ZFS_IOC_LEGACY_USERSPACE_ONE, + ZFS_IOC_LEGACY_USERSPACE_MANY, + ZFS_IOC_LEGACY_USERSPACE_UPGRADE, + ZFS_IOC_LEGACY_HOLD, + ZFS_IOC_LEGACY_RELEASE, + ZFS_IOC_LEGACY_GET_HOLDS, + ZFS_IOC_LEGACY_OBJSET_RECVD_PROPS, + ZFS_IOC_LEGACY_VDEV_SPLIT, + ZFS_IOC_LEGACY_NEXT_OBJ, + ZFS_IOC_LEGACY_DIFF, + ZFS_IOC_LEGACY_TMP_SNAPSHOT, + ZFS_IOC_LEGACY_OBJ_TO_STATS, + ZFS_IOC_LEGACY_JAIL, + ZFS_IOC_LEGACY_UNJAIL, + ZFS_IOC_LEGACY_POOL_REGUID, + ZFS_IOC_LEGACY_SPACE_WRITTEN, + ZFS_IOC_LEGACY_SPACE_SNAPS, + ZFS_IOC_LEGACY_SEND_PROGRESS, + ZFS_IOC_LEGACY_POOL_REOPEN, + ZFS_IOC_LEGACY_LOG_HISTORY, + ZFS_IOC_LEGACY_SEND_NEW, + ZFS_IOC_LEGACY_SEND_SPACE, + ZFS_IOC_LEGACY_CLONE, + ZFS_IOC_LEGACY_BOOKMARK, + ZFS_IOC_LEGACY_GET_BOOKMARKS, + ZFS_IOC_LEGACY_DESTROY_BOOKMARKS, + ZFS_IOC_LEGACY_NEXTBOOT, + ZFS_IOC_LEGACY_CHANNEL_PROGRAM, + ZFS_IOC_LEGACY_REMAP, + ZFS_IOC_LEGACY_POOL_CHECKPOINT, + ZFS_IOC_LEGACY_POOL_DISCARD_CHECKPOINT, + ZFS_IOC_LEGACY_POOL_INITIALIZE, + ZFS_IOC_LEGACY_POOL_SYNC, + ZFS_IOC_LEGACY_LAST +}; + +unsigned static long zfs_ioctl_legacy_to_ozfs_[] = { + ZFS_IOC_POOL_CREATE, /* 0x00 */ + ZFS_IOC_POOL_DESTROY, /* 0x01 */ + ZFS_IOC_POOL_IMPORT, /* 0x02 */ + ZFS_IOC_POOL_EXPORT, /* 0x03 */ + ZFS_IOC_POOL_CONFIGS, /* 0x04 */ + ZFS_IOC_POOL_STATS, /* 0x05 */ + ZFS_IOC_POOL_TRYIMPORT, /* 0x06 */ + ZFS_IOC_POOL_SCAN, /* 0x07 */ + ZFS_IOC_POOL_FREEZE, /* 0x08 */ + ZFS_IOC_POOL_UPGRADE, /* 0x09 */ + ZFS_IOC_POOL_GET_HISTORY, /* 0x0a */ + ZFS_IOC_VDEV_ADD, /* 0x0b */ + ZFS_IOC_VDEV_REMOVE, /* 0x0c */ + ZFS_IOC_VDEV_SET_STATE, /* 0x0d */ + ZFS_IOC_VDEV_ATTACH, /* 0x0e */ + ZFS_IOC_VDEV_DETACH, /* 0x0f */ + ZFS_IOC_VDEV_SETPATH, /* 0x10 */ + ZFS_IOC_VDEV_SETFRU, /* 0x11 */ + ZFS_IOC_OBJSET_STATS, /* 0x12 */ + ZFS_IOC_OBJSET_ZPLPROPS, /* 0x13 */ + ZFS_IOC_DATASET_LIST_NEXT, /* 0x14 */ + ZFS_IOC_SNAPSHOT_LIST_NEXT, /* 0x15 */ + ZFS_IOC_SET_PROP, /* 0x16 */ + ZFS_IOC_CREATE, /* 0x17 */ + ZFS_IOC_DESTROY, /* 0x18 */ + ZFS_IOC_ROLLBACK, /* 0x19 */ + ZFS_IOC_RENAME, /* 0x1a */ + ZFS_IOC_RECV, /* 0x1b */ + ZFS_IOC_SEND, /* 0x1c */ + ZFS_IOC_INJECT_FAULT, /* 0x1d */ + ZFS_IOC_CLEAR_FAULT, /* 0x1e */ + ZFS_IOC_INJECT_LIST_NEXT, /* 0x1f */ + ZFS_IOC_ERROR_LOG, /* 0x20 */ + ZFS_IOC_CLEAR, /* 0x21 */ + ZFS_IOC_PROMOTE, /* 0x22 */ + /* start of mismatch */ + + ZFS_IOC_DESTROY_SNAPS, /* 0x23:0x3b */ + ZFS_IOC_SNAPSHOT, /* 0x24:0x23 */ + ZFS_IOC_DSOBJ_TO_DSNAME, /* 0x25:0x24 */ + ZFS_IOC_OBJ_TO_PATH, /* 0x26:0x25 */ + ZFS_IOC_POOL_SET_PROPS, /* 0x27:0x26 */ + ZFS_IOC_POOL_GET_PROPS, /* 0x28:0x27 */ + ZFS_IOC_SET_FSACL, /* 0x29:0x28 */ + ZFS_IOC_GET_FSACL, /* 0x30:0x29 */ + ZFS_IOC_SHARE, /* 0x2b:0x2a */ + ZFS_IOC_INHERIT_PROP, /* 0x2c:0x2b */ + ZFS_IOC_SMB_ACL, /* 0x2d:0x2c */ + ZFS_IOC_USERSPACE_ONE, /* 0x2e:0x2d */ + ZFS_IOC_USERSPACE_MANY, /* 0x2f:0x2e */ + ZFS_IOC_USERSPACE_UPGRADE, /* 0x30:0x2f */ + ZFS_IOC_HOLD, /* 0x31:0x30 */ + ZFS_IOC_RELEASE, /* 0x32:0x31 */ + ZFS_IOC_GET_HOLDS, /* 0x33:0x32 */ + ZFS_IOC_OBJSET_RECVD_PROPS, /* 0x34:0x33 */ + ZFS_IOC_VDEV_SPLIT, /* 0x35:0x34 */ + ZFS_IOC_NEXT_OBJ, /* 0x36:0x35 */ + ZFS_IOC_DIFF, /* 0x37:0x36 */ + ZFS_IOC_TMP_SNAPSHOT, /* 0x38:0x37 */ + ZFS_IOC_OBJ_TO_STATS, /* 0x39:0x38 */ + ZFS_IOC_JAIL, /* 0x3a:0xc2 */ + ZFS_IOC_UNJAIL, /* 0x3b:0xc3 */ + ZFS_IOC_POOL_REGUID, /* 0x3c:0x3c */ + ZFS_IOC_SPACE_WRITTEN, /* 0x3d:0x39 */ + ZFS_IOC_SPACE_SNAPS, /* 0x3e:0x3a */ + ZFS_IOC_SEND_PROGRESS, /* 0x3f:0x3e */ + ZFS_IOC_POOL_REOPEN, /* 0x40:0x3d */ + ZFS_IOC_LOG_HISTORY, /* 0x41:0x3f */ + ZFS_IOC_SEND_NEW, /* 0x42:0x40 */ + ZFS_IOC_SEND_SPACE, /* 0x43:0x41 */ + ZFS_IOC_CLONE, /* 0x44:0x42 */ + ZFS_IOC_BOOKMARK, /* 0x45:0x43 */ + ZFS_IOC_GET_BOOKMARKS, /* 0x46:0x44 */ + ZFS_IOC_DESTROY_BOOKMARKS, /* 0x47:0x45 */ + ZFS_IOC_NEXTBOOT, /* 0x48:0xc1 */ + ZFS_IOC_CHANNEL_PROGRAM, /* 0x49:0x48 */ + ZFS_IOC_REMAP, /* 0x4a:0x4c */ + ZFS_IOC_POOL_CHECKPOINT, /* 0x4b:0x4d */ + ZFS_IOC_POOL_DISCARD_CHECKPOINT, /* 0x4c:0x4e */ + ZFS_IOC_POOL_INITIALIZE, /* 0x4d:0x4f */ +}; + +unsigned static long zfs_ioctl_ozfs_to_legacy_common_[] = { + ZFS_IOC_POOL_CREATE, /* 0x00 */ + ZFS_IOC_POOL_DESTROY, /* 0x01 */ + ZFS_IOC_POOL_IMPORT, /* 0x02 */ + ZFS_IOC_POOL_EXPORT, /* 0x03 */ + ZFS_IOC_POOL_CONFIGS, /* 0x04 */ + ZFS_IOC_POOL_STATS, /* 0x05 */ + ZFS_IOC_POOL_TRYIMPORT, /* 0x06 */ + ZFS_IOC_POOL_SCAN, /* 0x07 */ + ZFS_IOC_POOL_FREEZE, /* 0x08 */ + ZFS_IOC_POOL_UPGRADE, /* 0x09 */ + ZFS_IOC_POOL_GET_HISTORY, /* 0x0a */ + ZFS_IOC_VDEV_ADD, /* 0x0b */ + ZFS_IOC_VDEV_REMOVE, /* 0x0c */ + ZFS_IOC_VDEV_SET_STATE, /* 0x0d */ + ZFS_IOC_VDEV_ATTACH, /* 0x0e */ + ZFS_IOC_VDEV_DETACH, /* 0x0f */ + ZFS_IOC_VDEV_SETPATH, /* 0x10 */ + ZFS_IOC_VDEV_SETFRU, /* 0x11 */ + ZFS_IOC_OBJSET_STATS, /* 0x12 */ + ZFS_IOC_OBJSET_ZPLPROPS, /* 0x13 */ + ZFS_IOC_DATASET_LIST_NEXT, /* 0x14 */ + ZFS_IOC_SNAPSHOT_LIST_NEXT, /* 0x15 */ + ZFS_IOC_SET_PROP, /* 0x16 */ + ZFS_IOC_CREATE, /* 0x17 */ + ZFS_IOC_DESTROY, /* 0x18 */ + ZFS_IOC_ROLLBACK, /* 0x19 */ + ZFS_IOC_RENAME, /* 0x1a */ + ZFS_IOC_RECV, /* 0x1b */ + ZFS_IOC_SEND, /* 0x1c */ + ZFS_IOC_INJECT_FAULT, /* 0x1d */ + ZFS_IOC_CLEAR_FAULT, /* 0x1e */ + ZFS_IOC_INJECT_LIST_NEXT, /* 0x1f */ + ZFS_IOC_ERROR_LOG, /* 0x20 */ + ZFS_IOC_CLEAR, /* 0x21 */ + ZFS_IOC_PROMOTE, /* 0x22 */ + /* start of mismatch */ + ZFS_IOC_LEGACY_SNAPSHOT, /* 0x23 */ + ZFS_IOC_LEGACY_DSOBJ_TO_DSNAME, /* 0x24 */ + ZFS_IOC_LEGACY_OBJ_TO_PATH, /* 0x25 */ + ZFS_IOC_LEGACY_POOL_SET_PROPS, /* 0x26 */ + ZFS_IOC_LEGACY_POOL_GET_PROPS, /* 0x27 */ + ZFS_IOC_LEGACY_SET_FSACL, /* 0x28 */ + ZFS_IOC_LEGACY_GET_FSACL, /* 0x29 */ + ZFS_IOC_LEGACY_SHARE, /* 0x2a */ + ZFS_IOC_LEGACY_INHERIT_PROP, /* 0x2b */ + ZFS_IOC_LEGACY_SMB_ACL, /* 0x2c */ + ZFS_IOC_LEGACY_USERSPACE_ONE, /* 0x2d */ + ZFS_IOC_LEGACY_USERSPACE_MANY, /* 0x2e */ + ZFS_IOC_LEGACY_USERSPACE_UPGRADE, /* 0x2f */ + ZFS_IOC_LEGACY_HOLD, /* 0x30 */ + ZFS_IOC_LEGACY_RELEASE, /* 0x31 */ + ZFS_IOC_LEGACY_GET_HOLDS, /* 0x32 */ + ZFS_IOC_LEGACY_OBJSET_RECVD_PROPS, /* 0x33 */ + ZFS_IOC_LEGACY_VDEV_SPLIT, /* 0x34 */ + ZFS_IOC_LEGACY_NEXT_OBJ, /* 0x35 */ + ZFS_IOC_LEGACY_DIFF, /* 0x36 */ + ZFS_IOC_LEGACY_TMP_SNAPSHOT, /* 0x37 */ + ZFS_IOC_LEGACY_OBJ_TO_STATS, /* 0x38 */ + ZFS_IOC_LEGACY_SPACE_WRITTEN, /* 0x39 */ + ZFS_IOC_LEGACY_SPACE_SNAPS, /* 0x3a */ + ZFS_IOC_LEGACY_DESTROY_SNAPS, /* 0x3b */ + ZFS_IOC_LEGACY_POOL_REGUID, /* 0x3c */ + ZFS_IOC_LEGACY_POOL_REOPEN, /* 0x3d */ + ZFS_IOC_LEGACY_SEND_PROGRESS, /* 0x3e */ + ZFS_IOC_LEGACY_LOG_HISTORY, /* 0x3f */ + ZFS_IOC_LEGACY_SEND_NEW, /* 0x40 */ + ZFS_IOC_LEGACY_SEND_SPACE, /* 0x41 */ + ZFS_IOC_LEGACY_CLONE, /* 0x42 */ + ZFS_IOC_LEGACY_BOOKMARK, /* 0x43 */ + ZFS_IOC_LEGACY_GET_BOOKMARKS, /* 0x44 */ + ZFS_IOC_LEGACY_DESTROY_BOOKMARKS, /* 0x45 */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_RECV_NEW */ + ZFS_IOC_LEGACY_POOL_SYNC, /* 0x47 */ + ZFS_IOC_LEGACY_CHANNEL_PROGRAM, /* 0x48 */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_LOAD_KEY */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_UNLOAD_KEY */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_CHANGE_KEY */ + ZFS_IOC_LEGACY_REMAP, /* 0x4c */ + ZFS_IOC_LEGACY_POOL_CHECKPOINT, /* 0x4d */ + ZFS_IOC_LEGACY_POOL_DISCARD_CHECKPOINT, /* 0x4e */ + ZFS_IOC_LEGACY_POOL_INITIALIZE, /* 0x4f */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_POOL_TRIM */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_REDACT */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_GET_BOOKMARK_PROPS */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_WAIT */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_WAIT_FS */ +}; + +unsigned static long zfs_ioctl_ozfs_to_legacy_platform_[] = { + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_EVENTS_NEXT */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_EVENTS_CLEAR */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_EVENTS_SEEK */ + ZFS_IOC_LEGACY_NEXTBOOT, + ZFS_IOC_LEGACY_JAIL, + ZFS_IOC_LEGACY_UNJAIL, + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_SET_BOOTENV */ + ZFS_IOC_LEGACY_NONE, /* ZFS_IOC_GET_BOOTENV */ +}; + +int +zfs_ioctl_legacy_to_ozfs(int request) +{ + if (request >= sizeof (zfs_ioctl_legacy_to_ozfs_)/sizeof (long)) + return (-1); + return (zfs_ioctl_legacy_to_ozfs_[request]); +} + +int +zfs_ioctl_ozfs_to_legacy(int request) +{ + if (request > ZFS_IOC_LAST) + return (-1); + + if (request > ZFS_IOC_PLATFORM) + return (zfs_ioctl_ozfs_to_legacy_platform_[request]); + if (request >= sizeof (zfs_ioctl_ozfs_to_legacy_common_)/sizeof (long)) + return (-1); + return (zfs_ioctl_ozfs_to_legacy_common_[request]); +} + +void +zfs_cmd_legacy_to_ozfs(zfs_cmd_legacy_t *src, zfs_cmd_t *dst) +{ + memcpy(dst, src, offsetof(zfs_cmd_t, zc_objset_stats)); + *&dst->zc_objset_stats = *&src->zc_objset_stats; + memcpy(&dst->zc_begin_record, &src->zc_begin_record, + offsetof(zfs_cmd_t, zc_sendobj) - + offsetof(zfs_cmd_t, zc_begin_record)); + memcpy(&dst->zc_sendobj, &src->zc_sendobj, + sizeof (zfs_cmd_t) - 8 - offsetof(zfs_cmd_t, zc_sendobj)); + dst->zc_zoneid = src->zc_jailid; +} + +void +zfs_cmd_ozfs_to_legacy(zfs_cmd_t *src, zfs_cmd_legacy_t *dst) +{ + memcpy(dst, src, offsetof(zfs_cmd_t, zc_objset_stats)); + *&dst->zc_objset_stats = *&src->zc_objset_stats; + *&dst->zc_begin_record.drr_u.drr_begin = *&src->zc_begin_record; + dst->zc_begin_record.drr_payloadlen = 0; + dst->zc_begin_record.drr_type = 0; + + memcpy(&dst->zc_inject_record, &src->zc_inject_record, + offsetof(zfs_cmd_t, zc_sendobj) - + offsetof(zfs_cmd_t, zc_inject_record)); + dst->zc_resumable = B_FALSE; + memcpy(&dst->zc_sendobj, &src->zc_sendobj, + sizeof (zfs_cmd_t) - 8 - offsetof(zfs_cmd_t, zc_sendobj)); + dst->zc_jailid = src->zc_zoneid; +}