From owner-svn-src-all@FreeBSD.ORG Mon May 11 18:40:26 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 091391065675; Mon, 11 May 2009 18:40:26 +0000 (UTC) (envelope-from dfr@rabson.org) Received: from itchy.rabson.org (router.rabson.org [80.177.232.241]) by mx1.freebsd.org (Postfix) with ESMTP id ADA298FC17; Mon, 11 May 2009 18:40:24 +0000 (UTC) (envelope-from dfr@rabson.org) Received: from [IPv6:2001:470:909f:1:225:ff:feed:9426] (unknown [IPv6:2001:470:909f:1:225:ff:feed:9426]) by itchy.rabson.org (Postfix) with ESMTP id ED8785CF3; Mon, 11 May 2009 19:22:05 +0100 (BST) Message-Id: <0E48393C-F519-42A1-AD3C-3EC31EE2AE06@rabson.org> From: Doug Rabson To: Kip Macy In-Reply-To: <200905110418.n4B4IxPC077484@svn.freebsd.org> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v930.4) Date: Mon, 11 May 2009 19:21:29 +0100 References: <200905110418.n4B4IxPC077484@svn.freebsd.org> X-Mailer: Apple Mail (2.930.4) Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r191984 - in head/sys: cddl/contrib/opensolaris/uts/common/rpc modules/zfs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 May 2009 18:40:26 -0000 The XDR support code that is in the main kernel should have a very similar API to the opensolaris bits, possibly identical. Perhaps the opensolaris compat could use the main kernel's XDR implementation? On 11 May 2009, at 05:18, Kip Macy wrote: > Author: kmacy > Date: Mon May 11 04:18:58 2009 > New Revision: 191984 > URL: http://svn.freebsd.org/changeset/base/191984 > > Log: > rename xdr support files to avoid conflicts when linking in to the > kernel > > Added: > head/sys/cddl/contrib/opensolaris/uts/common/rpc/ > opensolaris_xdr.c (props changed) > - copied unchanged from r191983, head/sys/cddl/contrib/ > opensolaris/uts/common/rpc/xdr.c > head/sys/cddl/contrib/opensolaris/uts/common/rpc/ > opensolaris_xdr_array.c (props changed) > - copied unchanged from r191983, head/sys/cddl/contrib/ > opensolaris/uts/common/rpc/xdr_array.c > head/sys/cddl/contrib/opensolaris/uts/common/rpc/ > opensolaris_xdr_mem.c (props changed) > - copied unchanged from r191983, head/sys/cddl/contrib/ > opensolaris/uts/common/rpc/xdr_mem.c > Deleted: > head/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.c > head/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr_array.c > head/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr_mem.c > Modified: > head/sys/modules/zfs/Makefile > > Copied: head/sys/cddl/contrib/opensolaris/uts/common/rpc/ > opensolaris_xdr.c (from r191983, head/sys/cddl/contrib/opensolaris/ > uts/common/rpc/xdr.c) > = > = > = > = > = > = > = > = > ====================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/sys/cddl/contrib/opensolaris/uts/common/rpc/ > opensolaris_xdr.c Mon May 11 04:18:58 2009 (r191984, copy of > r191983, head/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.c) > @@ -0,0 +1,621 @@ > +/* > + * CDDL HEADER START > + * > + * 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 2008 Sun Microsystems, Inc. All rights reserved. > + * Use is subject to license terms. > + */ > + > +/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ > +/* All Rights Reserved */ > + > +/* > + * Portions of this source code were derived from Berkeley 4.3 BSD > + * under license from the Regents of the University of California. > + */ > + > +/* > + * xdr.c, generic XDR routines implementation. > + * These are the "generic" xdr routines used to serialize and de- > serialize > + * most common data items. See xdr.h for more info on the > interface to > + * xdr. > + */ > + > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#pragma weak xdr_int32_t = xdr_int > +#pragma weak xdr_uint32_t = xdr_u_int > +#pragma weak xdr_int64_t = xdr_longlong_t > +#pragma weak xdr_uint64_t = xdr_u_longlong_t > + > +#if defined(sun) > +#if !defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) > +#error "Exactly one of _BIG_ENDIAN or _LITTLE_ENDIAN must be defined" > +#elif defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) > +#error "Only one of _BIG_ENDIAN or _LITTLE_ENDIAN may be defined" > +#endif > +#endif > + > +/* > + * constants specific to the xdr "protocol" > + */ > +#define XDR_FALSE ((int32_t)0) > +#define XDR_TRUE ((int32_t)1) > +#define LASTUNSIGNED ((uint_t)0-1) > + > +/* > + * for unit alignment > + */ > +static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; > + > +/* > + * Free a data structure using XDR > + * Not a filter, but a convenient utility nonetheless > + */ > +void > +xdr_free(xdrproc_t proc, char *objp) > +{ > + XDR x; > + > + x.x_op = XDR_FREE; > + (*proc)(&x, objp); > +} > + > +/* > + * XDR nothing > + */ > +bool_t > +xdr_void(void) > +{ > + return (TRUE); > +} > + > +/* > + * XDR integers > + * > + * PSARC 2003/523 Contract Private Interface > + * xdr_int > + * Changes must be reviewed by Solaris File Sharing > + * Changes must be communicated to contract-2003-523@sun.com > + */ > +bool_t > +xdr_int(XDR *xdrs, int *ip) > +{ > + if (xdrs->x_op == XDR_ENCODE) > + return (XDR_PUTINT32(xdrs, ip)); > + > + if (xdrs->x_op == XDR_DECODE) > + return (XDR_GETINT32(xdrs, ip)); > + > + if (xdrs->x_op == XDR_FREE) > + return (TRUE); > + > + return (FALSE); > +} > + > +/* > + * XDR unsigned integers > + * > + * PSARC 2003/523 Contract Private Interface > + * xdr_u_int > + * Changes must be reviewed by Solaris File Sharing > + * Changes must be communicated to contract-2003-523@sun.com > + */ > +bool_t > +xdr_u_int(XDR *xdrs, uint_t *up) > +{ > + if (xdrs->x_op == XDR_ENCODE) > + return (XDR_PUTINT32(xdrs, (int32_t *)up)); > + > + if (xdrs->x_op == XDR_DECODE) > + return (XDR_GETINT32(xdrs, (int32_t *)up)); > + > + if (xdrs->x_op == XDR_FREE) > + return (TRUE); > + > + return (FALSE); > +} > + > + > +#if defined(_ILP32) > +/* > + * xdr_long and xdr_u_long for binary compatability on ILP32 kernels. > + * > + * No prototypes since new code should not be using these interfaces. > + */ > +bool_t > +xdr_long(XDR *xdrs, long *ip) > +{ > + return (xdr_int(xdrs, (int *)ip)); > +} > + > +bool_t > +xdr_u_long(XDR *xdrs, unsigned long *up) > +{ > + return (xdr_u_int(xdrs, (uint_t *)up)); > +} > +#endif /* _ILP32 */ > + > + > +/* > + * XDR long long integers > + */ > +bool_t > +xdr_longlong_t(XDR *xdrs, longlong_t *hp) > +{ > + if (xdrs->x_op == XDR_ENCODE) { > +#if BYTE_ORDER == _LITTLE_ENDIAN > + if (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp + > + BYTES_PER_XDR_UNIT)) == TRUE) { > + return (XDR_PUTINT32(xdrs, (int32_t *)hp)); > + } > +#else > + if (XDR_PUTINT32(xdrs, (int32_t *)hp) == TRUE) { > + return (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp + > + BYTES_PER_XDR_UNIT))); > + } > +#endif > + return (FALSE); > + > + } > + if (xdrs->x_op == XDR_DECODE) { > +#if BYTE_ORDER == _LITTLE_ENDIAN > + if (XDR_GETINT32(xdrs, (int32_t *)((char *)hp + > + BYTES_PER_XDR_UNIT)) == TRUE) { > + return (XDR_GETINT32(xdrs, (int32_t *)hp)); > + } > +#else > + if (XDR_GETINT32(xdrs, (int32_t *)hp) == TRUE) { > + return (XDR_GETINT32(xdrs, (int32_t *)((char *)hp + > + BYTES_PER_XDR_UNIT))); > + } > +#endif > + return (FALSE); > + } > + return (TRUE); > +} > + > +/* > + * XDR unsigned long long integers > + */ > +bool_t > +xdr_u_longlong_t(XDR *xdrs, u_longlong_t *hp) > +{ > + > + if (xdrs->x_op == XDR_ENCODE) { > +#if BYTE_ORDER == _LITTLE_ENDIAN > + if (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp + > + BYTES_PER_XDR_UNIT)) == TRUE) { > + return (XDR_PUTINT32(xdrs, (int32_t *)hp)); > + } > +#else > + if (XDR_PUTINT32(xdrs, (int32_t *)hp) == TRUE) { > + return (XDR_PUTINT32(xdrs, (int32_t *)((char *)hp + > + BYTES_PER_XDR_UNIT))); > + } > +#endif > + return (FALSE); > + > + } > + if (xdrs->x_op == XDR_DECODE) { > +#if BYTE_ORDER == _LITTLE_ENDIAN > + if (XDR_GETINT32(xdrs, (int32_t *)((char *)hp + > + BYTES_PER_XDR_UNIT)) == TRUE) { > + return (XDR_GETINT32(xdrs, (int32_t *)hp)); > + } > +#else > + if (XDR_GETINT32(xdrs, (int32_t *)hp) == TRUE) { > + return (XDR_GETINT32(xdrs, (int32_t *)((char *)hp + > + BYTES_PER_XDR_UNIT))); > + } > +#endif > + return (FALSE); > + } > + return (TRUE); > +} > + > +/* > + * XDR short integers > + */ > +bool_t > +xdr_short(XDR *xdrs, short *sp) > +{ > + int32_t l; > + > + switch (xdrs->x_op) { > + > + case XDR_ENCODE: > + l = (int32_t)*sp; > + return (XDR_PUTINT32(xdrs, &l)); > + > + case XDR_DECODE: > + if (!XDR_GETINT32(xdrs, &l)) > + return (FALSE); > + *sp = (short)l; > + return (TRUE); > + > + case XDR_FREE: > + return (TRUE); > + } > + return (FALSE); > +} > + > +/* > + * XDR unsigned short integers > + */ > +bool_t > +xdr_u_short(XDR *xdrs, ushort_t *usp) > +{ > + uint32_t l; > + > + switch (xdrs->x_op) { > + > + case XDR_ENCODE: > + l = (uint32_t)*usp; > + return (XDR_PUTINT32(xdrs, (int32_t *)&l)); > + > + case XDR_DECODE: > + if (!XDR_GETINT32(xdrs, (int32_t *)&l)) { > + return (FALSE); > + } > + *usp = (ushort_t)l; > + return (TRUE); > + > + case XDR_FREE: > + return (TRUE); > + } > + return (FALSE); > +} > + > + > +/* > + * XDR a char > + */ > +bool_t > +xdr_char(XDR *xdrs, char *cp) > +{ > + int i; > + > + i = (*cp); > + if (!xdr_int(xdrs, &i)) { > + return (FALSE); > + } > + *cp = (char)i; > + return (TRUE); > +} > + > +/* > + * XDR booleans > + * > + * PSARC 2003/523 Contract Private Interface > + * xdr_bool > + * Changes must be reviewed by Solaris File Sharing > + * Changes must be communicated to contract-2003-523@sun.com > + */ > +bool_t > +xdr_bool(XDR *xdrs, bool_t *bp) > +{ > + int32_t i32b; > + > + switch (xdrs->x_op) { > + > + case XDR_ENCODE: > + i32b = *bp ? XDR_TRUE : XDR_FALSE; > + return (XDR_PUTINT32(xdrs, &i32b)); > + > + case XDR_DECODE: > + if (!XDR_GETINT32(xdrs, &i32b)) { > + return (FALSE); > + } > + *bp = (i32b == XDR_FALSE) ? FALSE : TRUE; > + return (TRUE); > + > + case XDR_FREE: > + return (TRUE); > + } > + return (FALSE); > +} > + > +/* > + * XDR enumerations > + * > + * PSARC 2003/523 Contract Private Interface > + * xdr_enum > + * Changes must be reviewed by Solaris File Sharing > + * Changes must be communicated to contract-2003-523@sun.com > + */ > +#ifndef lint > +enum sizecheck { SIZEVAL } sizecheckvar; /* used to find the size > of */ > + /* an enum */ > +#endif > +bool_t > +xdr_enum(XDR *xdrs, enum_t *ep) > +{ > +#ifndef lint > + /* > + * enums are treated as ints > + */ > + if (sizeof (sizecheckvar) == sizeof (int32_t)) { > + return (xdr_int(xdrs, (int32_t *)ep)); > + } else if (sizeof (sizecheckvar) == sizeof (short)) { > + return (xdr_short(xdrs, (short *)ep)); > + } else { > + return (FALSE); > + } > +#else > + (void) (xdr_short(xdrs, (short *)ep)); > + return (xdr_int(xdrs, (int32_t *)ep)); > +#endif > +} > + > +/* > + * XDR opaque data > + * Allows the specification of a fixed size sequence of opaque bytes. > + * cp points to the opaque object and cnt gives the byte length. > + * > + * PSARC 2003/523 Contract Private Interface > + * xdr_opaque > + * Changes must be reviewed by Solaris File Sharing > + * Changes must be communicated to contract-2003-523@sun.com > + */ > +bool_t > +xdr_opaque(XDR *xdrs, caddr_t cp, const uint_t cnt) > +{ > + uint_t rndup; > + static char crud[BYTES_PER_XDR_UNIT]; > + > + /* > + * if no data we are done > + */ > + if (cnt == 0) > + return (TRUE); > + > + /* > + * round byte count to full xdr units > + */ > + rndup = cnt % BYTES_PER_XDR_UNIT; > + if (rndup != 0) > + rndup = BYTES_PER_XDR_UNIT - rndup; > + > + if (xdrs->x_op == XDR_DECODE) { > + if (!XDR_GETBYTES(xdrs, cp, cnt)) { > + return (FALSE); > + } > + if (rndup == 0) > + return (TRUE); > + return (XDR_GETBYTES(xdrs, (caddr_t)crud, rndup)); > + } > + > + if (xdrs->x_op == XDR_ENCODE) { > + if (!XDR_PUTBYTES(xdrs, cp, cnt)) { > + return (FALSE); > + } > + if (rndup == 0) > + return (TRUE); > + return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); > + } > + > + if (xdrs->x_op == XDR_FREE) > + return (TRUE); > + > + return (FALSE); > +} > + > +/* > + * XDR counted bytes > + * *cpp is a pointer to the bytes, *sizep is the count. > + * If *cpp is NULL maxsize bytes are allocated > + * > + * PSARC 2003/523 Contract Private Interface > + * xdr_bytes > + * Changes must be reviewed by Solaris File Sharing > + * Changes must be communicated to contract-2003-523@sun.com > + */ > +bool_t > +xdr_bytes(XDR *xdrs, char **cpp, uint_t *sizep, const uint_t maxsize) > +{ > + char *sp = *cpp; /* sp is the actual string pointer */ > + uint_t nodesize; > + > + /* > + * first deal with the length since xdr bytes are counted > + */ > + if (!xdr_u_int(xdrs, sizep)) { > + return (FALSE); > + } > + nodesize = *sizep; > + if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { > + return (FALSE); > + } > + > + /* > + * now deal with the actual bytes > + */ > + switch (xdrs->x_op) { > + case XDR_DECODE: > + if (nodesize == 0) > + return (TRUE); > + if (sp == NULL) > + *cpp = sp = (char *)mem_alloc(nodesize); > + /* FALLTHROUGH */ > + > + case XDR_ENCODE: > + return (xdr_opaque(xdrs, sp, nodesize)); > + > + case XDR_FREE: > + if (sp != NULL) { > + mem_free(sp, nodesize); > + *cpp = NULL; > + } > + return (TRUE); > + } > + return (FALSE); > +} > + > +/* > + * Implemented here due to commonality of the object. > + */ > +bool_t > +xdr_netobj(XDR *xdrs, struct netobj *np) > +{ > + return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); > +} > + > +/* > + * XDR a descriminated union > + * Support routine for discriminated unions. > + * You create an array of xdrdiscrim structures, terminated with > + * an entry with a null procedure pointer. The routine gets > + * the discriminant value and then searches the array of xdrdiscrims > + * looking for that value. It calls the procedure given in the > xdrdiscrim > + * to handle the discriminant. If there is no specific routine a > default > + * routine may be called. > + * If there is no specific or default routine an error is returned. > + */ > +bool_t > +xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, > + const struct xdr_discrim *choices, const xdrproc_t dfault) > +{ > + enum_t dscm; > + > + /* > + * we deal with the discriminator; it's an enum > + */ > + if (!xdr_enum(xdrs, dscmp)) { > + return (FALSE); > + } > + dscm = *dscmp; > + > + /* > + * search choices for a value that matches the discriminator. > + * if we find one, execute the xdr routine for that value. > + */ > + for (; choices->proc != NULL_xdrproc_t; choices++) { > + if (choices->value == dscm) > + return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED)); > + } > + > + /* > + * no match - execute the default xdr routine if there is one > + */ > + return ((dfault == NULL_xdrproc_t) ? FALSE : > + (*dfault)(xdrs, unp, LASTUNSIGNED)); > +} > + > + > +/* > + * Non-portable xdr primitives. > + * Care should be taken when moving these routines to new > architectures. > + */ > + > + > +/* > + * XDR null terminated ASCII strings > + * xdr_string deals with "C strings" - arrays of bytes that are > + * terminated by a NULL character. The parameter cpp references a > + * pointer to storage; If the pointer is null, then the necessary > + * storage is allocated. The last parameter is the max allowed > length > + * of the string as specified by a protocol. > + */ > +bool_t > +xdr_string(XDR *xdrs, char **cpp, const uint_t maxsize) > +{ > + char *sp = *cpp; /* sp is the actual string pointer */ > + uint_t size; > + uint_t nodesize; > + > + /* > + * first deal with the length since xdr strings are counted-strings > + */ > + switch (xdrs->x_op) { > + case XDR_FREE: > + if (sp == NULL) > + return (TRUE); /* already free */ > + /* FALLTHROUGH */ > + case XDR_ENCODE: > + size = (sp != NULL) ? (uint_t)strlen(sp) : 0; > + break; > + case XDR_DECODE: > + break; > + } > + if (!xdr_u_int(xdrs, &size)) { > + return (FALSE); > + } > + if (size > maxsize) { > + return (FALSE); > + } > + nodesize = size + 1; > + > + /* > + * now deal with the actual bytes > + */ > + switch (xdrs->x_op) { > + case XDR_DECODE: > + if (nodesize == 0) > + return (TRUE); > + if (sp == NULL) > + sp = (char *)mem_alloc(nodesize); > + sp[size] = 0; > + if (!xdr_opaque(xdrs, sp, size)) { > + /* > + * free up memory if allocated here > + */ > + if (*cpp == NULL) { > + mem_free(sp, nodesize); > + } > + return (FALSE); > + } > + if (strlen(sp) != size) { > + if (*cpp == NULL) { > + mem_free(sp, nodesize); > + } > + return (FALSE); > + } > + *cpp = sp; > + return (TRUE); > + > + case XDR_ENCODE: > + return (xdr_opaque(xdrs, sp, size)); > + > + case XDR_FREE: > + mem_free(sp, nodesize); > + *cpp = NULL; > + return (TRUE); > + } > + return (FALSE); > +} > + > +/* > + * Wrapper for xdr_string that can be called directly from > + * routines like clnt_call > + */ > +bool_t > +xdr_wrapstring(XDR *xdrs, char **cpp) > +{ > + if (xdr_string(xdrs, cpp, LASTUNSIGNED)) > + return (TRUE); > + return (FALSE); > +} > > Copied: head/sys/cddl/contrib/opensolaris/uts/common/rpc/ > opensolaris_xdr_array.c (from r191983, head/sys/cddl/contrib/ > opensolaris/uts/common/rpc/xdr_array.c) > = > = > = > = > = > = > = > = > ====================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/sys/cddl/contrib/opensolaris/uts/common/rpc/ > opensolaris_xdr_array.c Mon May 11 04:18:58 2009 (r191984, copy of > r191983, head/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr_array.c) > @@ -0,0 +1,114 @@ > +/* > + * CDDL HEADER START > + * > + * 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 2008 Sun Microsystems, Inc. All rights reserved. > + * Use is subject to license terms. > + */ > + > +/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ > +/* All Rights Reserved */ > + > +/* > + * Portions of this source code were derived from Berkeley 4.3 BSD > + * under license from the Regents of the University of California. > + */ > + > +/* > + * xdr_array.c, Generic XDR routines impelmentation. > + * These are the "non-trivial" xdr primitives used to serialize and > de-serialize > + * arrays. See xdr.h for more info on the interface to xdr. > + */ > + > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#define LASTUNSIGNED ((uint_t)0-1) > + > +/* > + * XDR an array of arbitrary elements > + * *addrp is a pointer to the array, *sizep is the number of > elements. > + * If addrp is NULL (*sizep * elsize) bytes are allocated. > + * elsize is the size (in bytes) of each element, and elproc is the > + * xdr procedure to call to handle each element of the array. > + */ > +bool_t > +xdr_array(XDR *xdrs, caddr_t *addrp, uint_t *sizep, const uint_t > maxsize, > + const uint_t elsize, const xdrproc_t elproc) > +{ > + uint_t i; > + caddr_t target = *addrp; > + uint_t c; /* the actual element count */ > + bool_t stat = TRUE; > + uint_t nodesize; > + > + /* like strings, arrays are really counted arrays */ > + if (!xdr_u_int(xdrs, sizep)) { > + return (FALSE); > + } > + c = *sizep; > + if ((c > maxsize || LASTUNSIGNED / elsize < c) && > + xdrs->x_op != XDR_FREE) { > + return (FALSE); > + } > + nodesize = c * elsize; > + > + /* > + * if we are deserializing, we may need to allocate an array. > + * We also save time by checking for a null array if we are freeing. > + */ > + if (target == NULL) > + switch (xdrs->x_op) { > + case XDR_DECODE: > + if (c == 0) > + return (TRUE); > + *addrp = target = (char *)mem_alloc(nodesize); > + bzero(target, nodesize); > + break; > + > + case XDR_FREE: > + return (TRUE); > + > + case XDR_ENCODE: > + break; > + } > + > + /* > + * now we xdr each element of array > + */ > + for (i = 0; (i < c) && stat; i++) { > + stat = (*elproc)(xdrs, target, LASTUNSIGNED); > + target += elsize; > + } > + > + /* > + * the array may need freeing > + */ > + if (xdrs->x_op == XDR_FREE) { > + mem_free(*addrp, nodesize); > + *addrp = NULL; > + } > + return (stat); > +} > > Copied: head/sys/cddl/contrib/opensolaris/uts/common/rpc/ > opensolaris_xdr_mem.c (from r191983, head/sys/cddl/contrib/ > opensolaris/uts/common/rpc/xdr_mem.c) > = > = > = > = > = > = > = > = > ====================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/sys/cddl/contrib/opensolaris/uts/common/rpc/ > opensolaris_xdr_mem.c Mon May 11 04:18:58 2009 (r191984, copy of > r191983, head/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr_mem.c) > @@ -0,0 +1,209 @@ > +/* > + * CDDL HEADER START > + * > + * The contents of this file are subject to the terms of the > + * Common Development and Distribution License, Version 1.0 only > + * (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 2005 Sun Microsystems, Inc. All rights reserved. > + * Use is subject to license terms. > + */ > + > +/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ > +/* All Rights Reserved */ > + > +/* > + * Portions of this source code were derived from Berkeley 4.3 BSD > + * under license from the Regents of the University of California. > + */ > + > +#pragma ident "%Z%%M% %I% %E% SMI" > + > +/* > + * xdr_mem.c, XDR implementation using memory buffers. > + * > + * If you have some data to be interpreted as external data > representation > + * or to be converted to external data representation in a memory > buffer, > + * then this is the package for you. > + */ > + > +#include > +#include > +#include > + > +#include > +#include > + > +static struct xdr_ops *xdrmem_ops(void); > + > +/* > + * The procedure xdrmem_create initializes a stream descriptor for a > + * memory buffer. > + */ > +void > +xdrmem_create(XDR *xdrs, caddr_t addr, uint_t size, enum xdr_op op) > +{ > + xdrs->x_op = op; > + xdrs->x_ops = xdrmem_ops(); > + xdrs->x_private = xdrs->x_base = addr; > + xdrs->x_handy = size; > + xdrs->x_public = NULL; > +} > + > +/* ARGSUSED */ > +static void > +xdrmem_destroy(XDR *xdrs) > +{ > +} > + > +static bool_t > +xdrmem_getint32(XDR *xdrs, int32_t *int32p) > +{ > + if ((xdrs->x_handy -= (int)sizeof (int32_t)) < 0) > + return (FALSE); > + /* LINTED pointer alignment */ > + *int32p = (int32_t)ntohl((uint32_t)(*((int32_t *)(xdrs- > >x_private)))); > + xdrs->x_private += sizeof (int32_t); > + return (TRUE); > +} > + > +static bool_t > +xdrmem_putint32(XDR *xdrs, int32_t *int32p) > +{ > + if ((xdrs->x_handy -= (int)sizeof (int32_t)) < 0) > + return (FALSE); > + /* LINTED pointer alignment */ > + *(int32_t *)xdrs->x_private = (int32_t)htonl((uint32_t)(*int32p)); > + xdrs->x_private += sizeof (int32_t); > + return (TRUE); > +} > + > +static bool_t > +xdrmem_getbytes(XDR *xdrs, caddr_t addr, int len) > +{ > + if ((xdrs->x_handy -= len) < 0) > + return (FALSE); > + bcopy(xdrs->x_private, addr, len); > + xdrs->x_private += len; > + return (TRUE); > +} > + > +static bool_t > +xdrmem_putbytes(XDR *xdrs, caddr_t addr, int len) > +{ > + if ((xdrs->x_handy -= len) < 0) > + return (FALSE); > + bcopy(addr, xdrs->x_private, len); > + xdrs->x_private += len; > + return (TRUE); > +} > + > +static uint_t > +xdrmem_getpos(XDR *xdrs) > +{ > + return ((uint_t)((uintptr_t)xdrs->x_private - (uintptr_t)xdrs- > >x_base)); > +} > + > +static bool_t > +xdrmem_setpos(XDR *xdrs, uint_t pos) > +{ > + caddr_t newaddr = xdrs->x_base + pos; > + caddr_t lastaddr = xdrs->x_private + xdrs->x_handy; > + ptrdiff_t diff; > + > + if (newaddr > lastaddr) > + return (FALSE); > + xdrs->x_private = newaddr; > + diff = lastaddr - newaddr; > + xdrs->x_handy = (int)diff; > + return (TRUE); > +} > + > +static rpc_inline_t * > +xdrmem_inline(XDR *xdrs, int len) > +{ > + rpc_inline_t *buf = NULL; > + > + if (xdrs->x_handy >= len) { > + xdrs->x_handy -= len; > + /* LINTED pointer alignment */ > + buf = (rpc_inline_t *)xdrs->x_private; > + xdrs->x_private += len; > + } > + return (buf); > +} > + > +static bool_t > +xdrmem_control(XDR *xdrs, int request, void *info) > +{ > + xdr_bytesrec *xptr; > + int32_t *int32p; > + int len; > + > + switch (request) { > + > + case XDR_GET_BYTES_AVAIL: > + xptr = (xdr_bytesrec *)info; > + xptr->xc_is_last_record = TRUE; > + xptr->xc_num_avail = xdrs->x_handy; > + return (TRUE); > + > + case XDR_PEEK: > + /* > + * Return the next 4 byte unit in the XDR stream. > + */ > + if (xdrs->x_handy < sizeof (int32_t)) > + return (FALSE); > + int32p = (int32_t *)info; > + *int32p = (int32_t)ntohl((uint32_t) > + (*((int32_t *)(xdrs->x_private)))); > + return (TRUE); > + > + case XDR_SKIPBYTES: > + /* > + * Skip the next N bytes in the XDR stream. > + */ > + int32p = (int32_t *)info; > + len = RNDUP((int)(*int32p)); > + if ((xdrs->x_handy -= len) < 0) > + return (FALSE); > + xdrs->x_private += len; > + return (TRUE); > + > + } > + return (FALSE); > +} > + > +static struct xdr_ops * > +xdrmem_ops(void) > +{ > + static struct xdr_ops ops; > + > + if (ops.x_getint32 == NULL) { > + ops.x_getbytes = xdrmem_getbytes; > + ops.x_putbytes = xdrmem_putbytes; > + ops.x_getpostn = xdrmem_getpos; > + ops.x_setpostn = xdrmem_setpos; > + ops.x_inline = xdrmem_inline; > + ops.x_destroy = xdrmem_destroy; > + ops.x_control = xdrmem_control; > + ops.x_getint32 = xdrmem_getint32; > + ops.x_putint32 = xdrmem_putint32; > + } > + return (&ops); > +} > > Modified: head/sys/modules/zfs/Makefile > = > = > = > = > = > = > = > = > ====================================================================== > --- head/sys/modules/zfs/Makefile Mon May 11 02:39:49 2009 (r191983) > +++ head/sys/modules/zfs/Makefile Mon May 11 04:18:58 2009 (r191984) > @@ -44,9 +44,9 @@ SRCS+= nvpair_alloc_system.c > SRCS+= taskq.c > > .PATH: ${SUNW}/uts/common/rpc > -SRCS+= xdr.c > -SRCS+= xdr_array.c > -SRCS+= xdr_mem.c > +SRCS+= opensolaris_xdr.c > +SRCS+= opensolaris_xdr_array.c > +SRCS+= opensolaris_xdr_mem.c > > .PATH: ${SUNW}/uts/common/zmod > SRCS+= adler32.c