xref: /onnv-gate/usr/src/uts/common/rpc/xdrrdma_sizeof.c (revision 7387:0b3a92e31fd8)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7387SRobert.Gordon@Sun.COM  * Common Development and Distribution License (the "License").
6*7387SRobert.Gordon@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*7387SRobert.Gordon@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <rpc/types.h>
270Sstevel@tonic-gate #include <rpc/xdr.h>
280Sstevel@tonic-gate #include <sys/types.h>
29*7387SRobert.Gordon@Sun.COM #include <sys/sdt.h>
300Sstevel@tonic-gate #include <rpc/auth.h>
310Sstevel@tonic-gate #include <rpc/rpc_rdma.h>
320Sstevel@tonic-gate 
330Sstevel@tonic-gate struct private {
340Sstevel@tonic-gate 	int	min_chunk;
350Sstevel@tonic-gate 	uint_t	flags;			/* controls setting for rdma xdr */
360Sstevel@tonic-gate 	int	num_chunk;
370Sstevel@tonic-gate 	caddr_t	inline_buf;		/* temporary buffer for xdr inlining */
380Sstevel@tonic-gate 	int	inline_len;		/* inline buffer length */
39*7387SRobert.Gordon@Sun.COM 	uint_t	xp_reply_chunk_len;
40*7387SRobert.Gordon@Sun.COM 	uint_t	xp_reply_chunk_len_alt;
410Sstevel@tonic-gate };
420Sstevel@tonic-gate 
430Sstevel@tonic-gate /* ARGSUSED */
440Sstevel@tonic-gate static bool_t
x_putint32_t(XDR * xdrs,int32_t * ip)450Sstevel@tonic-gate x_putint32_t(XDR *xdrs, int32_t *ip)
460Sstevel@tonic-gate {
470Sstevel@tonic-gate 	xdrs->x_handy += BYTES_PER_XDR_UNIT;
480Sstevel@tonic-gate 	return (TRUE);
490Sstevel@tonic-gate }
500Sstevel@tonic-gate 
510Sstevel@tonic-gate /* ARGSUSED */
520Sstevel@tonic-gate static bool_t
x_putbytes(XDR * xdrs,char * bp,int len)530Sstevel@tonic-gate x_putbytes(XDR *xdrs, char *bp, int len)
540Sstevel@tonic-gate {
550Sstevel@tonic-gate 	struct private *xdrp = (struct private *)xdrs->x_private;
560Sstevel@tonic-gate 
570Sstevel@tonic-gate 	/*
580Sstevel@tonic-gate 	 * min_chunk = 0, means that the stream of bytes, to estimate size of,
590Sstevel@tonic-gate 	 * contains no chunks to seperate out. See xdrrdma_putbytes()
600Sstevel@tonic-gate 	 */
61*7387SRobert.Gordon@Sun.COM 	if (len < xdrp->min_chunk || !(xdrp->flags & XDR_RDMA_CHUNK)) {
620Sstevel@tonic-gate 		xdrs->x_handy += len;
630Sstevel@tonic-gate 		return (TRUE);
640Sstevel@tonic-gate 	}
650Sstevel@tonic-gate 	/*
660Sstevel@tonic-gate 	 * Chunk item. No impact on xdr size.
670Sstevel@tonic-gate 	 */
680Sstevel@tonic-gate 	xdrp->num_chunk++;
69*7387SRobert.Gordon@Sun.COM 
700Sstevel@tonic-gate 	return (TRUE);
710Sstevel@tonic-gate }
720Sstevel@tonic-gate 
730Sstevel@tonic-gate static uint_t
x_getpostn(XDR * xdrs)740Sstevel@tonic-gate x_getpostn(XDR *xdrs)
750Sstevel@tonic-gate {
760Sstevel@tonic-gate 	return (xdrs->x_handy);
770Sstevel@tonic-gate }
780Sstevel@tonic-gate 
790Sstevel@tonic-gate /* ARGSUSED */
800Sstevel@tonic-gate static bool_t
x_setpostn(XDR * xdrs,uint_t pos)810Sstevel@tonic-gate x_setpostn(XDR *xdrs, uint_t pos)
820Sstevel@tonic-gate {
830Sstevel@tonic-gate 	/* This is not allowed */
840Sstevel@tonic-gate 	return (FALSE);
850Sstevel@tonic-gate }
860Sstevel@tonic-gate 
870Sstevel@tonic-gate /* ARGSUSED */
880Sstevel@tonic-gate static bool_t
x_control(XDR * xdrs,int request,void * info)890Sstevel@tonic-gate x_control(XDR *xdrs, int request, void *info)
900Sstevel@tonic-gate {
910Sstevel@tonic-gate 	int32_t *int32p;
920Sstevel@tonic-gate 	uint_t in_flags;
93*7387SRobert.Gordon@Sun.COM 	rdma_chunkinfo_t *rcip = NULL;
94*7387SRobert.Gordon@Sun.COM 	rdma_chunkinfo_lengths_t *rcilp = NULL;
950Sstevel@tonic-gate 	struct private *xdrp = (struct private *)xdrs->x_private;
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	switch (request) {
98*7387SRobert.Gordon@Sun.COM 	case XDR_RDMA_SET_FLAGS:
990Sstevel@tonic-gate 		/*
1000Sstevel@tonic-gate 		 * Set the flags provided in the *info in xp_flags for rdma xdr
1010Sstevel@tonic-gate 		 * stream control.
1020Sstevel@tonic-gate 		 */
1030Sstevel@tonic-gate 		int32p = (int32_t *)info;
1040Sstevel@tonic-gate 		in_flags = (uint_t)(*int32p);
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 		xdrp->flags = in_flags;
1070Sstevel@tonic-gate 		return (TRUE);
1080Sstevel@tonic-gate 
109*7387SRobert.Gordon@Sun.COM 	case XDR_RDMA_GET_FLAGS:
1100Sstevel@tonic-gate 		/*
1110Sstevel@tonic-gate 		 * Get the flags provided in xp_flags return through *info
1120Sstevel@tonic-gate 		 */
1130Sstevel@tonic-gate 		int32p = (int32_t *)info;
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 		*int32p = (int32_t)xdrp->flags;
1160Sstevel@tonic-gate 		return (TRUE);
1170Sstevel@tonic-gate 
118*7387SRobert.Gordon@Sun.COM 	case XDR_RDMA_GET_CHUNK_LEN:
119*7387SRobert.Gordon@Sun.COM 		rcilp = (rdma_chunkinfo_lengths_t *)info;
120*7387SRobert.Gordon@Sun.COM 		rcilp->rcil_len = xdrp->xp_reply_chunk_len;
121*7387SRobert.Gordon@Sun.COM 		rcilp->rcil_len_alt = xdrp->xp_reply_chunk_len_alt;
122*7387SRobert.Gordon@Sun.COM 
123*7387SRobert.Gordon@Sun.COM 		return (TRUE);
124*7387SRobert.Gordon@Sun.COM 
125*7387SRobert.Gordon@Sun.COM 	case XDR_RDMA_ADD_CHUNK:
126*7387SRobert.Gordon@Sun.COM 		rcip = (rdma_chunkinfo_t *)info;
127*7387SRobert.Gordon@Sun.COM 
128*7387SRobert.Gordon@Sun.COM 		switch (rcip->rci_type) {
129*7387SRobert.Gordon@Sun.COM 		case RCI_WRITE_UIO_CHUNK:
130*7387SRobert.Gordon@Sun.COM 			xdrp->xp_reply_chunk_len_alt += rcip->rci_len;
131*7387SRobert.Gordon@Sun.COM 			break;
132*7387SRobert.Gordon@Sun.COM 
133*7387SRobert.Gordon@Sun.COM 		case RCI_WRITE_ADDR_CHUNK:
134*7387SRobert.Gordon@Sun.COM 			xdrp->xp_reply_chunk_len_alt += rcip->rci_len;
135*7387SRobert.Gordon@Sun.COM 			break;
136*7387SRobert.Gordon@Sun.COM 
137*7387SRobert.Gordon@Sun.COM 		case RCI_REPLY_CHUNK:
138*7387SRobert.Gordon@Sun.COM 			xdrp->xp_reply_chunk_len += rcip->rci_len;
139*7387SRobert.Gordon@Sun.COM 			break;
140*7387SRobert.Gordon@Sun.COM 		}
141*7387SRobert.Gordon@Sun.COM 		return (TRUE);
142*7387SRobert.Gordon@Sun.COM 
1430Sstevel@tonic-gate 	default:
1440Sstevel@tonic-gate 		return (FALSE);
1450Sstevel@tonic-gate 	}
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate /* ARGSUSED */
1490Sstevel@tonic-gate static rpc_inline_t *
x_inline(XDR * xdrs,int len)1500Sstevel@tonic-gate x_inline(XDR *xdrs, int len)
1510Sstevel@tonic-gate {
1520Sstevel@tonic-gate 	struct private *xdrp = (struct private *)xdrs->x_private;
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	if (len == 0) {
1550Sstevel@tonic-gate 		return (NULL);
1560Sstevel@tonic-gate 	}
1570Sstevel@tonic-gate 	if (xdrs->x_op != XDR_ENCODE) {
1580Sstevel@tonic-gate 		return (NULL);
1590Sstevel@tonic-gate 	}
1600Sstevel@tonic-gate 	if (len >= xdrp->min_chunk) {
1610Sstevel@tonic-gate 		return (NULL);
1620Sstevel@tonic-gate 	}
1630Sstevel@tonic-gate 	if (len <= xdrp->inline_len) {
1640Sstevel@tonic-gate 		/* inline_buf was already allocated, just reuse it */
1650Sstevel@tonic-gate 		xdrs->x_handy += len;
1660Sstevel@tonic-gate 		return ((rpc_inline_t *)xdrp->inline_buf);
1670Sstevel@tonic-gate 	} else {
1680Sstevel@tonic-gate 		/* Free the earlier space and allocate new area */
1690Sstevel@tonic-gate 		if (xdrp->inline_buf)
1700Sstevel@tonic-gate 			mem_free(xdrp->inline_buf, xdrp->inline_len);
1710Sstevel@tonic-gate 		if ((xdrp->inline_buf = (caddr_t)mem_alloc(len)) == NULL) {
1720Sstevel@tonic-gate 			xdrp->inline_len = 0;
1730Sstevel@tonic-gate 			return (NULL);
1740Sstevel@tonic-gate 		}
1750Sstevel@tonic-gate 		xdrp->inline_len = len;
1760Sstevel@tonic-gate 		xdrs->x_handy += len;
1770Sstevel@tonic-gate 		return ((rpc_inline_t *)xdrp->inline_buf);
1780Sstevel@tonic-gate 	}
1790Sstevel@tonic-gate }
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate static int
harmless()1820Sstevel@tonic-gate harmless()
1830Sstevel@tonic-gate {
1840Sstevel@tonic-gate 	/* Always return FALSE/NULL, as the case may be */
1850Sstevel@tonic-gate 	return (0);
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate static void
x_destroy(XDR * xdrs)1890Sstevel@tonic-gate x_destroy(XDR *xdrs)
1900Sstevel@tonic-gate {
1910Sstevel@tonic-gate 	struct private *xdrp = (struct private *)xdrs->x_private;
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 	xdrs->x_handy = 0;
1940Sstevel@tonic-gate 	if (xdrp) {
1950Sstevel@tonic-gate 		if (xdrp->inline_buf)
1960Sstevel@tonic-gate 			mem_free(xdrp->inline_buf, xdrp->inline_len);
1970Sstevel@tonic-gate 		mem_free(xdrp, sizeof (struct private));
1980Sstevel@tonic-gate 		xdrs->x_private = NULL;
1990Sstevel@tonic-gate 	}
2000Sstevel@tonic-gate 	xdrs->x_base = 0;
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate static bool_t
xdrrdma_common(XDR * xdrs,int min_chunk)2040Sstevel@tonic-gate xdrrdma_common(XDR *xdrs, int min_chunk)
2050Sstevel@tonic-gate {
2060Sstevel@tonic-gate 	struct private *xdrp;
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate 	xdrs->x_ops = xdrrdma_xops();
2090Sstevel@tonic-gate 	xdrs->x_op = XDR_ENCODE;
2100Sstevel@tonic-gate 	xdrs->x_handy = 0;
2110Sstevel@tonic-gate 	xdrs->x_base = NULL;
2120Sstevel@tonic-gate 	xdrs->x_private = kmem_zalloc(sizeof (struct private), KM_SLEEP);
2130Sstevel@tonic-gate 	xdrp = (struct private *)xdrs->x_private;
2140Sstevel@tonic-gate 	xdrp->min_chunk = min_chunk;
2150Sstevel@tonic-gate 	xdrp->flags = 0;
216*7387SRobert.Gordon@Sun.COM 	if (xdrp->min_chunk != 0)
217*7387SRobert.Gordon@Sun.COM 		xdrp->flags |= XDR_RDMA_CHUNK;
218*7387SRobert.Gordon@Sun.COM 
219*7387SRobert.Gordon@Sun.COM 	xdrp->xp_reply_chunk_len = 0;
220*7387SRobert.Gordon@Sun.COM 	xdrp->xp_reply_chunk_len_alt = 0;
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate 	return (TRUE);
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate unsigned int
xdrrdma_sizeof(xdrproc_t func,void * data,int min_chunk,uint_t * reply_size,uint_t * reply_size_alt)226*7387SRobert.Gordon@Sun.COM xdrrdma_sizeof(xdrproc_t func, void *data, int min_chunk,
227*7387SRobert.Gordon@Sun.COM     uint_t *reply_size, uint_t *reply_size_alt)
2280Sstevel@tonic-gate {
2290Sstevel@tonic-gate 	XDR x;
2300Sstevel@tonic-gate 	struct xdr_ops ops;
2310Sstevel@tonic-gate 	bool_t stat;
2320Sstevel@tonic-gate 	struct private *xdrp;
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	x.x_ops = &ops;
2350Sstevel@tonic-gate 	(void) xdrrdma_common(&x, min_chunk);
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 	stat = func(&x, data);
2380Sstevel@tonic-gate 	xdrp = (struct private *)x.x_private;
2390Sstevel@tonic-gate 	if (xdrp) {
240*7387SRobert.Gordon@Sun.COM 		if (reply_size != NULL)
241*7387SRobert.Gordon@Sun.COM 			*reply_size = xdrp->xp_reply_chunk_len;
242*7387SRobert.Gordon@Sun.COM 		if (reply_size_alt != NULL)
243*7387SRobert.Gordon@Sun.COM 			*reply_size_alt = xdrp->xp_reply_chunk_len_alt;
2440Sstevel@tonic-gate 		if (xdrp->inline_buf)
2450Sstevel@tonic-gate 			mem_free(xdrp->inline_buf, xdrp->inline_len);
2460Sstevel@tonic-gate 		mem_free(xdrp, sizeof (struct private));
2470Sstevel@tonic-gate 	}
2480Sstevel@tonic-gate 	return (stat == TRUE ? (unsigned int)x.x_handy: 0);
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate unsigned int
xdrrdma_authsize(AUTH * auth,struct cred * cred,int min_chunk)2520Sstevel@tonic-gate xdrrdma_authsize(AUTH *auth, struct cred *cred, int min_chunk)
2530Sstevel@tonic-gate {
2540Sstevel@tonic-gate 	XDR x;
2550Sstevel@tonic-gate 	struct xdr_ops ops;
2560Sstevel@tonic-gate 	bool_t stat;
2570Sstevel@tonic-gate 	struct private *xdrp;
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate 	x.x_ops = &ops;
2600Sstevel@tonic-gate 	(void) xdrrdma_common(&x, min_chunk);
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate 	stat = AUTH_MARSHALL(auth, &x, cred);
2630Sstevel@tonic-gate 	xdrp = (struct private *)x.x_private;
2640Sstevel@tonic-gate 	if (xdrp) {
2650Sstevel@tonic-gate 		if (xdrp->inline_buf)
2660Sstevel@tonic-gate 			mem_free(xdrp->inline_buf, xdrp->inline_len);
2670Sstevel@tonic-gate 		mem_free(xdrp, sizeof (struct private));
2680Sstevel@tonic-gate 	}
2690Sstevel@tonic-gate 	return (stat == TRUE ? (unsigned int)x.x_handy: 0);
2700Sstevel@tonic-gate }
2710Sstevel@tonic-gate 
272*7387SRobert.Gordon@Sun.COM struct xdr_ops *
xdrrdma_xops(void)2730Sstevel@tonic-gate xdrrdma_xops(void)
2740Sstevel@tonic-gate {
2750Sstevel@tonic-gate 	static struct xdr_ops ops;
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 	/* to stop ANSI-C compiler from complaining */
2780Sstevel@tonic-gate 	typedef  bool_t (* dummyfunc1)(XDR *, long *);
2790Sstevel@tonic-gate 	typedef  bool_t (* dummyfunc2)(XDR *, caddr_t, int);
2800Sstevel@tonic-gate 	typedef  bool_t (* dummyfunc3)(XDR *, int32_t *);
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 	ops.x_putbytes = x_putbytes;
2830Sstevel@tonic-gate 	ops.x_inline = x_inline;
2840Sstevel@tonic-gate 	ops.x_getpostn = x_getpostn;
2850Sstevel@tonic-gate 	ops.x_setpostn = x_setpostn;
2860Sstevel@tonic-gate 	ops.x_destroy = x_destroy;
2870Sstevel@tonic-gate 	ops.x_control = x_control;
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate #if defined(_LP64) || defined(_KERNEL)
2900Sstevel@tonic-gate 	ops.x_getint32 = (dummyfunc3)harmless;
2910Sstevel@tonic-gate 	ops.x_putint32 = x_putint32_t;
2920Sstevel@tonic-gate #endif
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate 	/* the other harmless ones */
2950Sstevel@tonic-gate 	ops.x_getbytes = (dummyfunc2)harmless;
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	return (&ops);
2980Sstevel@tonic-gate }
299