17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5742e7b7fSmaheshvs * Common Development and Distribution License (the "License"). 6742e7b7fSmaheshvs * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*cf98b944SMarcel Telka 22*cf98b944SMarcel Telka /* 23*cf98b944SMarcel Telka * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 24*cf98b944SMarcel Telka */ 25*cf98b944SMarcel Telka 267c478bd9Sstevel@tonic-gate /* 27c242f9a0Schunli zhang - Sun Microsystems - Irvine United States * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 287c478bd9Sstevel@tonic-gate * Use is subject to license terms. 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 327c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate /* 357c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 367c478bd9Sstevel@tonic-gate * under license from the Regents of the University of California. 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate /* 407c478bd9Sstevel@tonic-gate * xdr_mblk.c, XDR implementation on kernel streams mblks. 417c478bd9Sstevel@tonic-gate */ 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate #include <sys/param.h> 447c478bd9Sstevel@tonic-gate #include <sys/types.h> 457c478bd9Sstevel@tonic-gate #include <sys/systm.h> 467c478bd9Sstevel@tonic-gate #include <sys/stream.h> 477c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 487c478bd9Sstevel@tonic-gate #include <sys/strsubr.h> 497c478bd9Sstevel@tonic-gate #include <sys/strsun.h> 507c478bd9Sstevel@tonic-gate #include <sys/debug.h> 517c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate #include <rpc/types.h> 547c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate static bool_t xdrmblk_getint32(XDR *, int32_t *); 577c478bd9Sstevel@tonic-gate static bool_t xdrmblk_putint32(XDR *, int32_t *); 587c478bd9Sstevel@tonic-gate static bool_t xdrmblk_getbytes(XDR *, caddr_t, int); 597c478bd9Sstevel@tonic-gate static bool_t xdrmblk_putbytes(XDR *, caddr_t, int); 607c478bd9Sstevel@tonic-gate static uint_t xdrmblk_getpos(XDR *); 617c478bd9Sstevel@tonic-gate static bool_t xdrmblk_setpos(XDR *, uint_t); 627c478bd9Sstevel@tonic-gate static rpc_inline_t *xdrmblk_inline(XDR *, int); 637c478bd9Sstevel@tonic-gate static void xdrmblk_destroy(XDR *); 647c478bd9Sstevel@tonic-gate static bool_t xdrmblk_control(XDR *, int, void *); 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate static mblk_t *xdrmblk_alloc(int); 67*cf98b944SMarcel Telka static void xdrmblk_skip_fully_read_mblks(XDR *); 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate /* 707c478bd9Sstevel@tonic-gate * Xdr on mblks operations vector. 717c478bd9Sstevel@tonic-gate */ 727c478bd9Sstevel@tonic-gate struct xdr_ops xdrmblk_ops = { 737c478bd9Sstevel@tonic-gate xdrmblk_getbytes, 747c478bd9Sstevel@tonic-gate xdrmblk_putbytes, 757c478bd9Sstevel@tonic-gate xdrmblk_getpos, 767c478bd9Sstevel@tonic-gate xdrmblk_setpos, 777c478bd9Sstevel@tonic-gate xdrmblk_inline, 787c478bd9Sstevel@tonic-gate xdrmblk_destroy, 797c478bd9Sstevel@tonic-gate xdrmblk_control, 807c478bd9Sstevel@tonic-gate xdrmblk_getint32, 817c478bd9Sstevel@tonic-gate xdrmblk_putint32 827c478bd9Sstevel@tonic-gate }; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* 85*cf98b944SMarcel Telka * The xdrmblk_params structure holds the internal data for the XDR stream. 86*cf98b944SMarcel Telka * The x_private member of the XDR points to this structure. The 87*cf98b944SMarcel Telka * xdrmblk_params structure is dynamically allocated in xdrmblk_init() and 88*cf98b944SMarcel Telka * freed in xdrmblk_destroy(). 89*cf98b944SMarcel Telka * 90*cf98b944SMarcel Telka * The apos and rpos members of the xdrmblk_params structure are used to 91*cf98b944SMarcel Telka * implement xdrmblk_getpos() and xdrmblk_setpos(). 92*cf98b944SMarcel Telka * 93*cf98b944SMarcel Telka * In addition to the xdrmblk_params structure we store some additional 94*cf98b944SMarcel Telka * internal data directly in the XDR stream structure: 95*cf98b944SMarcel Telka * 96*cf98b944SMarcel Telka * x_base A pointer to the current mblk (that one we are currently 97*cf98b944SMarcel Telka * working with). 98*cf98b944SMarcel Telka * x_handy The number of available bytes (either for read or for write) in 99*cf98b944SMarcel Telka * the current mblk. 100*cf98b944SMarcel Telka */ 101*cf98b944SMarcel Telka struct xdrmblk_params { 102*cf98b944SMarcel Telka int sz; 103*cf98b944SMarcel Telka uint_t apos; /* Absolute position of the current mblk */ 104*cf98b944SMarcel Telka uint_t rpos; /* Relative position in the current mblk */ 105*cf98b944SMarcel Telka }; 106*cf98b944SMarcel Telka 107*cf98b944SMarcel Telka /* 1087c478bd9Sstevel@tonic-gate * Initialize xdr stream. 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate void 1117c478bd9Sstevel@tonic-gate xdrmblk_init(XDR *xdrs, mblk_t *m, enum xdr_op op, int sz) 1127c478bd9Sstevel@tonic-gate { 113*cf98b944SMarcel Telka struct xdrmblk_params *p; 114*cf98b944SMarcel Telka 1157c478bd9Sstevel@tonic-gate xdrs->x_op = op; 1167c478bd9Sstevel@tonic-gate xdrs->x_ops = &xdrmblk_ops; 1177c478bd9Sstevel@tonic-gate xdrs->x_base = (caddr_t)m; 1187c478bd9Sstevel@tonic-gate xdrs->x_public = NULL; 119*cf98b944SMarcel Telka p = kmem_alloc(sizeof (struct xdrmblk_params), KM_SLEEP); 120*cf98b944SMarcel Telka xdrs->x_private = (caddr_t)p; 1217c478bd9Sstevel@tonic-gate 122*cf98b944SMarcel Telka p->sz = sz; 123*cf98b944SMarcel Telka p->apos = 0; 124*cf98b944SMarcel Telka p->rpos = 0; 125*cf98b944SMarcel Telka 126*cf98b944SMarcel Telka if (op == XDR_DECODE) { 127*cf98b944SMarcel Telka xdrs->x_handy = (int)MBLKL(m); 128*cf98b944SMarcel Telka } else { 129*cf98b944SMarcel Telka xdrs->x_handy = (int)MBLKTAIL(m); 130*cf98b944SMarcel Telka if (p->sz < sizeof (int32_t)) 131*cf98b944SMarcel Telka p->sz = sizeof (int32_t); 132*cf98b944SMarcel Telka } 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate static void 1367c478bd9Sstevel@tonic-gate xdrmblk_destroy(XDR *xdrs) 1377c478bd9Sstevel@tonic-gate { 138*cf98b944SMarcel Telka kmem_free(xdrs->x_private, sizeof (struct xdrmblk_params)); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate static bool_t 1427c478bd9Sstevel@tonic-gate xdrmblk_getint32(XDR *xdrs, int32_t *int32p) 1437c478bd9Sstevel@tonic-gate { 1447c478bd9Sstevel@tonic-gate mblk_t *m; 145*cf98b944SMarcel Telka struct xdrmblk_params *p; 146*cf98b944SMarcel Telka 147*cf98b944SMarcel Telka xdrmblk_skip_fully_read_mblks(xdrs); 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 1507c478bd9Sstevel@tonic-gate m = (mblk_t *)xdrs->x_base; 1517c478bd9Sstevel@tonic-gate if (m == NULL) 1527c478bd9Sstevel@tonic-gate return (FALSE); 153*cf98b944SMarcel Telka 154*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 155*cf98b944SMarcel Telka 1567c478bd9Sstevel@tonic-gate /* 1577c478bd9Sstevel@tonic-gate * If the pointer is not aligned or there is not 1587c478bd9Sstevel@tonic-gate * enough bytes, pullupmsg to get enough bytes and 1597c478bd9Sstevel@tonic-gate * align the mblk. 1607c478bd9Sstevel@tonic-gate */ 1617c478bd9Sstevel@tonic-gate if (!IS_P2ALIGNED(m->b_rptr, sizeof (int32_t)) || 1627c478bd9Sstevel@tonic-gate xdrs->x_handy < sizeof (int32_t)) { 1637c478bd9Sstevel@tonic-gate while (!pullupmsg(m, sizeof (int32_t))) { 1647c478bd9Sstevel@tonic-gate /* 1657c478bd9Sstevel@tonic-gate * Could have failed due to not 1667c478bd9Sstevel@tonic-gate * enough data or an allocb failure. 1677c478bd9Sstevel@tonic-gate */ 1687c478bd9Sstevel@tonic-gate if (xmsgsize(m) < sizeof (int32_t)) 1697c478bd9Sstevel@tonic-gate return (FALSE); 1707c478bd9Sstevel@tonic-gate delay(hz); 1717c478bd9Sstevel@tonic-gate } 172*cf98b944SMarcel Telka p->apos += p->rpos; 173*cf98b944SMarcel Telka p->rpos = 0; 174*cf98b944SMarcel Telka xdrs->x_handy = (int)MBLKL(m); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 1787c478bd9Sstevel@tonic-gate *int32p = ntohl(*((int32_t *)(m->b_rptr))); 1797c478bd9Sstevel@tonic-gate m->b_rptr += sizeof (int32_t); 180*cf98b944SMarcel Telka xdrs->x_handy -= sizeof (int32_t); 181*cf98b944SMarcel Telka p->rpos += sizeof (int32_t); 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate return (TRUE); 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate static bool_t 1877c478bd9Sstevel@tonic-gate xdrmblk_putint32(XDR *xdrs, int32_t *int32p) 1887c478bd9Sstevel@tonic-gate { 1897c478bd9Sstevel@tonic-gate mblk_t *m; 190*cf98b944SMarcel Telka struct xdrmblk_params *p; 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 1937c478bd9Sstevel@tonic-gate m = (mblk_t *)xdrs->x_base; 1947c478bd9Sstevel@tonic-gate if (m == NULL) 1957c478bd9Sstevel@tonic-gate return (FALSE); 196*cf98b944SMarcel Telka 197*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 198*cf98b944SMarcel Telka 199*cf98b944SMarcel Telka while (!IS_P2ALIGNED(m->b_wptr, sizeof (int32_t)) || 200*cf98b944SMarcel Telka xdrs->x_handy < sizeof (int32_t)) { 2017c478bd9Sstevel@tonic-gate if (m->b_cont == NULL) { 202*cf98b944SMarcel Telka ASSERT(p->sz >= sizeof (int32_t)); 203*cf98b944SMarcel Telka m->b_cont = xdrmblk_alloc(p->sz); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate m = m->b_cont; 2067c478bd9Sstevel@tonic-gate xdrs->x_base = (caddr_t)m; 207*cf98b944SMarcel Telka p->apos += p->rpos; 208*cf98b944SMarcel Telka p->rpos = 0; 2097c478bd9Sstevel@tonic-gate if (m == NULL) { 2107c478bd9Sstevel@tonic-gate xdrs->x_handy = 0; 2117c478bd9Sstevel@tonic-gate return (FALSE); 2127c478bd9Sstevel@tonic-gate } 213*cf98b944SMarcel Telka xdrs->x_handy = (int)MBLKTAIL(m); 2147c478bd9Sstevel@tonic-gate ASSERT(m->b_rptr == m->b_wptr); 2157c478bd9Sstevel@tonic-gate ASSERT(m->b_rptr >= m->b_datap->db_base); 2167c478bd9Sstevel@tonic-gate ASSERT(m->b_rptr < m->b_datap->db_lim); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 2197c478bd9Sstevel@tonic-gate *(int32_t *)m->b_wptr = htonl(*int32p); 2207c478bd9Sstevel@tonic-gate m->b_wptr += sizeof (int32_t); 221*cf98b944SMarcel Telka xdrs->x_handy -= sizeof (int32_t); 222*cf98b944SMarcel Telka p->rpos += sizeof (int32_t); 2237c478bd9Sstevel@tonic-gate ASSERT(m->b_wptr <= m->b_datap->db_lim); 2247c478bd9Sstevel@tonic-gate return (TRUE); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate /* 2287c478bd9Sstevel@tonic-gate * We pick 16 as a compromise threshold for most architectures. 2297c478bd9Sstevel@tonic-gate */ 2307c478bd9Sstevel@tonic-gate #define XDRMBLK_BCOPY_LIMIT 16 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate static bool_t 2337c478bd9Sstevel@tonic-gate xdrmblk_getbytes(XDR *xdrs, caddr_t addr, int len) 2347c478bd9Sstevel@tonic-gate { 2357c478bd9Sstevel@tonic-gate mblk_t *m; 236*cf98b944SMarcel Telka struct xdrmblk_params *p; 2377c478bd9Sstevel@tonic-gate int i; 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 2407c478bd9Sstevel@tonic-gate m = (mblk_t *)xdrs->x_base; 2417c478bd9Sstevel@tonic-gate if (m == NULL) 2427c478bd9Sstevel@tonic-gate return (FALSE); 243*cf98b944SMarcel Telka 244*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 245*cf98b944SMarcel Telka 2467c478bd9Sstevel@tonic-gate /* 2477c478bd9Sstevel@tonic-gate * Performance tweak: converted explicit bcopy() 2487c478bd9Sstevel@tonic-gate * call to simple in-line. This function is called 2497c478bd9Sstevel@tonic-gate * to process things like readdir reply filenames 2507c478bd9Sstevel@tonic-gate * which are small strings--typically 12 bytes or less. 2517c478bd9Sstevel@tonic-gate * Overhead of calling bcopy() is obnoxious for such 2527c478bd9Sstevel@tonic-gate * small copies. 2537c478bd9Sstevel@tonic-gate */ 254*cf98b944SMarcel Telka while (xdrs->x_handy < len) { 255*cf98b944SMarcel Telka if (xdrs->x_handy > 0) { 256*cf98b944SMarcel Telka if (xdrs->x_handy < XDRMBLK_BCOPY_LIMIT) { 2577c478bd9Sstevel@tonic-gate for (i = 0; i < xdrs->x_handy; i++) 2587c478bd9Sstevel@tonic-gate *addr++ = *m->b_rptr++; 2597c478bd9Sstevel@tonic-gate } else { 2607c478bd9Sstevel@tonic-gate bcopy(m->b_rptr, addr, xdrs->x_handy); 2617c478bd9Sstevel@tonic-gate m->b_rptr += xdrs->x_handy; 2627c478bd9Sstevel@tonic-gate addr += xdrs->x_handy; 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate len -= xdrs->x_handy; 265*cf98b944SMarcel Telka p->rpos += xdrs->x_handy; 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate m = m->b_cont; 2687c478bd9Sstevel@tonic-gate xdrs->x_base = (caddr_t)m; 269*cf98b944SMarcel Telka p->apos += p->rpos; 270*cf98b944SMarcel Telka p->rpos = 0; 2717c478bd9Sstevel@tonic-gate if (m == NULL) { 2727c478bd9Sstevel@tonic-gate xdrs->x_handy = 0; 2737c478bd9Sstevel@tonic-gate return (FALSE); 2747c478bd9Sstevel@tonic-gate } 275*cf98b944SMarcel Telka xdrs->x_handy = (int)MBLKL(m); 2767c478bd9Sstevel@tonic-gate } 277*cf98b944SMarcel Telka 278*cf98b944SMarcel Telka xdrs->x_handy -= len; 279*cf98b944SMarcel Telka p->rpos += len; 280*cf98b944SMarcel Telka 2817c478bd9Sstevel@tonic-gate if (len < XDRMBLK_BCOPY_LIMIT) { 2827c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) 2837c478bd9Sstevel@tonic-gate *addr++ = *m->b_rptr++; 2847c478bd9Sstevel@tonic-gate } else { 2857c478bd9Sstevel@tonic-gate bcopy(m->b_rptr, addr, len); 2867c478bd9Sstevel@tonic-gate m->b_rptr += len; 2877c478bd9Sstevel@tonic-gate } 288*cf98b944SMarcel Telka 2897c478bd9Sstevel@tonic-gate return (TRUE); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate /* 2937c478bd9Sstevel@tonic-gate * Sort of like getbytes except that instead of getting bytes we return the 2947c478bd9Sstevel@tonic-gate * mblk chain which contains the data. If the data ends in the middle of 2957c478bd9Sstevel@tonic-gate * an mblk, the mblk is dup'd and split, so that the data will end on an 2967c478bd9Sstevel@tonic-gate * mblk. Note that it is up to the caller to keep track of the data length 2977c478bd9Sstevel@tonic-gate * and not walk too far down the mblk chain. 2987c478bd9Sstevel@tonic-gate */ 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate bool_t 3017c478bd9Sstevel@tonic-gate xdrmblk_getmblk(XDR *xdrs, mblk_t **mm, uint_t *lenp) 3027c478bd9Sstevel@tonic-gate { 3037c478bd9Sstevel@tonic-gate mblk_t *m, *nextm; 304*cf98b944SMarcel Telka struct xdrmblk_params *p; 3057c478bd9Sstevel@tonic-gate int len; 306*cf98b944SMarcel Telka uint32_t llen; 3077c478bd9Sstevel@tonic-gate 308*cf98b944SMarcel Telka if (!xdrmblk_getint32(xdrs, (int32_t *)&llen)) 3097c478bd9Sstevel@tonic-gate return (FALSE); 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate *lenp = llen; 3127c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 3137c478bd9Sstevel@tonic-gate m = (mblk_t *)xdrs->x_base; 3147c478bd9Sstevel@tonic-gate *mm = m; 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate /* 3177c478bd9Sstevel@tonic-gate * Walk the mblk chain until we get to the end or we've gathered 3187c478bd9Sstevel@tonic-gate * enough data. 3197c478bd9Sstevel@tonic-gate */ 3207c478bd9Sstevel@tonic-gate len = 0; 3217c478bd9Sstevel@tonic-gate llen = roundup(llen, BYTES_PER_XDR_UNIT); 3227c478bd9Sstevel@tonic-gate while (m != NULL && len + (int)MBLKL(m) <= llen) { 3237c478bd9Sstevel@tonic-gate len += (int)MBLKL(m); 3247c478bd9Sstevel@tonic-gate m = m->b_cont; 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate if (len < llen) { 3277c478bd9Sstevel@tonic-gate if (m == NULL) { 3287c478bd9Sstevel@tonic-gate return (FALSE); 3297c478bd9Sstevel@tonic-gate } else { 3307c478bd9Sstevel@tonic-gate int tail_bytes = llen - len; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate /* 3337c478bd9Sstevel@tonic-gate * Split the mblk with the last chunk of data and 3347c478bd9Sstevel@tonic-gate * insert it into the chain. The new mblk goes 3357c478bd9Sstevel@tonic-gate * after the existing one so that it will get freed 3367c478bd9Sstevel@tonic-gate * properly. 3377c478bd9Sstevel@tonic-gate */ 3387c478bd9Sstevel@tonic-gate nextm = dupb(m); 3397c478bd9Sstevel@tonic-gate if (nextm == NULL) 3407c478bd9Sstevel@tonic-gate return (FALSE); 3417c478bd9Sstevel@tonic-gate nextm->b_cont = m->b_cont; 3427c478bd9Sstevel@tonic-gate m->b_cont = nextm; 3437c478bd9Sstevel@tonic-gate m->b_wptr = m->b_rptr + tail_bytes; 3447c478bd9Sstevel@tonic-gate nextm->b_rptr += tail_bytes; 3457c478bd9Sstevel@tonic-gate ASSERT(nextm->b_rptr != nextm->b_wptr); 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate m = nextm; /* for x_base */ 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate xdrs->x_base = (caddr_t)m; 3517c478bd9Sstevel@tonic-gate xdrs->x_handy = m != NULL ? MBLKL(m) : 0; 352*cf98b944SMarcel Telka 353*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 354*cf98b944SMarcel Telka p->apos += p->rpos + llen; 355*cf98b944SMarcel Telka p->rpos = 0; 356*cf98b944SMarcel Telka 3577c478bd9Sstevel@tonic-gate return (TRUE); 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate static bool_t 3617c478bd9Sstevel@tonic-gate xdrmblk_putbytes(XDR *xdrs, caddr_t addr, int len) 3627c478bd9Sstevel@tonic-gate { 3637c478bd9Sstevel@tonic-gate mblk_t *m; 364*cf98b944SMarcel Telka struct xdrmblk_params *p; 365*cf98b944SMarcel Telka int i; 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 3687c478bd9Sstevel@tonic-gate m = (mblk_t *)xdrs->x_base; 3697c478bd9Sstevel@tonic-gate if (m == NULL) 3707c478bd9Sstevel@tonic-gate return (FALSE); 371*cf98b944SMarcel Telka 372*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 373*cf98b944SMarcel Telka 3747c478bd9Sstevel@tonic-gate /* 3757c478bd9Sstevel@tonic-gate * Performance tweak: converted explicit bcopy() 3767c478bd9Sstevel@tonic-gate * call to simple in-line. This function is called 3777c478bd9Sstevel@tonic-gate * to process things like readdir reply filenames 3787c478bd9Sstevel@tonic-gate * which are small strings--typically 12 bytes or less. 3797c478bd9Sstevel@tonic-gate * Overhead of calling bcopy() is obnoxious for such 3807c478bd9Sstevel@tonic-gate * small copies. 3817c478bd9Sstevel@tonic-gate */ 382*cf98b944SMarcel Telka while (xdrs->x_handy < len) { 383*cf98b944SMarcel Telka if (xdrs->x_handy > 0) { 3847c478bd9Sstevel@tonic-gate if (xdrs->x_handy < XDRMBLK_BCOPY_LIMIT) { 385*cf98b944SMarcel Telka for (i = 0; i < xdrs->x_handy; i++) 3867c478bd9Sstevel@tonic-gate *m->b_wptr++ = *addr++; 3877c478bd9Sstevel@tonic-gate } else { 3887c478bd9Sstevel@tonic-gate bcopy(addr, m->b_wptr, xdrs->x_handy); 3897c478bd9Sstevel@tonic-gate m->b_wptr += xdrs->x_handy; 3907c478bd9Sstevel@tonic-gate addr += xdrs->x_handy; 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate len -= xdrs->x_handy; 393*cf98b944SMarcel Telka p->rpos += xdrs->x_handy; 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate /* 3977c478bd9Sstevel@tonic-gate * We don't have enough space, so allocate the 398*cf98b944SMarcel Telka * amount we need, or sz, whichever is larger. 3997c478bd9Sstevel@tonic-gate * It is better to let the underlying transport divide 4007c478bd9Sstevel@tonic-gate * large chunks than to try and guess what is best. 4017c478bd9Sstevel@tonic-gate */ 4027c478bd9Sstevel@tonic-gate if (m->b_cont == NULL) 403*cf98b944SMarcel Telka m->b_cont = xdrmblk_alloc(MAX(len, p->sz)); 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate m = m->b_cont; 4067c478bd9Sstevel@tonic-gate xdrs->x_base = (caddr_t)m; 407*cf98b944SMarcel Telka p->apos += p->rpos; 408*cf98b944SMarcel Telka p->rpos = 0; 4097c478bd9Sstevel@tonic-gate if (m == NULL) { 4107c478bd9Sstevel@tonic-gate xdrs->x_handy = 0; 4117c478bd9Sstevel@tonic-gate return (FALSE); 4127c478bd9Sstevel@tonic-gate } 413*cf98b944SMarcel Telka xdrs->x_handy = (int)MBLKTAIL(m); 4147c478bd9Sstevel@tonic-gate ASSERT(m->b_rptr == m->b_wptr); 4157c478bd9Sstevel@tonic-gate ASSERT(m->b_rptr >= m->b_datap->db_base); 4167c478bd9Sstevel@tonic-gate ASSERT(m->b_rptr < m->b_datap->db_lim); 4177c478bd9Sstevel@tonic-gate } 418*cf98b944SMarcel Telka 419*cf98b944SMarcel Telka xdrs->x_handy -= len; 420*cf98b944SMarcel Telka p->rpos += len; 421*cf98b944SMarcel Telka 4227c478bd9Sstevel@tonic-gate if (len < XDRMBLK_BCOPY_LIMIT) { 4237c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) 4247c478bd9Sstevel@tonic-gate *m->b_wptr++ = *addr++; 4257c478bd9Sstevel@tonic-gate } else { 4267c478bd9Sstevel@tonic-gate bcopy(addr, m->b_wptr, len); 4277c478bd9Sstevel@tonic-gate m->b_wptr += len; 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate ASSERT(m->b_wptr <= m->b_datap->db_lim); 4307c478bd9Sstevel@tonic-gate return (TRUE); 4317c478bd9Sstevel@tonic-gate } 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate /* 4347c478bd9Sstevel@tonic-gate * We avoid a copy by merely adding this mblk to the list. The caller is 4357c478bd9Sstevel@tonic-gate * responsible for allocating and filling in the mblk. If len is 4367c478bd9Sstevel@tonic-gate * not a multiple of BYTES_PER_XDR_UNIT, the caller has the option 4377c478bd9Sstevel@tonic-gate * of making the data a BYTES_PER_XDR_UNIT multiple (b_wptr - b_rptr is 4387c478bd9Sstevel@tonic-gate * a BYTES_PER_XDR_UNIT multiple), but in this case the caller has to ensure 439c242f9a0Schunli zhang - Sun Microsystems - Irvine United States * that the filler bytes are initialized to zero. 4407c478bd9Sstevel@tonic-gate */ 4417c478bd9Sstevel@tonic-gate bool_t 4427c478bd9Sstevel@tonic-gate xdrmblk_putmblk(XDR *xdrs, mblk_t *m, uint_t len) 4437c478bd9Sstevel@tonic-gate { 444*cf98b944SMarcel Telka struct xdrmblk_params *p; 4457c478bd9Sstevel@tonic-gate int32_t llen = (int32_t)len; 4467c478bd9Sstevel@tonic-gate 447c242f9a0Schunli zhang - Sun Microsystems - Irvine United States if ((DLEN(m) % BYTES_PER_XDR_UNIT) != 0) 4487c478bd9Sstevel@tonic-gate return (FALSE); 4497c478bd9Sstevel@tonic-gate if (!xdrmblk_putint32(xdrs, &llen)) 4507c478bd9Sstevel@tonic-gate return (FALSE); 451c242f9a0Schunli zhang - Sun Microsystems - Irvine United States 452*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 453*cf98b944SMarcel Telka 4547c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 4557c478bd9Sstevel@tonic-gate ((mblk_t *)xdrs->x_base)->b_cont = m; 456*cf98b944SMarcel Telka p->apos += p->rpos; 457c242f9a0Schunli zhang - Sun Microsystems - Irvine United States 458c242f9a0Schunli zhang - Sun Microsystems - Irvine United States /* base points to the last mblk */ 459*cf98b944SMarcel Telka while (m->b_cont) { 460*cf98b944SMarcel Telka p->apos += MBLKL(m); 461c242f9a0Schunli zhang - Sun Microsystems - Irvine United States m = m->b_cont; 462*cf98b944SMarcel Telka } 4637c478bd9Sstevel@tonic-gate xdrs->x_base = (caddr_t)m; 4647c478bd9Sstevel@tonic-gate xdrs->x_handy = 0; 465*cf98b944SMarcel Telka p->rpos = MBLKL(m); 4667c478bd9Sstevel@tonic-gate return (TRUE); 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate static uint_t 4707c478bd9Sstevel@tonic-gate xdrmblk_getpos(XDR *xdrs) 4717c478bd9Sstevel@tonic-gate { 472*cf98b944SMarcel Telka struct xdrmblk_params *p = (struct xdrmblk_params *)xdrs->x_private; 4737c478bd9Sstevel@tonic-gate 474*cf98b944SMarcel Telka return (p->apos + p->rpos); 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate static bool_t 4787c478bd9Sstevel@tonic-gate xdrmblk_setpos(XDR *xdrs, uint_t pos) 4797c478bd9Sstevel@tonic-gate { 4807c478bd9Sstevel@tonic-gate mblk_t *m; 481*cf98b944SMarcel Telka struct xdrmblk_params *p; 482*cf98b944SMarcel Telka 483*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 484*cf98b944SMarcel Telka 485*cf98b944SMarcel Telka if (pos < p->apos) 486*cf98b944SMarcel Telka return (FALSE); 487*cf98b944SMarcel Telka 488*cf98b944SMarcel Telka if (pos > p->apos + p->rpos + xdrs->x_handy) 489*cf98b944SMarcel Telka return (FALSE); 490*cf98b944SMarcel Telka 491*cf98b944SMarcel Telka if (pos == p->apos + p->rpos) 492*cf98b944SMarcel Telka return (TRUE); 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 4957c478bd9Sstevel@tonic-gate m = (mblk_t *)xdrs->x_base; 496*cf98b944SMarcel Telka ASSERT(m != NULL); 4977c478bd9Sstevel@tonic-gate 498*cf98b944SMarcel Telka if (xdrs->x_op == XDR_DECODE) 499*cf98b944SMarcel Telka m->b_rptr = m->b_rptr - p->rpos + (pos - p->apos); 500*cf98b944SMarcel Telka else 501*cf98b944SMarcel Telka m->b_wptr = m->b_wptr - p->rpos + (pos - p->apos); 5027c478bd9Sstevel@tonic-gate 503*cf98b944SMarcel Telka xdrs->x_handy = p->rpos + xdrs->x_handy - (pos - p->apos); 504*cf98b944SMarcel Telka p->rpos = pos - p->apos; 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate return (TRUE); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate #ifdef DEBUG 5107c478bd9Sstevel@tonic-gate static int xdrmblk_inline_hits = 0; 5117c478bd9Sstevel@tonic-gate static int xdrmblk_inline_misses = 0; 5127c478bd9Sstevel@tonic-gate static int do_xdrmblk_inline = 1; 5137c478bd9Sstevel@tonic-gate #endif 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate static rpc_inline_t * 5167c478bd9Sstevel@tonic-gate xdrmblk_inline(XDR *xdrs, int len) 5177c478bd9Sstevel@tonic-gate { 5187c478bd9Sstevel@tonic-gate rpc_inline_t *buf; 5197c478bd9Sstevel@tonic-gate mblk_t *m; 520*cf98b944SMarcel Telka unsigned char **mptr; 521*cf98b944SMarcel Telka struct xdrmblk_params *p; 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate /* 5247c478bd9Sstevel@tonic-gate * Can't inline XDR_FREE calls, doesn't make sense. 5257c478bd9Sstevel@tonic-gate */ 5267c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 5277c478bd9Sstevel@tonic-gate return (NULL); 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate #ifdef DEBUG 5307c478bd9Sstevel@tonic-gate if (!do_xdrmblk_inline) { 5317c478bd9Sstevel@tonic-gate xdrmblk_inline_misses++; 5327c478bd9Sstevel@tonic-gate return (NULL); 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate #endif 5357c478bd9Sstevel@tonic-gate 536*cf98b944SMarcel Telka if (xdrs->x_op == XDR_DECODE) 537*cf98b944SMarcel Telka xdrmblk_skip_fully_read_mblks(xdrs); 538*cf98b944SMarcel Telka 539*cf98b944SMarcel Telka /* 540*cf98b944SMarcel Telka * Can't inline if there isn't enough room. 541*cf98b944SMarcel Telka */ 542*cf98b944SMarcel Telka if (len <= 0 || xdrs->x_handy < len) { 543*cf98b944SMarcel Telka #ifdef DEBUG 544*cf98b944SMarcel Telka xdrmblk_inline_misses++; 545*cf98b944SMarcel Telka #endif 546*cf98b944SMarcel Telka return (NULL); 547*cf98b944SMarcel Telka } 548*cf98b944SMarcel Telka 549*cf98b944SMarcel Telka /* LINTED pointer alignment */ 550*cf98b944SMarcel Telka m = (mblk_t *)xdrs->x_base; 551*cf98b944SMarcel Telka ASSERT(m != NULL); 552*cf98b944SMarcel Telka 5537c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) { 5547c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 555*cf98b944SMarcel Telka mptr = &m->b_rptr; 5567c478bd9Sstevel@tonic-gate } else { 5577c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 558*cf98b944SMarcel Telka mptr = &m->b_wptr; 5597c478bd9Sstevel@tonic-gate } 560*cf98b944SMarcel Telka 561*cf98b944SMarcel Telka /* 562*cf98b944SMarcel Telka * Can't inline if the buffer is not 4 byte aligned, or if there is 563*cf98b944SMarcel Telka * more than one reference to the data block associated with this mblk. 564*cf98b944SMarcel Telka * This last check is used because the caller may want to modify the 565*cf98b944SMarcel Telka * data in the inlined portion and someone else is holding a reference 566*cf98b944SMarcel Telka * to the data who may not want it to be modified. 567*cf98b944SMarcel Telka */ 568*cf98b944SMarcel Telka if (!IS_P2ALIGNED(*mptr, sizeof (int32_t)) || 569*cf98b944SMarcel Telka m->b_datap->db_ref != 1) { 570*cf98b944SMarcel Telka #ifdef DEBUG 571*cf98b944SMarcel Telka xdrmblk_inline_misses++; 572*cf98b944SMarcel Telka #endif 573*cf98b944SMarcel Telka return (NULL); 574*cf98b944SMarcel Telka } 575*cf98b944SMarcel Telka 576*cf98b944SMarcel Telka buf = (rpc_inline_t *)*mptr; 577*cf98b944SMarcel Telka 578*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 579*cf98b944SMarcel Telka 580*cf98b944SMarcel Telka *mptr += len; 581*cf98b944SMarcel Telka xdrs->x_handy -= len; 582*cf98b944SMarcel Telka p->rpos += len; 583*cf98b944SMarcel Telka 5847c478bd9Sstevel@tonic-gate #ifdef DEBUG 5857c478bd9Sstevel@tonic-gate xdrmblk_inline_hits++; 5867c478bd9Sstevel@tonic-gate #endif 587*cf98b944SMarcel Telka 5887c478bd9Sstevel@tonic-gate return (buf); 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate static bool_t 5927c478bd9Sstevel@tonic-gate xdrmblk_control(XDR *xdrs, int request, void *info) 5937c478bd9Sstevel@tonic-gate { 5947c478bd9Sstevel@tonic-gate mblk_t *m; 595*cf98b944SMarcel Telka struct xdrmblk_params *p; 5967c478bd9Sstevel@tonic-gate int32_t *int32p; 5977c478bd9Sstevel@tonic-gate int len; 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate switch (request) { 6007c478bd9Sstevel@tonic-gate case XDR_PEEK: 601*cf98b944SMarcel Telka xdrmblk_skip_fully_read_mblks(xdrs); 602*cf98b944SMarcel Telka 6037c478bd9Sstevel@tonic-gate /* 6047c478bd9Sstevel@tonic-gate * Return the next 4 byte unit in the XDR stream. 6057c478bd9Sstevel@tonic-gate */ 6067c478bd9Sstevel@tonic-gate if (xdrs->x_handy < sizeof (int32_t)) 6077c478bd9Sstevel@tonic-gate return (FALSE); 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 6107c478bd9Sstevel@tonic-gate m = (mblk_t *)xdrs->x_base; 611*cf98b944SMarcel Telka ASSERT(m != NULL); 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate /* 6147c478bd9Sstevel@tonic-gate * If the pointer is not aligned, fail the peek 6157c478bd9Sstevel@tonic-gate */ 6167c478bd9Sstevel@tonic-gate if (!IS_P2ALIGNED(m->b_rptr, sizeof (int32_t))) 6177c478bd9Sstevel@tonic-gate return (FALSE); 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate int32p = (int32_t *)info; 6207c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 6217c478bd9Sstevel@tonic-gate *int32p = ntohl(*((int32_t *)(m->b_rptr))); 6227c478bd9Sstevel@tonic-gate return (TRUE); 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate case XDR_SKIPBYTES: 6257c478bd9Sstevel@tonic-gate int32p = (int32_t *)info; 6267c478bd9Sstevel@tonic-gate len = RNDUP((int)(*int32p)); 627742e7b7fSmaheshvs if (len < 0) 628742e7b7fSmaheshvs return (FALSE); 629*cf98b944SMarcel Telka if (len == 0) 630*cf98b944SMarcel Telka return (TRUE); 631*cf98b944SMarcel Telka 632*cf98b944SMarcel Telka /* LINTED pointer alignment */ 633*cf98b944SMarcel Telka m = (mblk_t *)xdrs->x_base; 634*cf98b944SMarcel Telka if (m == NULL) 635*cf98b944SMarcel Telka return (FALSE); 636*cf98b944SMarcel Telka 637*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 638*cf98b944SMarcel Telka 639*cf98b944SMarcel Telka while (xdrs->x_handy < len) { 640*cf98b944SMarcel Telka if (xdrs->x_handy > 0) { 6417c478bd9Sstevel@tonic-gate m->b_rptr += xdrs->x_handy; 6427c478bd9Sstevel@tonic-gate len -= xdrs->x_handy; 643*cf98b944SMarcel Telka p->rpos += xdrs->x_handy; 6447c478bd9Sstevel@tonic-gate } 6457c478bd9Sstevel@tonic-gate m = m->b_cont; 6467c478bd9Sstevel@tonic-gate xdrs->x_base = (caddr_t)m; 647*cf98b944SMarcel Telka p->apos += p->rpos; 648*cf98b944SMarcel Telka p->rpos = 0; 6497c478bd9Sstevel@tonic-gate if (m == NULL) { 6507c478bd9Sstevel@tonic-gate xdrs->x_handy = 0; 6517c478bd9Sstevel@tonic-gate return (FALSE); 6527c478bd9Sstevel@tonic-gate } 653*cf98b944SMarcel Telka xdrs->x_handy = (int)MBLKL(m); 6547c478bd9Sstevel@tonic-gate } 655*cf98b944SMarcel Telka 656*cf98b944SMarcel Telka xdrs->x_handy -= len; 657*cf98b944SMarcel Telka p->rpos += len; 6587c478bd9Sstevel@tonic-gate m->b_rptr += len; 6597c478bd9Sstevel@tonic-gate return (TRUE); 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate default: 6627c478bd9Sstevel@tonic-gate return (FALSE); 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate } 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate #define HDR_SPACE 128 6677c478bd9Sstevel@tonic-gate 6687c478bd9Sstevel@tonic-gate static mblk_t * 6697c478bd9Sstevel@tonic-gate xdrmblk_alloc(int sz) 6707c478bd9Sstevel@tonic-gate { 6717c478bd9Sstevel@tonic-gate mblk_t *mp; 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate if (sz == 0) 6747c478bd9Sstevel@tonic-gate return (NULL); 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate /* 6777c478bd9Sstevel@tonic-gate * Pad the front of the message to allow the lower networking 6787c478bd9Sstevel@tonic-gate * layers space to add headers as needed. 6797c478bd9Sstevel@tonic-gate */ 6807c478bd9Sstevel@tonic-gate sz += HDR_SPACE; 6817c478bd9Sstevel@tonic-gate 6827c478bd9Sstevel@tonic-gate while ((mp = allocb(sz, BPRI_LO)) == NULL) { 6837c478bd9Sstevel@tonic-gate if (strwaitbuf(sz, BPRI_LO)) 6847c478bd9Sstevel@tonic-gate return (NULL); 6857c478bd9Sstevel@tonic-gate } 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate mp->b_wptr += HDR_SPACE; 6887c478bd9Sstevel@tonic-gate mp->b_rptr = mp->b_wptr; 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate return (mp); 6917c478bd9Sstevel@tonic-gate } 692*cf98b944SMarcel Telka 693*cf98b944SMarcel Telka /* 694*cf98b944SMarcel Telka * Skip fully read or empty mblks 695*cf98b944SMarcel Telka */ 696*cf98b944SMarcel Telka static void 697*cf98b944SMarcel Telka xdrmblk_skip_fully_read_mblks(XDR *xdrs) 698*cf98b944SMarcel Telka { 699*cf98b944SMarcel Telka mblk_t *m; 700*cf98b944SMarcel Telka struct xdrmblk_params *p; 701*cf98b944SMarcel Telka 702*cf98b944SMarcel Telka if (xdrs->x_handy != 0) 703*cf98b944SMarcel Telka return; 704*cf98b944SMarcel Telka 705*cf98b944SMarcel Telka /* LINTED pointer alignment */ 706*cf98b944SMarcel Telka m = (mblk_t *)xdrs->x_base; 707*cf98b944SMarcel Telka if (m == NULL) 708*cf98b944SMarcel Telka return; 709*cf98b944SMarcel Telka 710*cf98b944SMarcel Telka p = (struct xdrmblk_params *)xdrs->x_private; 711*cf98b944SMarcel Telka p->apos += p->rpos; 712*cf98b944SMarcel Telka p->rpos = 0; 713*cf98b944SMarcel Telka 714*cf98b944SMarcel Telka do { 715*cf98b944SMarcel Telka m = m->b_cont; 716*cf98b944SMarcel Telka if (m == NULL) 717*cf98b944SMarcel Telka break; 718*cf98b944SMarcel Telka 719*cf98b944SMarcel Telka xdrs->x_handy = (int)MBLKL(m); 720*cf98b944SMarcel Telka } while (xdrs->x_handy == 0); 721*cf98b944SMarcel Telka 722*cf98b944SMarcel Telka xdrs->x_base = (caddr_t)m; 723*cf98b944SMarcel Telka } 724