summaryrefslogtreecommitdiffstats
path: root/cddl/contrib
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2013-03-18 09:32:29 +0000
committermm <mm@FreeBSD.org>2013-03-18 09:32:29 +0000
commit713c2d790d75eb897ffb4bf09b789cf8940e6ce4 (patch)
tree9353f3579ab3c149b4b017b4be06fbe98b7a5f52 /cddl/contrib
parentda897e350b0958d2948223afca3a685866ac6e9c (diff)
downloadFreeBSD-src-713c2d790d75eb897ffb4bf09b789cf8940e6ce4.zip
FreeBSD-src-713c2d790d75eb897ffb4bf09b789cf8940e6ce4.tar.gz
Move common zfs ioctl compatibility functions (userland) into libzfs_compat.c
Introduce additional constants for zfs ioctl versions
Diffstat (limited to 'cddl/contrib')
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c103
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h66
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c14
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c8
4 files changed, 116 insertions, 75 deletions
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c
new file mode 100644
index 0000000..2a2ae76
--- /dev/null
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c
@@ -0,0 +1,103 @@
+/*
+ * CDDL HEADER SART
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ */
+
+#include "libzfs_compat.h"
+
+int zfs_ioctl_version = ZFS_IOCVER_UNDEF;
+static int zfs_spa_version = -1;
+
+/*
+ * Get zfs_ioctl_version
+ */
+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);
+}
+
+/*
+ * Get the SPA version
+ */
+static int
+get_zfs_spa_version(void)
+{
+ size_t ver_size;
+ int ver = 0;
+
+ ver_size = sizeof(ver);
+ sysctlbyname("vfs.zfs.version.spa", &ver, &ver_size, NULL, 0);
+
+ return (ver);
+}
+
+/*
+ * This is FreeBSD version of ioctl, because Solaris' ioctl() updates
+ * zc_nvlist_dst_size even if an error is returned, on FreeBSD if an
+ * error is returned zc_nvlist_dst_size won't be updated.
+ */
+int
+zcmd_ioctl(int fd, int 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();
+
+ if (zfs_ioctl_version == ZFS_IOCVER_DEADMAN)
+ cflag = ZFS_CMD_COMPAT_DEADMAN;
+
+ /*
+ * 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;
+
+ if (zfs_spa_version < 0)
+ zfs_spa_version = get_zfs_spa_version();
+
+ if (zfs_spa_version == SPA_VERSION_15 ||
+ zfs_spa_version == SPA_VERSION_14 ||
+ zfs_spa_version == SPA_VERSION_13)
+ cflag = ZFS_CMD_COMPAT_V15;
+ }
+
+ oldsize = zc->zc_nvlist_dst_size;
+ ret = zcmd_ioctl_compat(fd, request, zc, cflag);
+
+ if (ret == 0 && oldsize < zc->zc_nvlist_dst_size) {
+ ret = -1;
+ errno = ENOMEM;
+ }
+
+ return (ret);
+}
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h
index 400c814..3761668 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h
@@ -32,71 +32,9 @@
extern "C" {
#endif
-static int zfs_ioctl_version = -1;
-static int zfs_kernel_version = 0;
+int get_zfs_ioctl_version(void);
+int zcmd_ioctl(int fd, int request, zfs_cmd_t *zc);
-/*
- * Get zfs_ioctl_version
- */
-static __inline int
-get_zfs_ioctl_version(void)
-{
- size_t ver_size;
- int ver = 0;
-
- ver_size = sizeof(ver);
- sysctlbyname("vfs.zfs.version.ioctl", &ver, &ver_size, NULL, 0);
-
- return (ver);
-}
-
-/*
- * This is FreeBSD version of ioctl, because Solaris' ioctl() updates
- * zc_nvlist_dst_size even if an error is returned, on FreeBSD if an
- * error is returned zc_nvlist_dst_size won't be updated.
- */
-static __inline int
-zcmd_ioctl(int fd, int request, zfs_cmd_t *zc)
-{
- size_t oldsize, zfs_kernel_version_size;
- int version, ret, cflag = ZFS_CMD_COMPAT_NONE;
-
- if (zfs_ioctl_version == -1)
- zfs_ioctl_version = get_zfs_ioctl_version();
-
- if (zfs_ioctl_version == ZFS_IOCVER_DEADMAN)
- cflag = ZFS_CMD_COMPAT_DEADMAN;
-
- /*
- * 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, request, zc, cflag);
-
- if (ret == 0 && oldsize < zc->zc_nvlist_dst_size) {
- ret = -1;
- errno = ENOMEM;
- }
-
- return (ret);
-}
#define ioctl(fd, ioc, zc) zcmd_ioctl((fd), (ioc), (zc))
#ifdef __cplusplus
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
index 3319d20..83d0296 100644
--- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
@@ -88,7 +88,7 @@
#include "libzfs_compat.h"
#ifdef __FreeBSD__
-int lzc_ioctl_version = -1;
+extern int zfs_ioctl_version;
#endif
static int g_fd;
@@ -140,10 +140,10 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
#ifdef __FreeBSD__
- if (lzc_ioctl_version == -1)
- lzc_ioctl_version = get_zfs_ioctl_version();
+ if (zfs_ioctl_version == ZFS_IOCVER_UNDEF)
+ zfs_ioctl_version = get_zfs_ioctl_version();
- if (lzc_ioctl_version < ZFS_IOCVER_LZC) {
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC) {
oldsource = source;
error = lzc_compat_pre(&zc, &ioc, &source);
if (error)
@@ -190,7 +190,7 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
}
#ifdef __FreeBSD__
- if (lzc_ioctl_version < ZFS_IOCVER_LZC)
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC)
lzc_compat_post(&zc, ioc);
#endif
if (zc.zc_nvlist_dst_filled) {
@@ -200,12 +200,12 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
*resultp = NULL;
}
#ifdef __FreeBSD__
- if (lzc_ioctl_version < ZFS_IOCVER_LZC)
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC)
lzc_compat_outnvl(&zc, ioc, resultp);
#endif
out:
#ifdef __FreeBSD__
- if (lzc_ioctl_version < ZFS_IOCVER_LZC) {
+ if (zfs_ioctl_version < ZFS_IOCVER_LZC) {
if (source != oldsource)
nvlist_free(source);
source = oldsource;
diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c
index 0ab12b6..c19be1f 100644
--- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c
+++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core_compat.c
@@ -27,7 +27,7 @@
#include <zfs_ioctl_compat.h>
#include "libzfs_core_compat.h"
-extern int lzc_ioctl_version;
+extern int zfs_ioctl_version;
int
lzc_compat_pre(zfs_cmd_t *zc, zfs_ioc_t *ioc, nvlist_t **source)
@@ -40,7 +40,7 @@ lzc_compat_pre(zfs_cmd_t *zc, zfs_ioc_t *ioc, nvlist_t **source)
int error = 0;
int pos;
- if (lzc_ioctl_version >= ZFS_IOCVER_LZC)
+ if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
return (0);
vecnum = *ioc;
@@ -99,7 +99,7 @@ lzc_compat_pre(zfs_cmd_t *zc, zfs_ioc_t *ioc, nvlist_t **source)
void
lzc_compat_post(zfs_cmd_t *zc, const zfs_ioc_t ioc)
{
- if (lzc_ioctl_version >= ZFS_IOCVER_LZC)
+ if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
return;
switch (ioc) {
@@ -118,7 +118,7 @@ lzc_compat_outnvl(zfs_cmd_t *zc, const zfs_ioc_t ioc, nvlist_t **outnvl)
{
nvlist_t *nvl;
- if (lzc_ioctl_version >= ZFS_IOCVER_LZC)
+ if (zfs_ioctl_version >= ZFS_IOCVER_LZC)
return (0);
switch (ioc) {
OpenPOWER on IntegriCloud