From owner-svn-src-head@FreeBSD.ORG Fri Apr 8 11:08:27 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1F1591065675; Fri, 8 Apr 2011 11:08:27 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0DA558FC13; Fri, 8 Apr 2011 11:08:27 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p38B8QeI078309; Fri, 8 Apr 2011 11:08:26 GMT (envelope-from mm@svn.freebsd.org) Received: (from mm@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p38B8QS1078306; Fri, 8 Apr 2011 11:08:26 GMT (envelope-from mm@svn.freebsd.org) Message-Id: <201104081108.p38B8QS1078306@svn.freebsd.org> From: Martin Matuska Date: Fri, 8 Apr 2011 11:08:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r220447 - in head/sys/cddl: compat/opensolaris/sys contrib/opensolaris/common/zfs X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Apr 2011 11:08:27 -0000 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 . 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