mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
FreeBSD: zfs commands backward compatibility
Update the zfs commands such that they're backwards compatible with the version of ZFS is the base FreeBSD. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Ryan Moeller <ryan@ixsystems.com> Signed-off-by: Matt Macy <mmacy@FreeBSD.org> Closes #10542
This commit is contained in:
@@ -23,10 +23,16 @@ USER_C += \
|
||||
endif
|
||||
|
||||
if BUILD_FREEBSD
|
||||
DEFAULT_INCLUDES += -I$(top_srcdir)/include/os/freebsd/zfs
|
||||
|
||||
USER_C += \
|
||||
os/freebsd/zutil_device_path_os.c \
|
||||
os/freebsd/zutil_import_os.c \
|
||||
os/freebsd/zutil_compat.c
|
||||
|
||||
VPATH += $(top_srcdir)/module/os/freebsd/zfs
|
||||
|
||||
nodist_libzutil_la_SOURCES = zfs_ioctl_compat.c
|
||||
endif
|
||||
|
||||
libzutil_la_SOURCES = $(USER_C)
|
||||
|
||||
@@ -20,15 +20,35 @@
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/zfs_ioctl.h>
|
||||
#include <os/freebsd/zfs/sys/zfs_ioctl_compat.h>
|
||||
#include <libzutil.h>
|
||||
|
||||
#include <err.h>
|
||||
|
||||
int zfs_ioctl_version = ZFS_IOCVER_UNDEF;
|
||||
|
||||
/*
|
||||
* Get zfs_ioctl_version
|
||||
*/
|
||||
static int
|
||||
get_zfs_ioctl_version(void)
|
||||
{
|
||||
size_t ver_size;
|
||||
int ver = ZFS_IOCVER_NONE;
|
||||
|
||||
ver_size = sizeof (ver);
|
||||
sysctlbyname("vfs.zfs.version.ioctl", &ver, &ver_size, NULL, 0);
|
||||
|
||||
return (ver);
|
||||
}
|
||||
|
||||
static int
|
||||
zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
|
||||
{
|
||||
int ret;
|
||||
void *zc_c;
|
||||
int newrequest, ret;
|
||||
void *zc_c = NULL;
|
||||
unsigned long ncmd;
|
||||
zfs_iocparm_t zp;
|
||||
|
||||
@@ -37,17 +57,32 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
|
||||
ncmd = _IOWR('Z', request, zfs_iocparm_t);
|
||||
zp.zfs_cmd = (uint64_t)zc;
|
||||
zp.zfs_cmd_size = sizeof (zfs_cmd_t);
|
||||
zp.zfs_ioctl_version = ZFS_IOCVER_ZOF;
|
||||
return (ioctl(fd, ncmd, &zp));
|
||||
zp.zfs_ioctl_version = ZFS_IOCVER_OZFS;
|
||||
break;
|
||||
case ZFS_CMD_COMPAT_LEGACY:
|
||||
newrequest = zfs_ioctl_ozfs_to_legacy(request);
|
||||
ncmd = _IOWR('Z', newrequest, zfs_iocparm_t);
|
||||
zc_c = malloc(sizeof (zfs_cmd_legacy_t));
|
||||
zfs_cmd_ozfs_to_legacy(zc, zc_c);
|
||||
zp.zfs_cmd = (uint64_t)zc_c;
|
||||
zp.zfs_cmd_size = sizeof (zfs_cmd_legacy_t);
|
||||
zp.zfs_ioctl_version = ZFS_IOCVER_LEGACY;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
ret = ioctl(fd, ncmd, zc_c);
|
||||
zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag);
|
||||
free(zc_c);
|
||||
|
||||
ret = ioctl(fd, ncmd, &zp);
|
||||
if (ret) {
|
||||
if (zc_c)
|
||||
free(zc_c);
|
||||
return (ret);
|
||||
}
|
||||
if (zc_c) {
|
||||
zfs_cmd_legacy_to_ozfs(zc_c, zc);
|
||||
free(zc_c);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -62,6 +97,21 @@ zfs_ioctl_fd(int fd, unsigned long request, zfs_cmd_t *zc)
|
||||
size_t oldsize;
|
||||
int ret, cflag = ZFS_CMD_COMPAT_NONE;
|
||||
|
||||
if (zfs_ioctl_version == ZFS_IOCVER_UNDEF)
|
||||
zfs_ioctl_version = get_zfs_ioctl_version();
|
||||
|
||||
switch (zfs_ioctl_version) {
|
||||
case ZFS_IOCVER_LEGACY:
|
||||
cflag = ZFS_CMD_COMPAT_LEGACY;
|
||||
break;
|
||||
case ZFS_IOCVER_OZFS:
|
||||
cflag = ZFS_CMD_COMPAT_NONE;
|
||||
break;
|
||||
default:
|
||||
errx(1, "unrecognized zfs ioctl version %d",
|
||||
zfs_ioctl_version);
|
||||
}
|
||||
|
||||
oldsize = zc->zc_nvlist_dst_size;
|
||||
ret = zcmd_ioctl_compat(fd, request, zc, cflag);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user