summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2013-03-17 10:57:04 +0000
committermm <mm@FreeBSD.org>2013-03-17 10:57:04 +0000
commit6c7511b96eb323641755bcec17f25f6f6f220a35 (patch)
tree40daf53539cb7fa1f1f9d3393c67ff6457a692bf /sys/cddl
parentb9a4266c5c62b694f294026dcd9c7d02b41da67e (diff)
downloadFreeBSD-src-6c7511b96eb323641755bcec17f25f6f6f220a35.zip
FreeBSD-src-6c7511b96eb323641755bcec17f25f6f6f220a35.tar.gz
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
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c258
-rw-r--r--sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h50
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c23
3 files changed, 309 insertions, 22 deletions
diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
index 0463e9a..926ba26 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
@@ -33,6 +33,7 @@
#include <sys/nvpair.h>
#include <sys/dsl_deleg.h>
#include <sys/zfs_ioctl.h>
+#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_t addr, const int cflag)
{
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_t addr, const int cflag)
{
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_t *zc)
#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 cmd, zfs_cmd_t *zc, const int cflag)
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 cmd, zfs_cmd_t *zc, const int cflag)
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 cmd, zfs_cmd_t *zc, const int cflag)
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 vec, const int cflag)
{
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 vec, const int cflag)
}
}
}
+
+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 */
diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
index 6e897b8..2ec2242 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
@@ -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_v15[] = {
#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);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index 38c386e..bb2ead3 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -5805,7 +5805,7 @@ zfsdev_ioctl(struct cdev *dev, u_long zcmd, caddr_t arg, int flag,
#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 zcmd, caddr_t arg, int flag,
* 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 zcmd, caddr_t arg, int flag,
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 zcmd, caddr_t arg, int flag,
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 zcmd, caddr_t arg, int flag,
}
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) {
OpenPOWER on IntegriCloud