From owner-svn-src-projects@FreeBSD.ORG Sun Mar 17 10:57:06 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id F288FA43; Sun, 17 Mar 2013 10:57:05 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id D6895B54; Sun, 17 Mar 2013 10:57:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r2HAv5vW059697; Sun, 17 Mar 2013 10:57:05 GMT (envelope-from mm@svn.freebsd.org) Received: (from mm@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r2HAv5Kr059691; Sun, 17 Mar 2013 10:57:05 GMT (envelope-from mm@svn.freebsd.org) Message-Id: <201303171057.r2HAv5Kr059691@svn.freebsd.org> From: Martin Matuska Date: Sun, 17 Mar 2013 10:57:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r248421 - in projects/libzfs_core: cddl/contrib/opensolaris/lib/libzfs/common sys/cddl/contrib/opensolaris/common/zfs sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Mar 2013 10:57:06 -0000 Author: mm Date: Sun Mar 17 10:57:04 2013 New Revision: 248421 URL: http://svnweb.freebsd.org/changeset/base/248421 Log: libzfs_core: - provide complete backwards compatibility (old utility, new kernel) - add zfs_cmd_t compatibility mapping in both directions - determine ioctl address in zfs_ioctl_compat.c Modified: projects/libzfs_core/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h projects/libzfs_core/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c projects/libzfs_core/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h projects/libzfs_core/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Modified: projects/libzfs_core/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h ============================================================================== --- projects/libzfs_core/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h Sun Mar 17 07:49:44 2013 (r248420) +++ projects/libzfs_core/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h Sun Mar 17 10:57:04 2013 (r248421) @@ -43,18 +43,18 @@ static int zfs_ioctl_version = 0; static __inline int zcmd_ioctl(int fd, int request, zfs_cmd_t *zc) { - unsigned long cmd; size_t oldsize, zfs_kernel_version_size, zfs_ioctl_version_size; int version, ret, cflag = ZFS_CMD_COMPAT_NONE; - cmd = _IOWR('Z', request, struct zfs_cmd); - zfs_ioctl_version_size = sizeof(zfs_ioctl_version); if (zfs_ioctl_version == 0) { sysctlbyname("vfs.zfs.version.ioctl", &zfs_ioctl_version, &zfs_ioctl_version_size, NULL, 0); } + if (zfs_ioctl_version == ZFS_IOCVER_DEADMAN) + cflag = ZFS_CMD_COMPAT_DEADMAN; + /* * If vfs.zfs.version.ioctl is not defined, assume we have v28 * compatible binaries and use vfs.zfs.version.spa to test for v15 @@ -76,7 +76,7 @@ zcmd_ioctl(int fd, int request, zfs_cmd_ } oldsize = zc->zc_nvlist_dst_size; - ret = zcmd_ioctl_compat(fd, cmd, zc, cflag); + ret = zcmd_ioctl_compat(fd, request, zc, cflag); if (ret == 0 && oldsize < zc->zc_nvlist_dst_size) { ret = -1; @@ -85,7 +85,7 @@ zcmd_ioctl(int fd, int request, zfs_cmd_ return (ret); } -#define ioctl(fd, cmd, zc) zcmd_ioctl((fd), (cmd), (zc)) +#define ioctl(fd, ioc, zc) zcmd_ioctl((fd), (ioc), (zc)) #ifdef __cplusplus } Modified: projects/libzfs_core/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c ============================================================================== --- projects/libzfs_core/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c Sun Mar 17 07:49:44 2013 (r248420) +++ projects/libzfs_core/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c Sun Mar 17 10:57:04 2013 (r248421) @@ -33,6 +33,7 @@ #include #include #include +#include "zfs_namecheck.h" #include "zfs_ioctl_compat.h" static int zfs_version_ioctl = ZFS_IOCVER_CURRENT; @@ -49,8 +50,53 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_ { zfs_cmd_v15_t *zc_c; zfs_cmd_v28_t *zc28_c; + zfs_cmd_deadman_t *zcdm_c; switch (cflag) { + case ZFS_CMD_COMPAT_DEADMAN: + zcdm_c = (void *)addr; + /* zc */ + strlcpy(zc->zc_name, zcdm_c->zc_name, MAXPATHLEN); + strlcpy(zc->zc_value, zcdm_c->zc_value, MAXPATHLEN * 2); + strlcpy(zc->zc_string, zcdm_c->zc_string, MAXPATHLEN); + strlcpy(zc->zc_top_ds, zcdm_c->zc_top_ds, MAXPATHLEN); + zc->zc_guid = zcdm_c->zc_guid; + zc->zc_nvlist_conf = zcdm_c->zc_nvlist_conf; + zc->zc_nvlist_conf_size = zcdm_c->zc_nvlist_conf_size; + zc->zc_nvlist_src = zcdm_c->zc_nvlist_src; + zc->zc_nvlist_src_size = zcdm_c->zc_nvlist_src_size; + zc->zc_nvlist_dst = zcdm_c->zc_nvlist_dst; + zc->zc_nvlist_dst_size = zcdm_c->zc_nvlist_dst_size; + zc->zc_cookie = zcdm_c->zc_cookie; + zc->zc_objset_type = zcdm_c->zc_objset_type; + zc->zc_perm_action = zcdm_c->zc_perm_action; + zc->zc_history = zcdm_c->zc_history; + zc->zc_history_len = zcdm_c->zc_history_len; + zc->zc_history_offset = zcdm_c->zc_history_offset; + zc->zc_obj = zcdm_c->zc_obj; + zc->zc_iflags = zcdm_c->zc_iflags; + zc->zc_share = zcdm_c->zc_share; + zc->zc_jailid = zcdm_c->zc_jailid; + zc->zc_objset_stats = zcdm_c->zc_objset_stats; + zc->zc_begin_record = zcdm_c->zc_begin_record; + zc->zc_defer_destroy = zcdm_c->zc_defer_destroy; + zc->zc_temphold = zcdm_c->zc_temphold; + zc->zc_action_handle = zcdm_c->zc_action_handle; + zc->zc_cleanup_fd = zcdm_c->zc_cleanup_fd; + zc->zc_simple = zcdm_c->zc_simple; + bcopy(zcdm_c->zc_pad, zc->zc_pad, sizeof(zc->zc_pad)); + zc->zc_sendobj = zcdm_c->zc_sendobj; + zc->zc_fromobj = zcdm_c->zc_fromobj; + zc->zc_createtxg = zcdm_c->zc_createtxg; + zc->zc_stat = zcdm_c->zc_stat; + + /* zc_inject_record doesn't change in libzfs_core */ + zcdm_c->zc_inject_record = zc->zc_inject_record; + + /* we always assume zc_nvlist_dst_filled is true */ + zc->zc_nvlist_dst_filled = B_TRUE; + break; + case ZFS_CMD_COMPAT_V28: zc28_c = (void *)addr; @@ -178,8 +224,51 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_ { zfs_cmd_v15_t *zc_c; zfs_cmd_v28_t *zc28_c; + zfs_cmd_deadman_t *zcdm_c; switch (cflag) { + case ZFS_CMD_COMPAT_DEADMAN: + zcdm_c = (void *)addr; + + strlcpy(zcdm_c->zc_name, zc->zc_name, MAXPATHLEN); + strlcpy(zcdm_c->zc_value, zc->zc_value, MAXPATHLEN * 2); + strlcpy(zcdm_c->zc_string, zc->zc_string, MAXPATHLEN); + strlcpy(zcdm_c->zc_top_ds, zc->zc_top_ds, MAXPATHLEN); + zcdm_c->zc_guid = zc->zc_guid; + zcdm_c->zc_nvlist_conf = zc->zc_nvlist_conf; + zcdm_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size; + zcdm_c->zc_nvlist_src = zc->zc_nvlist_src; + zcdm_c->zc_nvlist_src_size = zc->zc_nvlist_src_size; + zcdm_c->zc_nvlist_dst = zc->zc_nvlist_dst; + zcdm_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size; + zcdm_c->zc_cookie = zc->zc_cookie; + zcdm_c->zc_objset_type = zc->zc_objset_type; + zcdm_c->zc_perm_action = zc->zc_perm_action; + zcdm_c->zc_history = zc->zc_history; + zcdm_c->zc_history_len = zc->zc_history_len; + zcdm_c->zc_history_offset = zc->zc_history_offset; + zcdm_c->zc_obj = zc->zc_obj; + zcdm_c->zc_iflags = zc->zc_iflags; + zcdm_c->zc_share = zc->zc_share; + zcdm_c->zc_jailid = zc->zc_jailid; + zcdm_c->zc_objset_stats = zc->zc_objset_stats; + zcdm_c->zc_begin_record = zc->zc_begin_record; + zcdm_c->zc_defer_destroy = zc->zc_defer_destroy; + zcdm_c->zc_temphold = zc->zc_temphold; + zcdm_c->zc_action_handle = zc->zc_action_handle; + zcdm_c->zc_cleanup_fd = zc->zc_cleanup_fd; + zcdm_c->zc_simple = zc->zc_simple; + bcopy(zc->zc_pad, zcdm_c->zc_pad, sizeof(zcdm_c->zc_pad)); + zcdm_c->zc_sendobj = zc->zc_sendobj; + zcdm_c->zc_fromobj = zc->zc_fromobj; + zcdm_c->zc_createtxg = zc->zc_createtxg; + zcdm_c->zc_stat = zc->zc_stat; + + /* zc_inject_record doesn't change in libzfs_core */ + zc->zc_inject_record = zcdm_c->zc_inject_record; + + break; + case ZFS_CMD_COMPAT_V28: zc28_c = (void *)addr; @@ -476,7 +565,7 @@ zfs_ioctl_compat_pool_get_props(zfs_cmd_ #ifndef _KERNEL int -zcmd_ioctl_compat(int fd, unsigned long cmd, zfs_cmd_t *zc, const int cflag) +zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag) { int nc, ret; void *zc_c; @@ -484,16 +573,21 @@ zcmd_ioctl_compat(int fd, unsigned long switch (cflag) { case ZFS_CMD_COMPAT_NONE: - ret = ioctl(fd, cmd, zc); + ncmd = _IOWR('Z', request, struct zfs_cmd); + ret = ioctl(fd, ncmd, zc); return (ret); + case ZFS_CMD_COMPAT_DEADMAN: + zc_c = malloc(sizeof(zfs_cmd_deadman_t)); + ncmd = _IOWR('Z', request, struct zfs_cmd_deadman); + break; case ZFS_CMD_COMPAT_V28: zc_c = malloc(sizeof(zfs_cmd_v28_t)); - ncmd = _IOWR('Z', ZFS_IOCREQ(cmd), struct zfs_cmd_v28); + ncmd = _IOWR('Z', request, struct zfs_cmd_v28); break; case ZFS_CMD_COMPAT_V15: - nc = zfs_ioctl_v28_to_v15[ZFS_IOCREQ(cmd)]; + nc = zfs_ioctl_v28_to_v15[request]; zc_c = malloc(sizeof(zfs_cmd_v15_t)); - ncmd = _IOWR('Z', nc, struct zfs_cmd_v15); + ncmd = _IOWR('Z', request, struct zfs_cmd_v15); break; default: return (EINVAL); @@ -505,18 +599,18 @@ zcmd_ioctl_compat(int fd, unsigned long zfs_cmd_compat_put(zc, (caddr_t)zc_c, cflag); ret = ioctl(fd, ncmd, zc_c); if (cflag == ZFS_CMD_COMPAT_V15 && - nc == 2 /* ZFS_IOC_POOL_IMPORT */) - ret = ioctl(fd, _IOWR('Z', 4 /* ZFS_IOC_POOL_CONFIGS */, + nc == ZFS_IOC_POOL_IMPORT) + ret = ioctl(fd, _IOWR('Z', ZFS_IOC_POOL_CONFIGS, struct zfs_cmd_v15), zc_c); zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag); free(zc_c); if (cflag == ZFS_CMD_COMPAT_V15) { switch (nc) { - case 2: /* ZFS_IOC_POOL_IMPORT */ - case 4: /* ZFS_IOC_POOL_CONFIGS */ - case 5: /* ZFS_IOC_POOL_STATS */ - case 6: /* ZFS_IOC_POOL_TRYIMPORT */ + case ZFS_IOC_POOL_IMPORT: + case ZFS_IOC_POOL_CONFIGS: + case ZFS_IOC_POOL_STATS: + case ZFS_IOC_POOL_TRYIMPORT: zfs_ioctl_compat_fix_stats(zc, nc); break; case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */ @@ -528,16 +622,25 @@ zcmd_ioctl_compat(int fd, unsigned long return (ret); } #else /* _KERNEL */ -void +int zfs_ioctl_compat_pre(zfs_cmd_t *zc, int *vec, const int cflag) { - if (cflag == ZFS_CMD_COMPAT_V15) + int error = 0; + + /* are we creating a clone? */ + if (*vec == ZFS_IOC_CREATE && zc->zc_value[0] != '\0') + *vec = ZFS_IOC_CLONE; + + if (cflag == ZFS_CMD_COMPAT_V15) { switch (*vec) { case 7: /* ZFS_IOC_POOL_SCRUB (v15) */ zc->zc_cookie = POOL_SCAN_SCRUB; break; } + } + + return (error); } void @@ -545,9 +648,9 @@ zfs_ioctl_compat_post(zfs_cmd_t *zc, int { if (cflag == ZFS_CMD_COMPAT_V15) { switch (vec) { - case 4: /* ZFS_IOC_POOL_CONFIGS */ - case 5: /* ZFS_IOC_POOL_STATS */ - case 6: /* ZFS_IOC_POOL_TRYIMPORT */ + case ZFS_IOC_POOL_CONFIGS: + case ZFS_IOC_POOL_STATS: + case ZFS_IOC_POOL_TRYIMPORT: zfs_ioctl_compat_fix_stats(zc, vec); break; case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */ @@ -556,4 +659,127 @@ zfs_ioctl_compat_post(zfs_cmd_t *zc, int } } } + +nvlist_t * +zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec, + const int cflag) +{ + nvlist_t *nvl, *tmpnvl; + char *poolname, *snapname; + int err; + + if (cflag == ZFS_CMD_COMPAT_NONE) + goto out; + + switch (vec) { + case ZFS_IOC_CREATE: + nvl = fnvlist_alloc(); + fnvlist_add_int32(nvl, "type", zc->zc_objset_type); + if (innvl != NULL) { + fnvlist_add_nvlist(nvl, "props", innvl); + nvlist_free(innvl); + } + return (nvl); + break; + case ZFS_IOC_CLONE: + nvl = fnvlist_alloc(); + fnvlist_add_string(nvl, "origin", zc->zc_value); + if (innvl != NULL) { + fnvlist_add_nvlist(nvl, "props", innvl); + nvlist_free(innvl); + } + return (nvl); + break; + case ZFS_IOC_SNAPSHOT: + if (innvl == NULL) + goto out; + nvl = fnvlist_alloc(); + fnvlist_add_nvlist(nvl, "props", innvl); + tmpnvl = fnvlist_alloc(); + snapname = kmem_asprintf("%s@%s", zc->zc_name, zc->zc_value); + fnvlist_add_boolean(tmpnvl, snapname); + kmem_free(snapname, strlen(snapname + 1)); + /* check if we are doing a recursive snapshot */ + if (zc->zc_cookie) + dmu_get_recursive_snaps_nvl(zc->zc_name, zc->zc_value, + tmpnvl); + fnvlist_add_nvlist(nvl, "snaps", tmpnvl); + fnvlist_free(tmpnvl); + nvlist_free(innvl); + /* strip dataset part from zc->zc_name */ + zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0'; + return (nvl); + break; + case ZFS_IOC_SPACE_SNAPS: + nvl = fnvlist_alloc(); + fnvlist_add_string(nvl, "firstsnap", zc->zc_value); + if (innvl != NULL) + nvlist_free(innvl); + return (nvl); + break; + case ZFS_IOC_DESTROY_SNAPS: + if (innvl == NULL && cflag == ZFS_CMD_COMPAT_DEADMAN) + goto out; + nvl = fnvlist_alloc(); + if (innvl != NULL) { + fnvlist_add_nvlist(nvl, "snaps", innvl); + } else { + /* + * We are probably called by even older binaries, + * allocate and populate nvlist with recursive + * snapshots + */ + if (snapshot_namecheck(zc->zc_value, NULL, + NULL) == 0) { + tmpnvl = fnvlist_alloc(); + if (dmu_get_recursive_snaps_nvl(zc->zc_name, + zc->zc_value, tmpnvl) == 0) + fnvlist_add_nvlist(nvl, "snaps", + tmpnvl); + nvlist_free(tmpnvl); + } + } + if (innvl != NULL) + nvlist_free(innvl); + /* strip dataset part from zc->zc_name */ + zc->zc_name[strcspn(zc->zc_name, "/@")] = '\0'; + return (nvl); + break; + } +out: + return (innvl); +} + +nvlist_t * +zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec, + const int cflag) +{ + nvlist_t *tmpnvl; + + if (cflag == ZFS_CMD_COMPAT_NONE) + return (outnvl); + + switch (vec) { + case ZFS_IOC_SPACE_SNAPS: + (void) nvlist_lookup_uint64(outnvl, "used", &zc->zc_cookie); + (void) nvlist_lookup_uint64(outnvl, "compressed", + &zc->zc_objset_type); + (void) nvlist_lookup_uint64(outnvl, "uncompressed", + &zc->zc_perm_action); + nvlist_free(outnvl); + /* return empty outnvl */ + tmpnvl = fnvlist_alloc(); + return (tmpnvl); + break; + case ZFS_IOC_CREATE: + case ZFS_IOC_CLONE: + nvlist_free(outnvl); + /* return empty outnvl */ + tmpnvl = fnvlist_alloc(); + return (tmpnvl); + break; + } + + return (outnvl); +} #endif /* KERNEL */ Modified: projects/libzfs_core/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h ============================================================================== --- projects/libzfs_core/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h Sun Mar 17 07:49:44 2013 (r248420) +++ projects/libzfs_core/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h Sun Mar 17 10:57:04 2013 (r248421) @@ -45,13 +45,15 @@ extern "C" { */ /* ioctl versions for vfs.zfs.version.ioctl */ +#define ZFS_IOCVER_LZC 2 #define ZFS_IOCVER_DEADMAN 1 -#define ZFS_IOCVER_CURRENT ZFS_IOCVER_DEADMAN +#define ZFS_IOCVER_CURRENT ZFS_IOCVER_LZC /* compatibility conversion flag */ #define ZFS_CMD_COMPAT_NONE 0 #define ZFS_CMD_COMPAT_V15 1 #define ZFS_CMD_COMPAT_V28 2 +#define ZFS_CMD_COMPAT_DEADMAN 3 #define ZFS_IOC_COMPAT_PASS 254 #define ZFS_IOC_COMPAT_FAIL 255 @@ -150,6 +152,44 @@ typedef struct zfs_cmd_v28 { zfs_stat_t zc_stat; } zfs_cmd_v28_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_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; + #ifdef _KERNEL unsigned static long zfs_ioctl_v15_to_v28[] = { 0, /* 0 ZFS_IOC_POOL_CREATE */ @@ -274,10 +314,14 @@ unsigned static long zfs_ioctl_v28_to_v1 #endif /* ! _KERNEL */ #ifdef _KERNEL -void zfs_ioctl_compat_pre(zfs_cmd_t *, int *, const int); +int zfs_ioctl_compat_pre(zfs_cmd_t *, int *, const int); void zfs_ioctl_compat_post(zfs_cmd_t *, const int, const int); +nvlist_t *zfs_ioctl_compat_innvl(zfs_cmd_t *, nvlist_t *, const int, + const int); +nvlist_t *zfs_ioctl_compat_outnvl(zfs_cmd_t *, nvlist_t *, const int, + const int); #else -int zcmd_ioctl_compat(int, unsigned long, zfs_cmd_t *, const int); +int zcmd_ioctl_compat(int, int, zfs_cmd_t *, const int); #endif /* _KERNEL */ void zfs_cmd_compat_get(zfs_cmd_t *, caddr_t, const int); void zfs_cmd_compat_put(zfs_cmd_t *, caddr_t, const int); Modified: projects/libzfs_core/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c ============================================================================== --- projects/libzfs_core/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Sun Mar 17 07:49:44 2013 (r248420) +++ projects/libzfs_core/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c Sun Mar 17 10:57:04 2013 (r248421) @@ -5805,7 +5805,7 @@ zfsdev_ioctl(struct cdev *dev, u_long zc #ifdef illumos minor_t minor = getminor(dev); #else - int cflag, cmd; + int cflag, cmd, oldvecnum; cred_t *cr = td->td_ucred; #endif const zfs_ioc_vec_t *vec; @@ -5821,7 +5821,10 @@ zfsdev_ioctl(struct cdev *dev, u_long zc * and translate zfs_cmd if necessary */ if (len < sizeof(zfs_cmd_t)) - if (len == sizeof(zfs_cmd_v28_t)) { + if (len == sizeof(zfs_cmd_deadman_t)) { + cflag = ZFS_CMD_COMPAT_DEADMAN; + vecnum = cmd; + } else if (len == sizeof(zfs_cmd_v28_t)) { cflag = ZFS_CMD_COMPAT_V28; vecnum = cmd; } else if (len == sizeof(zfs_cmd_v15_t)) { @@ -5870,7 +5873,12 @@ zfsdev_ioctl(struct cdev *dev, u_long zc zc = kmem_zalloc(sizeof(zfs_cmd_t), KM_SLEEP); bzero(zc, sizeof(zfs_cmd_t)); zfs_cmd_compat_get(zc, arg, cflag); - zfs_ioctl_compat_pre(zc, &vecnum, cflag); + oldvecnum = vecnum; + error = zfs_ioctl_compat_pre(zc, &vecnum, cflag); + if (error != 0) + goto out; + if (oldvecnum != vecnum) + vec = &zfs_ioc_vec[vecnum]; } else zc = (void *)arg; @@ -5882,6 +5890,10 @@ zfsdev_ioctl(struct cdev *dev, u_long zc goto out; } + /* rewrite innvl for backwards compatibility */ + if (cflag != ZFS_CMD_COMPAT_NONE) + innvl = zfs_ioctl_compat_innvl(zc, innvl, vecnum, cflag); + /* * Ensure that all pool/dataset names are valid before we pass down to * the lower layers. @@ -5955,6 +5967,11 @@ zfsdev_ioctl(struct cdev *dev, u_long zc } fnvlist_free(lognv); + /* rewrite outnvl for backwards compatibility */ + if (cflag != ZFS_CMD_COMPAT_NONE) + outnvl = zfs_ioctl_compat_outnvl(zc, outnvl, vecnum, + cflag); + if (!nvlist_empty(outnvl) || zc->zc_nvlist_dst_size != 0) { int smusherror = 0; if (vec->zvec_smush_outnvlist) {