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 <[email protected]>. 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
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to