summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/common
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2013-04-09 22:27:44 +0000
committermm <mm@FreeBSD.org>2013-04-09 22:27:44 +0000
commit6cbe43292efc65801d4567c37e87a006c8850340 (patch)
treee9111837bcbde6a67f9789b2333ecdb28085ef46 /sys/cddl/contrib/opensolaris/common
parent306fddaf7801d7fae1206025486e9d9a97f52ad4 (diff)
downloadFreeBSD-src-6cbe43292efc65801d4567c37e87a006c8850340.zip
FreeBSD-src-6cbe43292efc65801d4567c37e87a006c8850340.tar.gz
ZFS expects a copyout of zfs_cmd_t on an ioctl error. Our sys_ioctl()
doesn't copyout in this case. To solve this issue a new struct zfs_iocparm_t is introduced consisting of: - zfs_ioctl_version (future backwards compatibility purposes) - user space pointer to zfs_cmd_t (copyin and copyout) - size of zfs_cmd_t (verification purposes) The copyin and copyout of zfs_cmd_t is now done the illumos (vendor) way what makes porting of new changes easier and ensures correct behavior if returning an error. MFC after: 10 days
Diffstat (limited to 'sys/cddl/contrib/opensolaris/common')
-rw-r--r--sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c14
-rw-r--r--sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h10
2 files changed, 19 insertions, 5 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 df91b2e..cfa4f44 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
@@ -577,12 +577,18 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
int nc, ret;
void *zc_c;
unsigned long ncmd;
+ zfs_iocparm_t zp;
switch (cflag) {
case ZFS_CMD_COMPAT_NONE:
+ ncmd = _IOWR('Z', request, struct zfs_iocparm);
+ zp.zfs_cmd = (uint64_t)zc;
+ zp.zfs_cmd_size = sizeof(zfs_cmd_t);
+ zp.zfs_ioctl_version = ZFS_IOCVER_CURRENT;
+ return (ioctl(fd, ncmd, &zp));
+ case ZFS_CMD_COMPAT_LZC:
ncmd = _IOWR('Z', request, struct zfs_cmd);
- ret = ioctl(fd, ncmd, zc);
- return (ret);
+ return (ioctl(fd, ncmd, zc));
case ZFS_CMD_COMPAT_DEADMAN:
zc_c = malloc(sizeof(zfs_cmd_deadman_t));
ncmd = _IOWR('Z', request, struct zfs_cmd_deadman);
@@ -677,7 +683,7 @@ zfs_ioctl_compat_innvl(zfs_cmd_t *zc, nvlist_t * innvl, const int vec,
char *poolname, *snapname;
int err;
- if (cflag == ZFS_CMD_COMPAT_NONE)
+ if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC)
goto out;
switch (vec) {
@@ -828,7 +834,7 @@ zfs_ioctl_compat_outnvl(zfs_cmd_t *zc, nvlist_t * outnvl, const int vec,
{
nvlist_t *tmpnvl;
- if (cflag == ZFS_CMD_COMPAT_NONE)
+ if (cflag == ZFS_CMD_COMPAT_NONE || cflag == ZFS_CMD_COMPAT_LZC)
return (outnvl);
switch (vec) {
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 0e7130d..6e8d51d 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
@@ -49,19 +49,27 @@ extern "C" {
#define ZFS_IOCVER_NONE 0
#define ZFS_IOCVER_DEADMAN 1
#define ZFS_IOCVER_LZC 2
-#define ZFS_IOCVER_CURRENT ZFS_IOCVER_LZC
+#define ZFS_IOCVER_ZCMD 3
+#define ZFS_IOCVER_CURRENT ZFS_IOCVER_ZCMD
/* 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_CMD_COMPAT_LZC 4
#define ZFS_IOC_COMPAT_PASS 254
#define ZFS_IOC_COMPAT_FAIL 255
#define ZFS_IOCREQ(ioreq) ((ioreq) & 0xff)
+typedef struct zfs_iocparm {
+ uint32_t zfs_ioctl_version;
+ uint64_t zfs_cmd;
+ uint64_t zfs_cmd_size;
+} zfs_iocparm_t;
+
typedef struct zinject_record_v15 {
uint64_t zi_objset;
uint64_t zi_object;
OpenPOWER on IntegriCloud