svn commit: r220447 - in head/sys/cddl: compat/opensolaris/sys
contrib/opensolaris/common/zfs
Martin Matuska
mm at FreeBSD.org
Fri Apr 8 11:08:27 UTC 2011
Author: mm
Date: Fri Apr 8 11:08:26 2011
New Revision: 220447
URL: http://svn.freebsd.org/changeset/base/220447
Log:
Partially fix ZFS compat code for sparc64.
Some endianess bugs still need to be resolved.
Submitted by: marius (parts of the fix)
MFC after: 1 month
Modified:
head/sys/cddl/compat/opensolaris/sys/sunddi.h
head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
Modified: head/sys/cddl/compat/opensolaris/sys/sunddi.h
==============================================================================
--- head/sys/cddl/compat/opensolaris/sys/sunddi.h Fri Apr 8 09:56:31 2011 (r220446)
+++ head/sys/cddl/compat/opensolaris/sys/sunddi.h Fri Apr 8 11:08:26 2011 (r220447)
@@ -37,8 +37,10 @@
#define strdup(ptr) strdup((ptr), M_SOLARIS)
#define ddi_driver_major(zfs_dip) (0)
-#define ddi_copyin(from, to, size, flag) (bcopy((from), (to), (size)), 0)
-#define ddi_copyout(from, to, size, flag) (bcopy((from), (to), (size)), 0)
+#define ddi_copyin(from, to, size, flag) \
+ (copyin((from), (to), (size)), 0)
+#define ddi_copyout(from, to, size, flag) \
+ (copyout((from), (to), (size)), 0)
int ddi_strtol(const char *str, char **nptr, int base, long *result);
int ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result);
int ddi_strtoull(const char *str, char **nptr, int base,
Modified: head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c Fri Apr 8 09:56:31 2011 (r220446)
+++ head/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c Fri Apr 8 11:08:26 2011 (r220447)
@@ -20,6 +20,8 @@
*/
/*
* Copyright 2010 Martin Matuska <mm at FreeBSD.org>. All rights reserved.
+ * Portions Copyright 2005, 2010, Oracle and/or its affiliates.
+ * All rights reserved.
* Use is subject to license terms.
*/
@@ -151,17 +153,69 @@ zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_
}
static int
-zfs_ioctl_compat_write_nvlist_dst(zfs_cmd_t *zc, nvlist_t *nvl, size_t nvsize)
+zfs_ioctl_compat_get_nvlist(uint64_t nvl, size_t size, int iflag,
+ nvlist_t **nvp)
{
- char *packed = (void *)(uintptr_t)zc->zc_nvlist_dst;
- int err;
+ char *packed;
+ int error;
+ nvlist_t *list = NULL;
+
+ /*
+ * Read in and unpack the user-supplied nvlist.
+ */
+ if (size == 0)
+ return (EINVAL);
+
+#ifdef _KERNEL
+ packed = kmem_alloc(size, KM_SLEEP);
+ if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
+ iflag)) != 0) {
+ kmem_free(packed, size);
+ return (error);
+ }
+#else
+ packed = (void *)(uintptr_t)nvl;
+#endif
- err = nvlist_pack(nvl, &packed, &nvsize,
- NV_ENCODE_NATIVE, 0);
- if (err == 0)
- zc->zc_nvlist_dst_size = nvsize;
+ error = nvlist_unpack(packed, size, &list, 0);
- return (err);
+#ifdef _KERNEL
+ kmem_free(packed, size);
+#endif
+
+ if (error != 0)
+ return (error);
+
+ *nvp = list;
+ return (0);
+}
+
+static int
+zfs_ioctl_compat_put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
+{
+ char *packed = NULL;
+ int error = 0;
+ size_t size;
+
+ VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0);
+
+#ifdef _KERNEL
+ packed = kmem_alloc(size, KM_SLEEP);
+ VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
+ KM_SLEEP) == 0);
+
+ if (ddi_copyout(packed,
+ (void *)(uintptr_t)zc->zc_nvlist_dst, size, zc->zc_iflags) != 0)
+ error = EFAULT;
+ kmem_free(packed, size);
+#else
+ packed = (void *)(uintptr_t)zc->zc_nvlist_dst;
+ VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
+ 0) == 0);
+#endif
+
+ zc->zc_nvlist_dst_size = size;
+ return (error);
}
static void
@@ -205,17 +259,16 @@ zfs_ioctl_compat_fix_stats_nvlist(nvlist
}
}
-static void
+static int
zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int cflag)
{
nvlist_t *nv, *nvp = NULL;
nvpair_t *elem;
- size_t nvsize;
- char *packed;
+ int error;
- if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst,
- zc->zc_nvlist_dst_size, &nv, 0) != 0)
- return;
+ if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
+ zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
+ return (error);
if (cflag == 5) { /* ZFS_IOC_POOL_STATS */
elem = NULL;
@@ -227,21 +280,22 @@ zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc
} else
zfs_ioctl_compat_fix_stats_nvlist(nv);
- VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_NATIVE) == 0);
- zfs_ioctl_compat_write_nvlist_dst(zc, nv, nvsize);
+ error = zfs_ioctl_compat_put_nvlist(zc, nv);
nvlist_free(nv);
+
+ return (error);
}
-static void
+static int
zfs_ioctl_compat_pool_get_props(zfs_cmd_t *zc)
{
nvlist_t *nv, *nva = NULL;
- size_t nvsize;
+ int error;
- if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst,
- zc->zc_nvlist_dst_size, &nv, 0) != 0)
- return;
+ if ((error = zfs_ioctl_compat_get_nvlist(zc->zc_nvlist_dst,
+ zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
+ return (error);
#ifdef _KERNEL
if (nvlist_lookup_nvlist(nv, "allocated", &nva) == 0) {
@@ -265,10 +319,11 @@ zfs_ioctl_compat_pool_get_props(zfs_cmd_
}
#endif
- VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_NATIVE) == 0);
- zfs_ioctl_compat_write_nvlist_dst(zc, nv, nvsize);
+ error = zfs_ioctl_compat_put_nvlist(zc, nv);
nvlist_free(nv);
+
+ return (error);
}
#ifndef _KERNEL
More information about the svn-src-all
mailing list