diff options
author | mm <mm@FreeBSD.org> | 2013-04-09 22:27:44 +0000 |
---|---|---|
committer | mm <mm@FreeBSD.org> | 2013-04-09 22:27:44 +0000 |
commit | 6cbe43292efc65801d4567c37e87a006c8850340 (patch) | |
tree | e9111837bcbde6a67f9789b2333ecdb28085ef46 /sys/cddl/contrib/opensolaris/common | |
parent | 306fddaf7801d7fae1206025486e9d9a97f52ad4 (diff) | |
download | FreeBSD-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.c | 14 | ||||
-rw-r--r-- | sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h | 10 |
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; |