On Mon, May 11, 2009 at 11:21 AM, Doug Rabson <d...@rabson.org> wrote: > 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?
I tried that. The label reads end up failing when ZFS uses the libkern implementation. Somewhere in there, there is a behavioral difference between the two implementations. At some point I'll track down the offending function. -Kip > > 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 <sys/param.h> >> +#include <sys/cmn_err.h> >> +#include <sys/types.h> >> +#include <sys/systm.h> >> + >> +#include <rpc/types.h> >> +#include <rpc/xdr.h> >> + >> +#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-...@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-...@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-...@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-...@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-...@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-...@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 <sys/param.h> >> +#include <sys/cmn_err.h> >> +#include <sys/types.h> >> +#include <sys/systm.h> >> + >> +#include <rpc/types.h> >> +#include <rpc/xdr.h> >> + >> +#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 <sys/param.h> >> +#include <sys/types.h> >> +#include <sys/systm.h> >> + >> +#include <rpc/types.h> >> +#include <rpc/xdr.h> >> + >> +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 > > -- When bad men combine, the good must associate; else they will fall one by one, an unpitied sacrifice in a contemptible struggle. Edmund Burke _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"