From 20b867f5f716fedab675f5eac395e7e1ea54572d Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Thu, 27 Oct 2022 22:45:44 +0100 Subject: freebsd: add ifdefs around legacy ioctl support Require that ZFS_LEGACY_SUPPORT be defined for legacy ioctl support to be built. For now, define it in zfs_ioctl_compat.h so support is always built. This will allow systems that need never support pre-openzfs tools a mechanism to remove support at build time. This code should be removed once the need for tool compatability is gone. No functional change at this time. Reviewed-by: Ryan Moeller Reviewed-by: Richard Yao Reviewed-by: Brian Behlendorf Signed-off-by: Brooks Davis Closes #14127 --- include/os/freebsd/zfs/sys/zfs_ioctl_compat.h | 13 +++++++++++++ lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c | 13 ++++++++++++- lib/libzpool/util.c | 4 ++++ module/os/freebsd/zfs/kmod_core.c | 16 ++++++++++++++-- module/os/freebsd/zfs/zfs_ioctl_compat.c | 2 ++ 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h b/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h index 79b30b508..34757a486 100644 --- a/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h +++ b/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h @@ -37,6 +37,15 @@ #include #endif /* _KERNEL */ +/* + * Legacy ioctl support allows compatibility with pre-OpenZFS tools on + * FreeBSD. The need for it will eventually pass (perhaps after FreeBSD + * 12 is well out of support), at which point this code can be removed. + * For now, downstream consumers may choose to disable this code by + * removing the following define. + */ +#define ZFS_LEGACY_SUPPORT + #ifdef __cplusplus extern "C" { #endif @@ -82,6 +91,7 @@ typedef struct zfs_iocparm { } zfs_iocparm_t; +#ifdef ZFS_LEGACY_SUPPORT #define LEGACY_MAXPATHLEN 1024 #define LEGACY_MAXNAMELEN 256 @@ -135,6 +145,7 @@ typedef struct zfs_cmd_legacy { uint64_t zc_createtxg; zfs_stat_t zc_stat; } zfs_cmd_legacy_t; +#endif #ifdef _KERNEL @@ -145,10 +156,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 */ +#ifdef ZFS_LEGACY_SUPPORT 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_ozfs_to_legacy(zfs_cmd_t *src, zfs_cmd_legacy_t *dst); +#endif void zfs_cmd_compat_put(zfs_cmd_t *, caddr_t, const int, const int); diff --git a/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c b/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c index 36fbbd88c..72f8f3930 100644 --- a/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c +++ b/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c @@ -46,8 +46,11 @@ get_zfs_ioctl_version(void) static int zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag) { - int newrequest, ret; + int ret; +#ifdef ZFS_LEGACY_SUPPORT + int newrequest; void *zc_c = NULL; +#endif unsigned long ncmd; zfs_iocparm_t zp; @@ -58,6 +61,7 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag) zp.zfs_cmd_size = sizeof (zfs_cmd_t); zp.zfs_ioctl_version = ZFS_IOCVER_OZFS; break; +#ifdef ZFS_LEGACY_SUPPORT case ZFS_CMD_COMPAT_LEGACY: newrequest = zfs_ioctl_ozfs_to_legacy(request); ncmd = _IOWR('Z', newrequest, zfs_iocparm_t); @@ -67,6 +71,7 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag) zp.zfs_cmd_size = sizeof (zfs_cmd_legacy_t); zp.zfs_ioctl_version = ZFS_IOCVER_LEGACY; break; +#endif default: abort(); return (EINVAL); @@ -74,14 +79,18 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag) ret = ioctl(fd, ncmd, &zp); if (ret) { +#ifdef ZFS_LEGACY_SUPPORT if (zc_c) free(zc_c); +#endif return (ret); } +#ifdef ZFS_LEGACY_SUPPORT if (zc_c) { zfs_cmd_legacy_to_ozfs(zc_c, zc); free(zc_c); } +#endif return (ret); } @@ -100,9 +109,11 @@ lzc_ioctl_fd(int fd, unsigned long request, zfs_cmd_t *zc) zfs_ioctl_version = get_zfs_ioctl_version(); switch (zfs_ioctl_version) { +#ifdef ZFS_LEGACY_SUPPORT case ZFS_IOCVER_LEGACY: cflag = ZFS_CMD_COMPAT_LEGACY; break; +#endif case ZFS_IOCVER_OZFS: cflag = ZFS_CMD_COMPAT_NONE; break; diff --git a/lib/libzpool/util.c b/lib/libzpool/util.c index a310255d7..551f1294d 100644 --- a/lib/libzpool/util.c +++ b/lib/libzpool/util.c @@ -261,7 +261,9 @@ pool_active(void *unused, const char *name, uint64_t guid, boolean_t *isactive) (void) unused, (void) guid; zfs_iocparm_t zp; zfs_cmd_t *zc = NULL; +#ifdef ZFS_LEGACY_SUPPORT zfs_cmd_legacy_t *zcl = NULL; +#endif unsigned long request; int ret; @@ -296,6 +298,7 @@ pool_active(void *unused, const char *name, uint64_t guid, boolean_t *isactive) umem_free(zc, sizeof (zfs_cmd_t)); break; +#ifdef ZFS_LEGACY_SUPPORT case ZFS_IOCVER_LEGACY: zcl = umem_zalloc(sizeof (zfs_cmd_legacy_t), UMEM_NOFAIL); @@ -311,6 +314,7 @@ pool_active(void *unused, const char *name, uint64_t guid, boolean_t *isactive) umem_free(zcl, sizeof (zfs_cmd_legacy_t)); break; +#endif default: fprintf(stderr, "unrecognized zfs ioctl version %d", ver); exit(1); diff --git a/module/os/freebsd/zfs/kmod_core.c b/module/os/freebsd/zfs/kmod_core.c index 020ef6a39..6885d565e 100644 --- a/module/os/freebsd/zfs/kmod_core.c +++ b/module/os/freebsd/zfs/kmod_core.c @@ -124,7 +124,9 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag, int vecnum; zfs_iocparm_t *zp; zfs_cmd_t *zc; +#ifdef ZFS_LEGACY_SUPPORT zfs_cmd_legacy_t *zcl; +#endif int rc, error; void *uaddr; @@ -133,7 +135,9 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag, zp = (void *)arg; uaddr = (void *)zp->zfs_cmd; error = 0; +#ifdef ZFS_LEGACY_SUPPORT zcl = NULL; +#endif if (len != sizeof (zfs_iocparm_t)) { printf("len %d vecnum: %d sizeof (zfs_cmd_t) %ju\n", @@ -142,6 +146,7 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag, } zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); +#ifdef ZFS_LEGACY_SUPPORT /* * Remap ioctl code for legacy user binaries */ @@ -157,22 +162,29 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag, goto out; } zfs_cmd_legacy_to_ozfs(zcl, zc); - } else if (copyin(uaddr, zc, sizeof (zfs_cmd_t))) { + } else +#endif + if (copyin(uaddr, zc, sizeof (zfs_cmd_t))) { error = SET_ERROR(EFAULT); goto out; } error = zfsdev_ioctl_common(vecnum, zc, 0); +#ifdef ZFS_LEGACY_SUPPORT if (zcl) { zfs_cmd_ozfs_to_legacy(zc, zcl); rc = copyout(zcl, uaddr, sizeof (*zcl)); - } else { + } else +#endif + { rc = copyout(zc, uaddr, sizeof (*zc)); } if (error == 0 && rc != 0) error = SET_ERROR(EFAULT); out: +#ifdef ZFS_LEGACY_SUPPORT if (zcl) kmem_free(zcl, sizeof (zfs_cmd_legacy_t)); +#endif kmem_free(zc, sizeof (zfs_cmd_t)); MPASS(tsd_get(rrw_tsd_key) == NULL); return (error); diff --git a/module/os/freebsd/zfs/zfs_ioctl_compat.c b/module/os/freebsd/zfs/zfs_ioctl_compat.c index 08913ab05..3ddffec91 100644 --- a/module/os/freebsd/zfs/zfs_ioctl_compat.c +++ b/module/os/freebsd/zfs/zfs_ioctl_compat.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef ZFS_LEGACY_SUPPORT enum zfs_ioc_legacy { ZFS_IOC_LEGACY_NONE = -1, ZFS_IOC_LEGACY_FIRST = 0, @@ -361,3 +362,4 @@ zfs_cmd_ozfs_to_legacy(zfs_cmd_t *src, zfs_cmd_legacy_t *dst) sizeof (zfs_cmd_t) - 8 - offsetof(zfs_cmd_t, zc_sendobj)); dst->zc_jailid = src->zc_zoneid; } +#endif /* ZFS_LEGACY_SUPPORT */ -- cgit v1.2.3