diff options
author | mm <mm@FreeBSD.org> | 2013-03-01 09:42:58 +0000 |
---|---|---|
committer | mm <mm@FreeBSD.org> | 2013-03-01 09:42:58 +0000 |
commit | e653c470f763b4dff0b51050c92e379b1ff3f646 (patch) | |
tree | 6a0f6613d26f6954346147f7c33ceb0283ec85d9 /cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h | |
parent | 9ecef62d739ff26f081c6ce4d79c74c293ba9fee (diff) | |
download | FreeBSD-src-e653c470f763b4dff0b51050c92e379b1ff3f646.zip FreeBSD-src-e653c470f763b4dff0b51050c92e379b1ff3f646.tar.gz |
Fix the zfs_ioctl compat layer to support zfs_cmd size change introduced
in r247265 (ZFS deadman thread). Both new utilities now support the old
kernel and new kernel properly detects old utilities.
For future backwards compatibility, the vfs.zfs.version.ioctl read-only
sysctl has been introduced. With this sysctl zfs utilities will be able
to detect the ioctl interface version of the currently loaded zfs module.
As a side effect, the zfs utilities between r247265 and this revision don't
support the old kernel module. If you are using HEAD newer or equal than
r247265, install the new kernel module (or whole kernel) first.
MFC after: 10 days
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h')
-rw-r--r-- | cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h index 1c46d32..be07187 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h @@ -24,6 +24,7 @@ * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. * Copyright (c) 2011 by Delphix. All rights reserved. + * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved. */ #ifndef _LIBFS_IMPL_H @@ -216,6 +217,7 @@ extern void libzfs_fru_clear(libzfs_handle_t *, boolean_t); #ifndef sun static int zfs_kernel_version = 0; +static int zfs_ioctl_version = 0; /* * This is FreeBSD version of ioctl, because Solaris' ioctl() updates @@ -225,19 +227,34 @@ static int zfs_kernel_version = 0; static __inline int zcmd_ioctl(int fd, unsigned long cmd, zfs_cmd_t *zc) { - size_t oldsize, zfs_kernel_version_size; + size_t oldsize, zfs_kernel_version_size, zfs_ioctl_version_size; int version, ret, cflag = ZFS_CMD_COMPAT_NONE; - zfs_kernel_version_size = sizeof(zfs_kernel_version); - if (zfs_kernel_version == 0) { - sysctlbyname("vfs.zfs.version.spa", &zfs_kernel_version, - &zfs_kernel_version_size, NULL, 0); + zfs_ioctl_version_size = sizeof(zfs_ioctl_version); + if (zfs_ioctl_version == 0) { + sysctlbyname("vfs.zfs.version.ioctl", &zfs_ioctl_version, + &zfs_ioctl_version_size, NULL, 0); } - if (zfs_kernel_version == SPA_VERSION_15 || - zfs_kernel_version == SPA_VERSION_14 || - zfs_kernel_version == SPA_VERSION_13) - cflag = ZFS_CMD_COMPAT_V15; + /* + * If vfs.zfs.version.ioctl is not defined, assume we have v28 + * compatible binaries and use vfs.zfs.version.spa to test for v15 + */ + if (zfs_ioctl_version < ZFS_IOCVER_DEADMAN) { + cflag = ZFS_CMD_COMPAT_V28; + zfs_kernel_version_size = sizeof(zfs_kernel_version); + + if (zfs_kernel_version == 0) { + sysctlbyname("vfs.zfs.version.spa", + &zfs_kernel_version, + &zfs_kernel_version_size, NULL, 0); + } + + if (zfs_kernel_version == SPA_VERSION_15 || + zfs_kernel_version == SPA_VERSION_14 || + zfs_kernel_version == SPA_VERSION_13) + cflag = ZFS_CMD_COMPAT_V15; + } oldsize = zc->zc_nvlist_dst_size; ret = zcmd_ioctl_compat(fd, cmd, zc, cflag); |