diff --git a/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.h b/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.h index 75fd1dd4c7a0..6cb0c6db3923 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.h +++ b/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.h @@ -121,6 +121,7 @@ typedef struct XDR { * Changes must be reviewed by Solaris File Sharing * Changes must be communicated to contract-2003-523@sun.com */ +#ifndef __FreeBSD__ struct xdr_ops { #ifdef __STDC__ #if !defined(_KERNEL) @@ -168,6 +169,28 @@ struct xdr_ops { #endif }; +#else /* FreeBSD */ +struct xdr_ops { + /* get a long from underlying stream */ + bool_t (*x_getint32)(struct XDR *, int32_t *); + /* put a long to " */ + bool_t (*x_putint32)(struct XDR *, const int32_t *); + /* get some bytes from " */ + bool_t (*x_getbytes)(struct XDR *, char *, u_int); + /* put some bytes to " */ + bool_t (*x_putbytes)(struct XDR *, const char *, u_int); + /* returns bytes off from beginning */ + u_int (*x_getpostn)(struct XDR *); + /* lets you reposition the stream */ + bool_t (*x_setpostn)(struct XDR *, u_int); + /* buf quick ptr to buffered data */ + int32_t *(*x_inline)(struct XDR *, u_int); + /* free privates of this xdr_stream */ + void (*x_destroy)(struct XDR *); + bool_t (*x_control)(struct XDR *, int, void *); +}; +#endif + /* * Operations defined on a XDR handle * diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index e5b9ad064f7f..c08a0532eccb 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -44,10 +44,10 @@ SRCS+= list.c SRCS+= nvpair_alloc_system.c SRCS+= taskq.c -.PATH: ${SUNW}/uts/common/rpc -SRCS+= opensolaris_xdr.c -SRCS+= opensolaris_xdr_array.c -SRCS+= opensolaris_xdr_mem.c +#.PATH: ${SUNW}/uts/common/rpc +#SRCS+= opensolaris_xdr.c +#SRCS+= opensolaris_xdr_array.c +#SRCS+= opensolaris_xdr_mem.c .PATH: ${SUNW}/uts/common/zmod SRCS+= adler32.c diff --git a/sys/rpc/xdr.h b/sys/rpc/xdr.h index 947bf4f98131..9bc76b6db006 100644 --- a/sys/rpc/xdr.h +++ b/sys/rpc/xdr.h @@ -337,6 +337,22 @@ struct netobj { typedef struct netobj netobj; extern bool_t xdr_netobj(XDR *, struct netobj *); +/* + * These are XDR control operators + */ + +#define XDR_GET_BYTES_AVAIL 1 +#define XDR_PEEK 2 +#define XDR_SKIPBYTES 3 + +struct xdr_bytesrec { + bool_t xc_is_last_record; + size_t xc_num_avail; +}; + +typedef struct xdr_bytesrec xdr_bytesrec; + + /* * These are the public routines for the various implementations of * xdr streams. diff --git a/sys/xdr/xdr_mem.c b/sys/xdr/xdr_mem.c index 2dd5b73a79b1..74bab3b2621f 100644 --- a/sys/xdr/xdr_mem.c +++ b/sys/xdr/xdr_mem.c @@ -66,7 +66,8 @@ static u_int xdrmem_getpos(XDR *); static bool_t xdrmem_setpos(XDR *, u_int); static int32_t *xdrmem_inline_aligned(XDR *, u_int); static int32_t *xdrmem_inline_unaligned(XDR *, u_int); - +static bool_t xdrmem_control(XDR *xdrs, int request, void *info); + static const struct xdr_ops xdrmem_ops_aligned = { xdrmem_getlong_aligned, xdrmem_putlong_aligned, @@ -75,7 +76,8 @@ static const struct xdr_ops xdrmem_ops_aligned = { xdrmem_getpos, xdrmem_setpos, xdrmem_inline_aligned, - xdrmem_destroy + xdrmem_destroy, + xdrmem_control }; static const struct xdr_ops xdrmem_ops_unaligned = { @@ -86,7 +88,8 @@ static const struct xdr_ops xdrmem_ops_unaligned = { xdrmem_getpos, xdrmem_setpos, xdrmem_inline_unaligned, - xdrmem_destroy + xdrmem_destroy, + xdrmem_control }; /* @@ -228,3 +231,45 @@ xdrmem_inline_unaligned(XDR *xdrs, u_int len) return (0); } + +static bool_t +xdrmem_control(XDR *xdrs, int request, void *info) +{ + xdr_bytesrec *xptr; + int32_t *l; + 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); + l = (int32_t *)info; + *l = (int32_t)ntohl((uint32_t) + (*((int32_t *)(xdrs->x_private)))); + return (TRUE); + + case XDR_SKIPBYTES: + /* + * Skip the next N bytes in the XDR stream. + */ + l = (int32_t *)info; + len = RNDUP((int)(*l)); + if (xdrs->x_handy < len) + return (FALSE); + xdrs->x_handy -= len; + xdrs->x_private = (char *)xdrs->x_private + len; + return (TRUE); + + } + return (FALSE); +}