xref: /illumos-gate/usr/src/uts/common/fs/nfs/nfs_xdr.c (revision ed629aef)
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
50a701b1eSRobert Gordon  * Common Development and Distribution License (the "License").
60a701b1eSRobert Gordon  * 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  */
217c478bd9Sstevel@tonic-gate /*
22f837ee4aSSiddheshwar Mahesh  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
277c478bd9Sstevel@tonic-gate /* All Rights Reserved */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/param.h>
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/systm.h>
327c478bd9Sstevel@tonic-gate #include <sys/user.h>
337c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
347c478bd9Sstevel@tonic-gate #include <sys/file.h>
357c478bd9Sstevel@tonic-gate #include <sys/dirent.h>
367c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
377c478bd9Sstevel@tonic-gate #include <sys/stream.h>
387c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
397c478bd9Sstevel@tonic-gate #include <sys/debug.h>
407c478bd9Sstevel@tonic-gate #include <sys/t_lock.h>
410a701b1eSRobert Gordon #include <sys/sdt.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #include <rpc/types.h>
447c478bd9Sstevel@tonic-gate #include <rpc/xdr.h>
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #include <nfs/nfs.h>
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate #include <vm/hat.h>
497c478bd9Sstevel@tonic-gate #include <vm/as.h>
507c478bd9Sstevel@tonic-gate #include <vm/seg.h>
517c478bd9Sstevel@tonic-gate #include <vm/seg_map.h>
527c478bd9Sstevel@tonic-gate #include <vm/seg_kmem.h>
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate static bool_t xdr_fastshorten(XDR *, uint_t);
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate /*
577c478bd9Sstevel@tonic-gate  * These are the XDR routines used to serialize and deserialize
587c478bd9Sstevel@tonic-gate  * the various structures passed as parameters accross the network
597c478bd9Sstevel@tonic-gate  * between NFS clients and servers.
607c478bd9Sstevel@tonic-gate  */
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate /*
637c478bd9Sstevel@tonic-gate  * File access handle
647c478bd9Sstevel@tonic-gate  * The fhandle struct is treated a opaque data on the wire
657c478bd9Sstevel@tonic-gate  */
667c478bd9Sstevel@tonic-gate bool_t
xdr_fhandle(XDR * xdrs,fhandle_t * fh)677c478bd9Sstevel@tonic-gate xdr_fhandle(XDR *xdrs, fhandle_t *fh)
687c478bd9Sstevel@tonic-gate {
697c478bd9Sstevel@tonic-gate 	int32_t *ptr;
707c478bd9Sstevel@tonic-gate 	int32_t *fhp;
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
737c478bd9Sstevel@tonic-gate 		return (TRUE);
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)));
767c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
777c478bd9Sstevel@tonic-gate 		fhp = (int32_t *)fh;
787c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
797c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
807c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
817c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
827c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
837c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
847c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
857c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
867c478bd9Sstevel@tonic-gate 			*fhp = *ptr;
877c478bd9Sstevel@tonic-gate 		} else {
887c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
897c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
907c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
917c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
927c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
937c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
947c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
957c478bd9Sstevel@tonic-gate 			*ptr = *fhp;
967c478bd9Sstevel@tonic-gate 		}
977c478bd9Sstevel@tonic-gate 		return (TRUE);
987c478bd9Sstevel@tonic-gate 	}
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, (caddr_t)fh, NFS_FHSIZE));
1017c478bd9Sstevel@tonic-gate }
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate bool_t
xdr_fastfhandle(XDR * xdrs,fhandle_t ** fh)1047c478bd9Sstevel@tonic-gate xdr_fastfhandle(XDR *xdrs, fhandle_t **fh)
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate 	int32_t *ptr;
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
1097c478bd9Sstevel@tonic-gate 		return (FALSE);
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)));
1127c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
1137c478bd9Sstevel@tonic-gate 		*fh = (fhandle_t *)ptr;
1147c478bd9Sstevel@tonic-gate 		return (TRUE);
1157c478bd9Sstevel@tonic-gate 	}
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	return (FALSE);
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate /*
1217c478bd9Sstevel@tonic-gate  * Arguments to remote write and writecache
1227c478bd9Sstevel@tonic-gate  */
1237c478bd9Sstevel@tonic-gate bool_t
xdr_writeargs(XDR * xdrs,struct nfswriteargs * wa)1247c478bd9Sstevel@tonic-gate xdr_writeargs(XDR *xdrs, struct nfswriteargs *wa)
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate 	int32_t *ptr;
1277c478bd9Sstevel@tonic-gate 	int32_t *fhp;
1287c478bd9Sstevel@tonic-gate 
1290a701b1eSRobert Gordon 	switch (xdrs->x_op) {
1300a701b1eSRobert Gordon 	case XDR_DECODE:
1317c478bd9Sstevel@tonic-gate 		wa->wa_args = &wa->wa_args_buf;
1327c478bd9Sstevel@tonic-gate 		ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
1337c478bd9Sstevel@tonic-gate 		    3 * BYTES_PER_XDR_UNIT);
1347c478bd9Sstevel@tonic-gate 		if (ptr != NULL) {
1357c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)&wa->wa_fhandle;
1367c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
1377c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
1387c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
1397c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
1407c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
1417c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
1427c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
1437c478bd9Sstevel@tonic-gate 			*fhp = *ptr++;
1447c478bd9Sstevel@tonic-gate 			wa->wa_begoff = IXDR_GET_U_INT32(ptr);
1457c478bd9Sstevel@tonic-gate 			wa->wa_offset = IXDR_GET_U_INT32(ptr);
1467c478bd9Sstevel@tonic-gate 			wa->wa_totcount = IXDR_GET_U_INT32(ptr);
147*ed629aefSSiddheshwar Mahesh 			wa->wa_mblk = NULL;
148*ed629aefSSiddheshwar Mahesh 			wa->wa_data = NULL;
149*ed629aefSSiddheshwar Mahesh 			wa->wa_rlist = NULL;
150*ed629aefSSiddheshwar Mahesh 			wa->wa_conn = NULL;
151*ed629aefSSiddheshwar Mahesh 			if (xdrs->x_ops == &xdrmblk_ops) {
1527c478bd9Sstevel@tonic-gate 				return (xdrmblk_getmblk(xdrs, &wa->wa_mblk,
1537c478bd9Sstevel@tonic-gate 				    &wa->wa_count));
154*ed629aefSSiddheshwar Mahesh 			} else {
155*ed629aefSSiddheshwar Mahesh 				if (xdrs->x_ops == &xdrrdmablk_ops) {
156*ed629aefSSiddheshwar Mahesh 					if (xdrrdma_getrdmablk(xdrs,
157*ed629aefSSiddheshwar Mahesh 					    &wa->wa_rlist,
158*ed629aefSSiddheshwar Mahesh 					    &wa->wa_count,
159*ed629aefSSiddheshwar Mahesh 					    &wa->wa_conn,
160*ed629aefSSiddheshwar Mahesh 					    NFS_MAXDATA) == TRUE)
161*ed629aefSSiddheshwar Mahesh 					return (xdrrdma_read_from_client(
162*ed629aefSSiddheshwar Mahesh 					    wa->wa_rlist,
163*ed629aefSSiddheshwar Mahesh 					    &wa->wa_conn,
164*ed629aefSSiddheshwar Mahesh 					    wa->wa_count));
165*ed629aefSSiddheshwar Mahesh 
166*ed629aefSSiddheshwar Mahesh 					wa->wa_rlist = NULL;
167*ed629aefSSiddheshwar Mahesh 					wa->wa_conn = NULL;
168*ed629aefSSiddheshwar Mahesh 				}
169*ed629aefSSiddheshwar Mahesh 			}
170*ed629aefSSiddheshwar Mahesh 
1717c478bd9Sstevel@tonic-gate 			/*
1727c478bd9Sstevel@tonic-gate 			 * It is just as efficient to xdr_bytes
1737c478bd9Sstevel@tonic-gate 			 * an array of unknown length as to inline copy it.
1747c478bd9Sstevel@tonic-gate 			 */
1757c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, &wa->wa_data,
1760a701b1eSRobert Gordon 			    &wa->wa_count, NFS_MAXDATA));
1777c478bd9Sstevel@tonic-gate 		}
1780a701b1eSRobert Gordon 		if (xdr_fhandle(xdrs, &wa->wa_fhandle) &&
1790a701b1eSRobert Gordon 		    xdr_u_int(xdrs, &wa->wa_begoff) &&
1800a701b1eSRobert Gordon 		    xdr_u_int(xdrs, &wa->wa_offset) &&
1810a701b1eSRobert Gordon 		    xdr_u_int(xdrs, &wa->wa_totcount)) {
1820a701b1eSRobert Gordon 			/* deal with the variety of data transfer types */
1837c478bd9Sstevel@tonic-gate 
1840a701b1eSRobert Gordon 			wa->wa_mblk = NULL;
1850a701b1eSRobert Gordon 			wa->wa_data = NULL;
1860a701b1eSRobert Gordon 			wa->wa_rlist = NULL;
1870a701b1eSRobert Gordon 			wa->wa_conn = NULL;
1880a701b1eSRobert Gordon 
1890a701b1eSRobert Gordon 			if (xdrs->x_ops == &xdrmblk_ops) {
1900a701b1eSRobert Gordon 				if (xdrmblk_getmblk(xdrs, &wa->wa_mblk,
1910a701b1eSRobert Gordon 				    &wa->wa_count) == TRUE)
1920a701b1eSRobert Gordon 					return (TRUE);
1930a701b1eSRobert Gordon 			} else {
1940a701b1eSRobert Gordon 				if (xdrs->x_ops == &xdrrdmablk_ops) {
1950a701b1eSRobert Gordon 					if (xdrrdma_getrdmablk(xdrs,
1960a701b1eSRobert Gordon 					    &wa->wa_rlist,
1970a701b1eSRobert Gordon 					    &wa->wa_count,
1980a701b1eSRobert Gordon 					    &wa->wa_conn,
1990a701b1eSRobert Gordon 					    NFS_MAXDATA) == TRUE)
2000a701b1eSRobert Gordon 					return (xdrrdma_read_from_client(
201f837ee4aSSiddheshwar Mahesh 					    wa->wa_rlist,
2020a701b1eSRobert Gordon 					    &wa->wa_conn,
2030a701b1eSRobert Gordon 					    wa->wa_count));
2040a701b1eSRobert Gordon 
2050a701b1eSRobert Gordon 					wa->wa_rlist = NULL;
2060a701b1eSRobert Gordon 					wa->wa_conn = NULL;
2070a701b1eSRobert Gordon 				}
2080a701b1eSRobert Gordon 			}
2090a701b1eSRobert Gordon 			return (xdr_bytes(xdrs, &wa->wa_data,
2100a701b1eSRobert Gordon 			    &wa->wa_count, NFS_MAXDATA));
2110a701b1eSRobert Gordon 		}
2120a701b1eSRobert Gordon 		return (FALSE);
2130a701b1eSRobert Gordon 	case XDR_ENCODE:
2147c478bd9Sstevel@tonic-gate 		ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
2157c478bd9Sstevel@tonic-gate 		    3 * BYTES_PER_XDR_UNIT);
2167c478bd9Sstevel@tonic-gate 		if (ptr != NULL) {
2177c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)&wa->wa_fhandle;
2187c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
2197c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
2207c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
2217c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
2227c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
2237c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
2247c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
2257c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp;
2267c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, wa->wa_begoff);
2277c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, wa->wa_offset);
2287c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, wa->wa_totcount);
2297c478bd9Sstevel@tonic-gate 		} else {
2307c478bd9Sstevel@tonic-gate 			if (!(xdr_fhandle(xdrs, &wa->wa_fhandle) &&
2317c478bd9Sstevel@tonic-gate 			    xdr_u_int(xdrs, &wa->wa_begoff) &&
2327c478bd9Sstevel@tonic-gate 			    xdr_u_int(xdrs, &wa->wa_offset) &&
2337c478bd9Sstevel@tonic-gate 			    xdr_u_int(xdrs, &wa->wa_totcount)))
2347c478bd9Sstevel@tonic-gate 				return (FALSE);
2357c478bd9Sstevel@tonic-gate 		}
2360a701b1eSRobert Gordon 
2377c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, &wa->wa_data, &wa->wa_count,
2387c478bd9Sstevel@tonic-gate 		    NFS_MAXDATA));
2390a701b1eSRobert Gordon 	case XDR_FREE:
2400a701b1eSRobert Gordon 		if (wa->wa_rlist) {
2410a701b1eSRobert Gordon 			(void) xdrrdma_free_clist(wa->wa_conn, wa->wa_rlist);
2420a701b1eSRobert Gordon 			wa->wa_rlist = NULL;
2430a701b1eSRobert Gordon 		}
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 		if (wa->wa_data != NULL) {
2467c478bd9Sstevel@tonic-gate 			kmem_free(wa->wa_data, wa->wa_count);
2477c478bd9Sstevel@tonic-gate 			wa->wa_data = NULL;
2487c478bd9Sstevel@tonic-gate 		}
2497c478bd9Sstevel@tonic-gate 		return (TRUE);
2507c478bd9Sstevel@tonic-gate 	}
2517c478bd9Sstevel@tonic-gate 	return (FALSE);
2527c478bd9Sstevel@tonic-gate }
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate /*
2567c478bd9Sstevel@tonic-gate  * File attributes
2577c478bd9Sstevel@tonic-gate  */
2587c478bd9Sstevel@tonic-gate bool_t
xdr_fattr(XDR * xdrs,struct nfsfattr * na)2597c478bd9Sstevel@tonic-gate xdr_fattr(XDR *xdrs, struct nfsfattr *na)
2607c478bd9Sstevel@tonic-gate {
2617c478bd9Sstevel@tonic-gate 	int32_t *ptr;
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
2647c478bd9Sstevel@tonic-gate 		return (TRUE);
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs, 17 * BYTES_PER_XDR_UNIT);
2677c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
2687c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
2697c478bd9Sstevel@tonic-gate 			na->na_type = IXDR_GET_ENUM(ptr, enum nfsftype);
2707c478bd9Sstevel@tonic-gate 			na->na_mode = IXDR_GET_U_INT32(ptr);
2717c478bd9Sstevel@tonic-gate 			na->na_nlink = IXDR_GET_U_INT32(ptr);
2727c478bd9Sstevel@tonic-gate 			na->na_uid = IXDR_GET_U_INT32(ptr);
2737c478bd9Sstevel@tonic-gate 			na->na_gid = IXDR_GET_U_INT32(ptr);
2747c478bd9Sstevel@tonic-gate 			na->na_size = IXDR_GET_U_INT32(ptr);
2757c478bd9Sstevel@tonic-gate 			na->na_blocksize = IXDR_GET_U_INT32(ptr);
2767c478bd9Sstevel@tonic-gate 			na->na_rdev = IXDR_GET_U_INT32(ptr);
2777c478bd9Sstevel@tonic-gate 			na->na_blocks = IXDR_GET_U_INT32(ptr);
2787c478bd9Sstevel@tonic-gate 			na->na_fsid = IXDR_GET_U_INT32(ptr);
2797c478bd9Sstevel@tonic-gate 			na->na_nodeid = IXDR_GET_U_INT32(ptr);
2807c478bd9Sstevel@tonic-gate 			na->na_atime.tv_sec = IXDR_GET_U_INT32(ptr);
2817c478bd9Sstevel@tonic-gate 			na->na_atime.tv_usec = IXDR_GET_U_INT32(ptr);
2827c478bd9Sstevel@tonic-gate 			na->na_mtime.tv_sec = IXDR_GET_U_INT32(ptr);
2837c478bd9Sstevel@tonic-gate 			na->na_mtime.tv_usec = IXDR_GET_U_INT32(ptr);
2847c478bd9Sstevel@tonic-gate 			na->na_ctime.tv_sec = IXDR_GET_U_INT32(ptr);
2857c478bd9Sstevel@tonic-gate 			na->na_ctime.tv_usec = IXDR_GET_U_INT32(ptr);
2867c478bd9Sstevel@tonic-gate 		} else {
2877c478bd9Sstevel@tonic-gate 			IXDR_PUT_ENUM(ptr, na->na_type);
2887c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_mode);
2897c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_nlink);
2907c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_uid);
2917c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_gid);
2927c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_size);
2937c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_blocksize);
2947c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_rdev);
2957c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_blocks);
2967c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_fsid);
2977c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_nodeid);
2987c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_atime.tv_sec);
2997c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_atime.tv_usec);
3007c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_sec);
3017c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_usec);
3027c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_sec);
3037c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_usec);
3047c478bd9Sstevel@tonic-gate 		}
3057c478bd9Sstevel@tonic-gate 		return (TRUE);
3067c478bd9Sstevel@tonic-gate 	}
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	if (xdr_enum(xdrs, (enum_t *)&na->na_type) &&
3097c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_mode) &&
3107c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_nlink) &&
3117c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_uid) &&
3127c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_gid) &&
3137c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_size) &&
3147c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_blocksize) &&
3157c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_rdev) &&
3167c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_blocks) &&
3177c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_fsid) &&
3187c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->na_nodeid) &&
3197c478bd9Sstevel@tonic-gate 	    xdr_nfs2_timeval(xdrs, &na->na_atime) &&
3207c478bd9Sstevel@tonic-gate 	    xdr_nfs2_timeval(xdrs, &na->na_mtime) &&
3217c478bd9Sstevel@tonic-gate 	    xdr_nfs2_timeval(xdrs, &na->na_ctime)) {
3227c478bd9Sstevel@tonic-gate 		return (TRUE);
3237c478bd9Sstevel@tonic-gate 	}
3247c478bd9Sstevel@tonic-gate 	return (FALSE);
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
3287c478bd9Sstevel@tonic-gate bool_t
xdr_fastfattr(XDR * xdrs,struct nfsfattr * na)3297c478bd9Sstevel@tonic-gate xdr_fastfattr(XDR *xdrs, struct nfsfattr *na)
3307c478bd9Sstevel@tonic-gate {
3317c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
3327c478bd9Sstevel@tonic-gate 		return (TRUE);
3337c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
3347c478bd9Sstevel@tonic-gate 		return (FALSE);
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 	na->na_type = htonl(na->na_type);
3377c478bd9Sstevel@tonic-gate 	na->na_mode = htonl(na->na_mode);
3387c478bd9Sstevel@tonic-gate 	na->na_nlink = htonl(na->na_nlink);
3397c478bd9Sstevel@tonic-gate 	na->na_uid = htonl(na->na_uid);
3407c478bd9Sstevel@tonic-gate 	na->na_gid = htonl(na->na_gid);
3417c478bd9Sstevel@tonic-gate 	na->na_size = htonl(na->na_size);
3427c478bd9Sstevel@tonic-gate 	na->na_blocksize = htonl(na->na_blocksize);
3437c478bd9Sstevel@tonic-gate 	na->na_rdev = htonl(na->na_rdev);
3447c478bd9Sstevel@tonic-gate 	na->na_blocks = htonl(na->na_blocks);
3457c478bd9Sstevel@tonic-gate 	na->na_fsid = htonl(na->na_fsid);
3467c478bd9Sstevel@tonic-gate 	na->na_nodeid = htonl(na->na_nodeid);
3477c478bd9Sstevel@tonic-gate 	na->na_atime.tv_sec = htonl(na->na_atime.tv_sec);
3487c478bd9Sstevel@tonic-gate 	na->na_atime.tv_usec = htonl(na->na_atime.tv_usec);
3497c478bd9Sstevel@tonic-gate 	na->na_mtime.tv_sec = htonl(na->na_mtime.tv_sec);
3507c478bd9Sstevel@tonic-gate 	na->na_mtime.tv_usec = htonl(na->na_mtime.tv_usec);
3517c478bd9Sstevel@tonic-gate 	na->na_ctime.tv_sec = htonl(na->na_ctime.tv_sec);
3527c478bd9Sstevel@tonic-gate 	na->na_ctime.tv_usec = htonl(na->na_ctime.tv_usec);
3537c478bd9Sstevel@tonic-gate 	return (TRUE);
3547c478bd9Sstevel@tonic-gate }
3557c478bd9Sstevel@tonic-gate #endif
3567c478bd9Sstevel@tonic-gate 
3570a701b1eSRobert Gordon bool_t
xdr_readlink(XDR * xdrs,fhandle_t * fh)3580a701b1eSRobert Gordon xdr_readlink(XDR *xdrs, fhandle_t *fh)
3590a701b1eSRobert Gordon {
3600a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
3610a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
3620a701b1eSRobert Gordon 
3630a701b1eSRobert Gordon 	if (xdr_fhandle(xdrs, fh)) {
3640a701b1eSRobert Gordon 		if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
3650a701b1eSRobert Gordon 		    xdrs->x_op == XDR_ENCODE) {
3660a701b1eSRobert Gordon 			rci.rci_type = RCI_REPLY_CHUNK;
3670a701b1eSRobert Gordon 			rci.rci_len = MAXPATHLEN;
3680a701b1eSRobert Gordon 			XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
3690a701b1eSRobert Gordon 		}
3700a701b1eSRobert Gordon 
3710a701b1eSRobert Gordon 		return (TRUE);
3720a701b1eSRobert Gordon 	}
3730a701b1eSRobert Gordon 	return (FALSE);
3740a701b1eSRobert Gordon }
3750a701b1eSRobert Gordon 
3767c478bd9Sstevel@tonic-gate /*
3777c478bd9Sstevel@tonic-gate  * Arguments to remote read
3787c478bd9Sstevel@tonic-gate  */
3797c478bd9Sstevel@tonic-gate bool_t
xdr_readargs(XDR * xdrs,struct nfsreadargs * ra)3807c478bd9Sstevel@tonic-gate xdr_readargs(XDR *xdrs, struct nfsreadargs *ra)
3817c478bd9Sstevel@tonic-gate {
3827c478bd9Sstevel@tonic-gate 	int32_t *ptr;
3837c478bd9Sstevel@tonic-gate 	int32_t *fhp;
3840a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
3850a701b1eSRobert Gordon 	rdma_wlist_conn_info_t rwci;
3860a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
3897c478bd9Sstevel@tonic-gate 		return (TRUE);
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs,
3920a701b1eSRobert Gordon 	    RNDUP(sizeof (fhandle_t)) + 3 * BYTES_PER_XDR_UNIT);
3937c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
3947c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
3957c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)&ra->ra_fhandle;
3967c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
3977c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
3987c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
3997c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
4007c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
4017c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
4027c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
4037c478bd9Sstevel@tonic-gate 			*fhp = *ptr++;
4047c478bd9Sstevel@tonic-gate 			ra->ra_offset = IXDR_GET_INT32(ptr);
4057c478bd9Sstevel@tonic-gate 			ra->ra_count = IXDR_GET_INT32(ptr);
4067c478bd9Sstevel@tonic-gate 			ra->ra_totcount = IXDR_GET_INT32(ptr);
4077c478bd9Sstevel@tonic-gate 		} else {
4087c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)&ra->ra_fhandle;
4097c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
4107c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
4117c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
4127c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
4137c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
4147c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
4157c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
4167c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp;
4177c478bd9Sstevel@tonic-gate 			IXDR_PUT_INT32(ptr, ra->ra_offset);
4187c478bd9Sstevel@tonic-gate 			IXDR_PUT_INT32(ptr, ra->ra_count);
4197c478bd9Sstevel@tonic-gate 			IXDR_PUT_INT32(ptr, ra->ra_totcount);
4207c478bd9Sstevel@tonic-gate 		}
4210a701b1eSRobert Gordon 	} else {
4220a701b1eSRobert Gordon 		if (!xdr_fhandle(xdrs, &ra->ra_fhandle) ||
4230a701b1eSRobert Gordon 		    !xdr_u_int(xdrs, &ra->ra_offset) ||
4240a701b1eSRobert Gordon 		    !xdr_u_int(xdrs, &ra->ra_count) ||
4250a701b1eSRobert Gordon 		    !xdr_u_int(xdrs, &ra->ra_totcount)) {
4267c478bd9Sstevel@tonic-gate 			return (FALSE);
4270a701b1eSRobert Gordon 		}
4287c478bd9Sstevel@tonic-gate 	}
4297c478bd9Sstevel@tonic-gate 
4300a701b1eSRobert Gordon 	if (ra->ra_count > NFS_MAXDATA)
4310a701b1eSRobert Gordon 		return (FALSE);
4320a701b1eSRobert Gordon 
4330a701b1eSRobert Gordon 	ra->ra_wlist = NULL;
4340a701b1eSRobert Gordon 	ra->ra_conn = NULL;
4350a701b1eSRobert Gordon 
4360a701b1eSRobert Gordon 	/* If this is xdrrdma_sizeof, record the expect response size */
4370a701b1eSRobert Gordon 	if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
4380a701b1eSRobert Gordon 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
4390a701b1eSRobert Gordon 		rci.rci_len = ra->ra_count;
4400a701b1eSRobert Gordon 		(void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
4410a701b1eSRobert Gordon 	}
4420a701b1eSRobert Gordon 	/* Nothing special to do, return */
4430a701b1eSRobert Gordon 	if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
4447c478bd9Sstevel@tonic-gate 		return (TRUE);
4450a701b1eSRobert Gordon 
4460a701b1eSRobert Gordon 	if (xdrs->x_op == XDR_ENCODE) {
4470a701b1eSRobert Gordon 		/* Place the target data location into the RDMA header */
4480a701b1eSRobert Gordon 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
4490a701b1eSRobert Gordon 		rci.rci_a.rci_addr = ra->ra_data;
4500a701b1eSRobert Gordon 		rci.rci_len = ra->ra_count;
4510a701b1eSRobert Gordon 		rci.rci_clpp = &ra->ra_wlist;
4520a701b1eSRobert Gordon 
4530a701b1eSRobert Gordon 		return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
4547c478bd9Sstevel@tonic-gate 	}
4550a701b1eSRobert Gordon 
4560a701b1eSRobert Gordon 	/* XDR_DECODE case */
4570a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
4580a701b1eSRobert Gordon 	ra->ra_wlist = rwci.rwci_wlist;
4590a701b1eSRobert Gordon 	ra->ra_conn = rwci.rwci_conn;
4600a701b1eSRobert Gordon 
4610a701b1eSRobert Gordon 	return (TRUE);
4627c478bd9Sstevel@tonic-gate }
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate /*
4667c478bd9Sstevel@tonic-gate  * Status OK portion of remote read reply
4677c478bd9Sstevel@tonic-gate  */
4687c478bd9Sstevel@tonic-gate bool_t
xdr_rrok(XDR * xdrs,struct nfsrrok * rrok)4697c478bd9Sstevel@tonic-gate xdr_rrok(XDR *xdrs, struct nfsrrok *rrok)
4707c478bd9Sstevel@tonic-gate {
4717c478bd9Sstevel@tonic-gate 	bool_t ret;
4727c478bd9Sstevel@tonic-gate 	mblk_t *mp;
4730a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate 	if (xdr_fattr(xdrs, &rrok->rrok_attr) == FALSE)
4767c478bd9Sstevel@tonic-gate 		return (FALSE);
4777c478bd9Sstevel@tonic-gate 
4780a701b1eSRobert Gordon 	/* deal with RDMA separately */
4790a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) {
4800a701b1eSRobert Gordon 		if (xdrs->x_op == XDR_ENCODE &&
4810a701b1eSRobert Gordon 		    rrok->rrok_mp != NULL) {
4820a701b1eSRobert Gordon 			ret = xdr_bytes(xdrs, (char **)&rrok->rrok_data,
4830a701b1eSRobert Gordon 			    &rrok->rrok_count, NFS_MAXDATA);
4840a701b1eSRobert Gordon 			return (ret);
4850a701b1eSRobert Gordon 		}
4860a701b1eSRobert Gordon 
4870a701b1eSRobert Gordon 		if (xdrs->x_op == XDR_ENCODE) {
4880a701b1eSRobert Gordon 			if (xdr_u_int(xdrs, &rrok->rrok_count) == FALSE) {
4890a701b1eSRobert Gordon 				return (FALSE);
4900a701b1eSRobert Gordon 			}
4910a701b1eSRobert Gordon 			/*
4920a701b1eSRobert Gordon 			 * If read data sent by wlist (RDMA_WRITE), don't do
4930a701b1eSRobert Gordon 			 * xdr_bytes() below.   RDMA_WRITE transfers the data.
4940a701b1eSRobert Gordon 			 */
4950a701b1eSRobert Gordon 			if (rrok->rrok_wlist) {
4960a701b1eSRobert Gordon 				if (rrok->rrok_count != 0) {
4970a701b1eSRobert Gordon 					return (xdrrdma_send_read_data(
498f837ee4aSSiddheshwar Mahesh 					    xdrs, rrok->rrok_count,
499f837ee4aSSiddheshwar Mahesh 					    rrok->rrok_wlist));
5000a701b1eSRobert Gordon 				}
5010a701b1eSRobert Gordon 				return (TRUE);
5020a701b1eSRobert Gordon 			}
5030a701b1eSRobert Gordon 			if (rrok->rrok_count == 0) {
5040a701b1eSRobert Gordon 				return (TRUE);
5050a701b1eSRobert Gordon 			}
5060a701b1eSRobert Gordon 		} else {
5070a701b1eSRobert Gordon 			struct clist *cl;
5080a701b1eSRobert Gordon 			uint32_t count;
5090a701b1eSRobert Gordon 
5100a701b1eSRobert Gordon 			XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
5110a701b1eSRobert Gordon 
5120a701b1eSRobert Gordon 			if (cl) {
5130a701b1eSRobert Gordon 				if (!xdr_u_int(xdrs, &count))
5140a701b1eSRobert Gordon 					return (FALSE);
5150a701b1eSRobert Gordon 				if (count == 0) {
5160a701b1eSRobert Gordon 					rrok->rrok_wlist_len = 0;
5170a701b1eSRobert Gordon 					rrok->rrok_count = 0;
5180a701b1eSRobert Gordon 				} else {
519f837ee4aSSiddheshwar Mahesh 					rrok->rrok_wlist_len = clist_len(cl);
520f837ee4aSSiddheshwar Mahesh 					if (rrok->rrok_wlist_len !=
521f837ee4aSSiddheshwar Mahesh 					    roundup(count,
522f837ee4aSSiddheshwar Mahesh 					    BYTES_PER_XDR_UNIT)) {
523f837ee4aSSiddheshwar Mahesh 						rrok->rrok_wlist_len = 0;
524f837ee4aSSiddheshwar Mahesh 						rrok->rrok_count = 0;
525f837ee4aSSiddheshwar Mahesh 						return (FALSE);
526f837ee4aSSiddheshwar Mahesh 					}
527f837ee4aSSiddheshwar Mahesh 					rrok->rrok_count = count;
5280a701b1eSRobert Gordon 				}
5290a701b1eSRobert Gordon 				return (TRUE);
5300a701b1eSRobert Gordon 			}
5310a701b1eSRobert Gordon 		}
5320a701b1eSRobert Gordon 		ret = xdr_bytes(xdrs, (char **)&rrok->rrok_data,
5330a701b1eSRobert Gordon 		    &rrok->rrok_count, NFS_MAXDATA);
5340a701b1eSRobert Gordon 
5350a701b1eSRobert Gordon 		return (ret);
5360a701b1eSRobert Gordon 	}
5370a701b1eSRobert Gordon 
5387c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
5397c478bd9Sstevel@tonic-gate 		int i, rndup;
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate 		mp = rrok->rrok_mp;
5427c478bd9Sstevel@tonic-gate 		if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
5437c478bd9Sstevel@tonic-gate 			mp->b_wptr += rrok->rrok_count;
5447c478bd9Sstevel@tonic-gate 			rndup = BYTES_PER_XDR_UNIT -
5450a701b1eSRobert Gordon 			    (rrok->rrok_count % BYTES_PER_XDR_UNIT);
5467c478bd9Sstevel@tonic-gate 			if (rndup != BYTES_PER_XDR_UNIT)
5477c478bd9Sstevel@tonic-gate 				for (i = 0; i < rndup; i++)
5487c478bd9Sstevel@tonic-gate 					*mp->b_wptr++ = '\0';
5497c478bd9Sstevel@tonic-gate 			if (xdrmblk_putmblk(xdrs, mp,
5500a701b1eSRobert Gordon 			    rrok->rrok_count) == TRUE) {
5517c478bd9Sstevel@tonic-gate 				rrok->rrok_mp = NULL;
5527c478bd9Sstevel@tonic-gate 				return (TRUE);
5537c478bd9Sstevel@tonic-gate 			}
5547c478bd9Sstevel@tonic-gate 		}
5550a701b1eSRobert Gordon 
5567c478bd9Sstevel@tonic-gate 		/*
5577c478bd9Sstevel@tonic-gate 		 * Fall thru for the xdr_bytes()
5587c478bd9Sstevel@tonic-gate 		 *
5597c478bd9Sstevel@tonic-gate 		 * Note: the mblk mp will be freed in rfs_rdfree
5607c478bd9Sstevel@tonic-gate 		 */
5617c478bd9Sstevel@tonic-gate 	}
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 	ret = xdr_bytes(xdrs, (char **)&rrok->rrok_data,
5647c478bd9Sstevel@tonic-gate 	    &rrok->rrok_count, NFS_MAXDATA);
5657c478bd9Sstevel@tonic-gate 
5667c478bd9Sstevel@tonic-gate 	return (ret);
5677c478bd9Sstevel@tonic-gate }
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate static struct xdr_discrim rdres_discrim[2] = {
5707c478bd9Sstevel@tonic-gate 	{ NFS_OK, xdr_rrok },
5717c478bd9Sstevel@tonic-gate 	{ __dontcare__, NULL_xdrproc_t }
5727c478bd9Sstevel@tonic-gate };
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate /*
5757c478bd9Sstevel@tonic-gate  * Reply from remote read
5767c478bd9Sstevel@tonic-gate  */
5777c478bd9Sstevel@tonic-gate bool_t
xdr_rdresult(XDR * xdrs,struct nfsrdresult * rr)5787c478bd9Sstevel@tonic-gate xdr_rdresult(XDR *xdrs, struct nfsrdresult *rr)
5797c478bd9Sstevel@tonic-gate {
5807c478bd9Sstevel@tonic-gate 	return (xdr_union(xdrs, (enum_t *)&(rr->rr_status),
5817c478bd9Sstevel@tonic-gate 	    (caddr_t)&(rr->rr_ok), rdres_discrim, xdr_void));
5827c478bd9Sstevel@tonic-gate }
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate /*
5857c478bd9Sstevel@tonic-gate  * File attributes which can be set
5867c478bd9Sstevel@tonic-gate  */
5877c478bd9Sstevel@tonic-gate bool_t
xdr_sattr(XDR * xdrs,struct nfssattr * sa)5887c478bd9Sstevel@tonic-gate xdr_sattr(XDR *xdrs, struct nfssattr *sa)
5897c478bd9Sstevel@tonic-gate {
5907c478bd9Sstevel@tonic-gate 	if (xdr_u_int(xdrs, &sa->sa_mode) &&
5917c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &sa->sa_uid) &&
5927c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &sa->sa_gid) &&
5937c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &sa->sa_size) &&
5947c478bd9Sstevel@tonic-gate 	    xdr_nfs2_timeval(xdrs, &sa->sa_atime) &&
5957c478bd9Sstevel@tonic-gate 	    xdr_nfs2_timeval(xdrs, &sa->sa_mtime)) {
5967c478bd9Sstevel@tonic-gate 		return (TRUE);
5977c478bd9Sstevel@tonic-gate 	}
5987c478bd9Sstevel@tonic-gate 	return (FALSE);
5997c478bd9Sstevel@tonic-gate }
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate static struct xdr_discrim attrstat_discrim[2] = {
6027c478bd9Sstevel@tonic-gate 	{ (int)NFS_OK, xdr_fattr },
6037c478bd9Sstevel@tonic-gate 	{ __dontcare__, NULL_xdrproc_t }
6047c478bd9Sstevel@tonic-gate };
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate /*
6077c478bd9Sstevel@tonic-gate  * Reply status with file attributes
6087c478bd9Sstevel@tonic-gate  */
6097c478bd9Sstevel@tonic-gate bool_t
xdr_attrstat(XDR * xdrs,struct nfsattrstat * ns)6107c478bd9Sstevel@tonic-gate xdr_attrstat(XDR *xdrs, struct nfsattrstat *ns)
6117c478bd9Sstevel@tonic-gate {
6127c478bd9Sstevel@tonic-gate 	return (xdr_union(xdrs, (enum_t *)&(ns->ns_status),
6137c478bd9Sstevel@tonic-gate 	    (caddr_t)&(ns->ns_attr), attrstat_discrim, xdr_void));
6147c478bd9Sstevel@tonic-gate }
6157c478bd9Sstevel@tonic-gate 
6167c478bd9Sstevel@tonic-gate /*
6177c478bd9Sstevel@tonic-gate  * Fast reply status with file attributes
6187c478bd9Sstevel@tonic-gate  */
6197c478bd9Sstevel@tonic-gate bool_t
xdr_fastattrstat(XDR * xdrs,struct nfsattrstat * ns)6207c478bd9Sstevel@tonic-gate xdr_fastattrstat(XDR *xdrs, struct nfsattrstat *ns)
6217c478bd9Sstevel@tonic-gate {
6227c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
6237c478bd9Sstevel@tonic-gate 	/*
6247c478bd9Sstevel@tonic-gate 	 * we deal with the discriminator;  it's an enum
6257c478bd9Sstevel@tonic-gate 	 */
6267c478bd9Sstevel@tonic-gate 	if (!xdr_fastenum(xdrs, (enum_t *)&ns->ns_status))
6277c478bd9Sstevel@tonic-gate 		return (FALSE);
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate 	if (ns->ns_status == NFS_OK)
6307c478bd9Sstevel@tonic-gate 		return (xdr_fastfattr(xdrs, &ns->ns_attr));
6317c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
6327c478bd9Sstevel@tonic-gate 	if (ns->ns_status == NFS_OK)
6337c478bd9Sstevel@tonic-gate 		return (TRUE);
6347c478bd9Sstevel@tonic-gate #endif
6357c478bd9Sstevel@tonic-gate 	return (xdr_fastshorten(xdrs, sizeof (*ns)));
6367c478bd9Sstevel@tonic-gate }
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate /*
6397c478bd9Sstevel@tonic-gate  * NFS_OK part of read sym link reply union
6407c478bd9Sstevel@tonic-gate  */
6417c478bd9Sstevel@tonic-gate bool_t
xdr_srok(XDR * xdrs,struct nfssrok * srok)6427c478bd9Sstevel@tonic-gate xdr_srok(XDR *xdrs, struct nfssrok *srok)
6437c478bd9Sstevel@tonic-gate {
6447c478bd9Sstevel@tonic-gate 	/*
6457c478bd9Sstevel@tonic-gate 	 * It is just as efficient to xdr_bytes
6467c478bd9Sstevel@tonic-gate 	 * an array of unknown length as to inline copy it.
6477c478bd9Sstevel@tonic-gate 	 */
6487c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, &srok->srok_data, &srok->srok_count,
6497c478bd9Sstevel@tonic-gate 	    NFS_MAXPATHLEN));
6507c478bd9Sstevel@tonic-gate }
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate static struct xdr_discrim rdlnres_discrim[2] = {
6537c478bd9Sstevel@tonic-gate 	{ (int)NFS_OK, xdr_srok },
6547c478bd9Sstevel@tonic-gate 	{ __dontcare__, NULL_xdrproc_t }
6557c478bd9Sstevel@tonic-gate };
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate /*
6587c478bd9Sstevel@tonic-gate  * Result of reading symbolic link
6597c478bd9Sstevel@tonic-gate  */
6607c478bd9Sstevel@tonic-gate bool_t
xdr_rdlnres(XDR * xdrs,struct nfsrdlnres * rl)6617c478bd9Sstevel@tonic-gate xdr_rdlnres(XDR *xdrs, struct nfsrdlnres *rl)
6627c478bd9Sstevel@tonic-gate {
6637c478bd9Sstevel@tonic-gate 	return (xdr_union(xdrs, (enum_t *)&(rl->rl_status),
6647c478bd9Sstevel@tonic-gate 	    (caddr_t)&(rl->rl_srok), rdlnres_discrim, xdr_void));
6657c478bd9Sstevel@tonic-gate }
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate /*
6687c478bd9Sstevel@tonic-gate  * Arguments to readdir
6697c478bd9Sstevel@tonic-gate  */
6707c478bd9Sstevel@tonic-gate bool_t
xdr_rddirargs(XDR * xdrs,struct nfsrddirargs * rda)6717c478bd9Sstevel@tonic-gate xdr_rddirargs(XDR *xdrs, struct nfsrddirargs *rda)
6727c478bd9Sstevel@tonic-gate {
6737c478bd9Sstevel@tonic-gate 	int32_t *ptr;
6747c478bd9Sstevel@tonic-gate 	int32_t *fhp;
6750a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
6760a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
6797c478bd9Sstevel@tonic-gate 		return (TRUE);
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs,
6827c478bd9Sstevel@tonic-gate 	    RNDUP(sizeof (fhandle_t)) + 2 * BYTES_PER_XDR_UNIT);
6830a701b1eSRobert Gordon 
6840a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
6850a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
6860a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
6870a701b1eSRobert Gordon 		rci.rci_len = rda->rda_count;
6880a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
6890a701b1eSRobert Gordon 	}
6900a701b1eSRobert Gordon 
6917c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
6927c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
6937c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)&rda->rda_fh;
6947c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
6957c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
6967c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
6977c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
6987c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
6997c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
7007c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
7017c478bd9Sstevel@tonic-gate 			*fhp = *ptr++;
7027c478bd9Sstevel@tonic-gate 			rda->rda_offset = IXDR_GET_U_INT32(ptr);
7037c478bd9Sstevel@tonic-gate 			rda->rda_count = IXDR_GET_U_INT32(ptr);
7047c478bd9Sstevel@tonic-gate 		} else {
7057c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)&rda->rda_fh;
7067c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
7077c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
7087c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
7097c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
7107c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
7117c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
7127c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
7137c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp;
7147c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, rda->rda_offset);
7157c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, rda->rda_count);
7167c478bd9Sstevel@tonic-gate 		}
7177c478bd9Sstevel@tonic-gate 		return (TRUE);
7187c478bd9Sstevel@tonic-gate 	}
7197c478bd9Sstevel@tonic-gate 
7207c478bd9Sstevel@tonic-gate 	if (xdr_fhandle(xdrs, &rda->rda_fh) &&
7217c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &rda->rda_offset) &&
7227c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &rda->rda_count)) {
7237c478bd9Sstevel@tonic-gate 		return (TRUE);
7247c478bd9Sstevel@tonic-gate 	}
7257c478bd9Sstevel@tonic-gate 	return (FALSE);
7267c478bd9Sstevel@tonic-gate }
7277c478bd9Sstevel@tonic-gate 
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate /*
7307c478bd9Sstevel@tonic-gate  * Directory read reply:
7317c478bd9Sstevel@tonic-gate  * union (enum status) {
7327c478bd9Sstevel@tonic-gate  *	NFS_OK: entlist;
7337c478bd9Sstevel@tonic-gate  *		boolean eof;
7347c478bd9Sstevel@tonic-gate  *	default:
7357c478bd9Sstevel@tonic-gate  * }
7367c478bd9Sstevel@tonic-gate  *
7377c478bd9Sstevel@tonic-gate  * Directory entries
7387c478bd9Sstevel@tonic-gate  *	struct  direct {
7397c478bd9Sstevel@tonic-gate  *		off_t   d_off;			* offset of next entry *
7407c478bd9Sstevel@tonic-gate  *		u_int	d_fileno;		* inode number of entry *
7417c478bd9Sstevel@tonic-gate  *		u_short d_reclen;		* length of this record *
7427c478bd9Sstevel@tonic-gate  *		u_short d_namlen;		* length of string in d_name *
7437c478bd9Sstevel@tonic-gate  *		char    d_name[MAXNAMLEN + 1];	* name no longer than this *
7447c478bd9Sstevel@tonic-gate  *	};
7457c478bd9Sstevel@tonic-gate  * are on the wire as:
7467c478bd9Sstevel@tonic-gate  * union entlist (boolean valid) {
7477c478bd9Sstevel@tonic-gate  * 	TRUE:	struct otw_dirent;
7487c478bd9Sstevel@tonic-gate  *		u_int nxtoffset;
7497c478bd9Sstevel@tonic-gate  *		union entlist;
7507c478bd9Sstevel@tonic-gate  *	FALSE:
7517c478bd9Sstevel@tonic-gate  * }
7527c478bd9Sstevel@tonic-gate  * where otw_dirent is:
7537c478bd9Sstevel@tonic-gate  * 	struct dirent {
7547c478bd9Sstevel@tonic-gate  *		u_int	de_fid;
7557c478bd9Sstevel@tonic-gate  *		string	de_name<NFS_MAXNAMELEN>;
7567c478bd9Sstevel@tonic-gate  *	}
7577c478bd9Sstevel@tonic-gate  */
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate #ifdef nextdp
7607c478bd9Sstevel@tonic-gate #undef	nextdp
7617c478bd9Sstevel@tonic-gate #endif
7627c478bd9Sstevel@tonic-gate #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
7637c478bd9Sstevel@tonic-gate #ifdef roundup
7647c478bd9Sstevel@tonic-gate #undef	roundup
7657c478bd9Sstevel@tonic-gate #endif
7667c478bd9Sstevel@tonic-gate #define	roundup(x, y)	((((x) + ((y) - 1)) / (y)) * (y))
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate /*
7697c478bd9Sstevel@tonic-gate  * ENCODE ONLY
7707c478bd9Sstevel@tonic-gate  */
7717c478bd9Sstevel@tonic-gate bool_t
xdr_putrddirres(XDR * xdrs,struct nfsrddirres * rd)7727c478bd9Sstevel@tonic-gate xdr_putrddirres(XDR *xdrs, struct nfsrddirres *rd)
7737c478bd9Sstevel@tonic-gate {
7747c478bd9Sstevel@tonic-gate 	struct dirent64 *dp;
7757c478bd9Sstevel@tonic-gate 	char *name;
7767c478bd9Sstevel@tonic-gate 	int size;
7777c478bd9Sstevel@tonic-gate 	uint_t namlen;
7787c478bd9Sstevel@tonic-gate 	bool_t true = TRUE;
7797c478bd9Sstevel@tonic-gate 	bool_t false = FALSE;
7807c478bd9Sstevel@tonic-gate 	int entrysz;
7817c478bd9Sstevel@tonic-gate 	int tofit;
7827c478bd9Sstevel@tonic-gate 	int bufsize;
7837c478bd9Sstevel@tonic-gate 	uint32_t ino, off;
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_ENCODE)
7867c478bd9Sstevel@tonic-gate 		return (FALSE);
7877c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
7887c478bd9Sstevel@tonic-gate 		return (FALSE);
7897c478bd9Sstevel@tonic-gate 	if (rd->rd_status != NFS_OK)
7907c478bd9Sstevel@tonic-gate 		return (TRUE);
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate 	bufsize = 1 * BYTES_PER_XDR_UNIT;
7937c478bd9Sstevel@tonic-gate 	for (size = rd->rd_size, dp = rd->rd_entries;
7940a701b1eSRobert Gordon 	    size > 0;
7950a701b1eSRobert Gordon 	    size -= dp->d_reclen, dp = nextdp(dp)) {
7967c478bd9Sstevel@tonic-gate 		if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */)
7977c478bd9Sstevel@tonic-gate 			return (FALSE);
7987c478bd9Sstevel@tonic-gate 		if (dp->d_ino == 0)
7997c478bd9Sstevel@tonic-gate 			continue;
8007c478bd9Sstevel@tonic-gate 		ino = (uint32_t)dp->d_ino; /* for LP64 we clip the bits */
8017c478bd9Sstevel@tonic-gate 		if (dp->d_ino != (ino64_t)ino)	/* and they better be zeros */
8027c478bd9Sstevel@tonic-gate 			return (FALSE);
8037c478bd9Sstevel@tonic-gate 		off = (uint32_t)dp->d_off;
8047c478bd9Sstevel@tonic-gate 		name = dp->d_name;
8057c478bd9Sstevel@tonic-gate 		namlen = (uint_t)strlen(name);
8067c478bd9Sstevel@tonic-gate 		entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
8077c478bd9Sstevel@tonic-gate 		    roundup(namlen, BYTES_PER_XDR_UNIT);
8087c478bd9Sstevel@tonic-gate 		tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
8097c478bd9Sstevel@tonic-gate 		if (bufsize + tofit > rd->rd_bufsize) {
8107c478bd9Sstevel@tonic-gate 			rd->rd_eof = FALSE;
8117c478bd9Sstevel@tonic-gate 			break;
8127c478bd9Sstevel@tonic-gate 		}
8137c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &true) ||
8147c478bd9Sstevel@tonic-gate 		    !xdr_u_int(xdrs, &ino) ||
8157c478bd9Sstevel@tonic-gate 		    !xdr_bytes(xdrs, &name, &namlen, NFS_MAXNAMLEN) ||
8167c478bd9Sstevel@tonic-gate 		    !xdr_u_int(xdrs, &off)) {
8177c478bd9Sstevel@tonic-gate 			return (FALSE);
8187c478bd9Sstevel@tonic-gate 		}
8197c478bd9Sstevel@tonic-gate 		bufsize += entrysz;
8207c478bd9Sstevel@tonic-gate 	}
8217c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &false))
8227c478bd9Sstevel@tonic-gate 		return (FALSE);
8237c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &rd->rd_eof))
8247c478bd9Sstevel@tonic-gate 		return (FALSE);
8257c478bd9Sstevel@tonic-gate 	return (TRUE);
8267c478bd9Sstevel@tonic-gate }
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate /*
8297c478bd9Sstevel@tonic-gate  * DECODE ONLY
8307c478bd9Sstevel@tonic-gate  */
8317c478bd9Sstevel@tonic-gate bool_t
xdr_getrddirres(XDR * xdrs,struct nfsrddirres * rd)8327c478bd9Sstevel@tonic-gate xdr_getrddirres(XDR *xdrs, struct nfsrddirres *rd)
8337c478bd9Sstevel@tonic-gate {
8347c478bd9Sstevel@tonic-gate 	struct dirent64 *dp;
8357c478bd9Sstevel@tonic-gate 	uint_t namlen;
8367c478bd9Sstevel@tonic-gate 	int size;
8377c478bd9Sstevel@tonic-gate 	bool_t valid;
8387c478bd9Sstevel@tonic-gate 	uint32_t offset;
8397c478bd9Sstevel@tonic-gate 	uint_t fileid, this_reclen;
8407c478bd9Sstevel@tonic-gate 
8417c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
8427c478bd9Sstevel@tonic-gate 		return (FALSE);
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
8457c478bd9Sstevel@tonic-gate 		return (FALSE);
8467c478bd9Sstevel@tonic-gate 	if (rd->rd_status != NFS_OK)
8477c478bd9Sstevel@tonic-gate 		return (TRUE);
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 	size = rd->rd_size;
8507c478bd9Sstevel@tonic-gate 	dp = rd->rd_entries;
8517c478bd9Sstevel@tonic-gate 	offset = rd->rd_offset;
8527c478bd9Sstevel@tonic-gate 	for (;;) {
8537c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &valid))
8547c478bd9Sstevel@tonic-gate 			return (FALSE);
8557c478bd9Sstevel@tonic-gate 		if (!valid)
8567c478bd9Sstevel@tonic-gate 			break;
8577c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &fileid) ||
8587c478bd9Sstevel@tonic-gate 		    !xdr_u_int(xdrs, &namlen))
8597c478bd9Sstevel@tonic-gate 			return (FALSE);
8607c478bd9Sstevel@tonic-gate 		this_reclen = DIRENT64_RECLEN(namlen);
8617c478bd9Sstevel@tonic-gate 		if (this_reclen > size) {
8627c478bd9Sstevel@tonic-gate 			rd->rd_eof = FALSE;
8637c478bd9Sstevel@tonic-gate 			goto bufovflw;
8647c478bd9Sstevel@tonic-gate 		}
8657c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, dp->d_name, namlen)||
8667c478bd9Sstevel@tonic-gate 		    !xdr_u_int(xdrs, &offset)) {
8677c478bd9Sstevel@tonic-gate 			return (FALSE);
8687c478bd9Sstevel@tonic-gate 		}
8697c478bd9Sstevel@tonic-gate 		bzero(&dp->d_name[namlen],
8707c478bd9Sstevel@tonic-gate 		    DIRENT64_NAMELEN(this_reclen) - namlen);
8717c478bd9Sstevel@tonic-gate 		dp->d_ino = (ino64_t)fileid;
8727c478bd9Sstevel@tonic-gate 		dp->d_reclen = this_reclen;
8737c478bd9Sstevel@tonic-gate 		dp->d_off = (off64_t)offset;
8747c478bd9Sstevel@tonic-gate 		size -= dp->d_reclen;
8757c478bd9Sstevel@tonic-gate 		dp = nextdp(dp);
8767c478bd9Sstevel@tonic-gate 	}
8777c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &rd->rd_eof))
8787c478bd9Sstevel@tonic-gate 		return (FALSE);
8797c478bd9Sstevel@tonic-gate bufovflw:
8807c478bd9Sstevel@tonic-gate 	rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_entries));
8817c478bd9Sstevel@tonic-gate 	rd->rd_offset = offset;
8827c478bd9Sstevel@tonic-gate 	return (TRUE);
8837c478bd9Sstevel@tonic-gate }
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate /*
8867c478bd9Sstevel@tonic-gate  * Arguments for directory operations
8877c478bd9Sstevel@tonic-gate  */
8887c478bd9Sstevel@tonic-gate bool_t
xdr_diropargs(XDR * xdrs,struct nfsdiropargs * da)8897c478bd9Sstevel@tonic-gate xdr_diropargs(XDR *xdrs, struct nfsdiropargs *da)
8907c478bd9Sstevel@tonic-gate {
8917c478bd9Sstevel@tonic-gate 	int32_t *ptr;
8927c478bd9Sstevel@tonic-gate 	int32_t *fhp;
8937c478bd9Sstevel@tonic-gate 	uint32_t size;
8947c478bd9Sstevel@tonic-gate 	uint32_t nodesize;
8957c478bd9Sstevel@tonic-gate 	int i;
8967c478bd9Sstevel@tonic-gate 	int rndup;
8977c478bd9Sstevel@tonic-gate 	char *cptr;
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
9007c478bd9Sstevel@tonic-gate 		da->da_fhandle = &da->da_fhandle_buf;
9017c478bd9Sstevel@tonic-gate 		ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
9027c478bd9Sstevel@tonic-gate 		    1 * BYTES_PER_XDR_UNIT);
9037c478bd9Sstevel@tonic-gate 		if (ptr != NULL) {
9047c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)da->da_fhandle;
9057c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
9067c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
9077c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
9087c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
9097c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
9107c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
9117c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
9127c478bd9Sstevel@tonic-gate 			*fhp = *ptr++;
9137c478bd9Sstevel@tonic-gate 			size = IXDR_GET_U_INT32(ptr);
9147c478bd9Sstevel@tonic-gate 			if (size > NFS_MAXNAMLEN)
9157c478bd9Sstevel@tonic-gate 				return (FALSE);
9167c478bd9Sstevel@tonic-gate 			nodesize = size + 1;
9177c478bd9Sstevel@tonic-gate 			if (nodesize == 0)
9187c478bd9Sstevel@tonic-gate 				return (TRUE);
9197c478bd9Sstevel@tonic-gate 			if (da->da_name == NULL) {
9207c478bd9Sstevel@tonic-gate 				da->da_name = kmem_alloc(nodesize, KM_NOSLEEP);
9217c478bd9Sstevel@tonic-gate 				if (da->da_name == NULL)
9227c478bd9Sstevel@tonic-gate 					return (FALSE);
9237c478bd9Sstevel@tonic-gate 				da->da_flags |= DA_FREENAME;
9247c478bd9Sstevel@tonic-gate 			}
9257c478bd9Sstevel@tonic-gate 			ptr = XDR_INLINE(xdrs, RNDUP(size));
9267c478bd9Sstevel@tonic-gate 			if (ptr == NULL) {
9277c478bd9Sstevel@tonic-gate 				if (!xdr_opaque(xdrs, da->da_name, size)) {
9287c478bd9Sstevel@tonic-gate 					if (da->da_flags & DA_FREENAME) {
9297c478bd9Sstevel@tonic-gate 						kmem_free(da->da_name,
9307c478bd9Sstevel@tonic-gate 						    nodesize);
9317c478bd9Sstevel@tonic-gate 						da->da_name = NULL;
9327c478bd9Sstevel@tonic-gate 					}
9337c478bd9Sstevel@tonic-gate 					return (FALSE);
9347c478bd9Sstevel@tonic-gate 				}
9357c478bd9Sstevel@tonic-gate 				da->da_name[size] = '\0';
9367c478bd9Sstevel@tonic-gate 				if (strlen(da->da_name) != size) {
9377c478bd9Sstevel@tonic-gate 					if (da->da_flags & DA_FREENAME) {
9387c478bd9Sstevel@tonic-gate 						kmem_free(da->da_name,
9397c478bd9Sstevel@tonic-gate 						    nodesize);
9407c478bd9Sstevel@tonic-gate 						da->da_name = NULL;
9417c478bd9Sstevel@tonic-gate 					}
9427c478bd9Sstevel@tonic-gate 					return (FALSE);
9437c478bd9Sstevel@tonic-gate 				}
9447c478bd9Sstevel@tonic-gate 				return (TRUE);
9457c478bd9Sstevel@tonic-gate 			}
9467c478bd9Sstevel@tonic-gate 			bcopy(ptr, da->da_name, size);
9477c478bd9Sstevel@tonic-gate 			da->da_name[size] = '\0';
9487c478bd9Sstevel@tonic-gate 			if (strlen(da->da_name) != size) {
9497c478bd9Sstevel@tonic-gate 				if (da->da_flags & DA_FREENAME) {
9507c478bd9Sstevel@tonic-gate 					kmem_free(da->da_name, nodesize);
9517c478bd9Sstevel@tonic-gate 					da->da_name = NULL;
9527c478bd9Sstevel@tonic-gate 				}
9537c478bd9Sstevel@tonic-gate 				return (FALSE);
9547c478bd9Sstevel@tonic-gate 			}
9557c478bd9Sstevel@tonic-gate 			return (TRUE);
9567c478bd9Sstevel@tonic-gate 		}
9577c478bd9Sstevel@tonic-gate 		if (da->da_name == NULL)
9587c478bd9Sstevel@tonic-gate 			da->da_flags |= DA_FREENAME;
9597c478bd9Sstevel@tonic-gate 	}
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
9627c478bd9Sstevel@tonic-gate 		size = (uint32_t)strlen(da->da_name);
9637c478bd9Sstevel@tonic-gate 		if (size > NFS_MAXNAMLEN)
9647c478bd9Sstevel@tonic-gate 			return (FALSE);
9657c478bd9Sstevel@tonic-gate 		ptr = XDR_INLINE(xdrs, (int)(RNDUP(sizeof (fhandle_t)) +
9667c478bd9Sstevel@tonic-gate 		    1 * BYTES_PER_XDR_UNIT + RNDUP(size)));
9677c478bd9Sstevel@tonic-gate 		if (ptr != NULL) {
9687c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)da->da_fhandle;
9697c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
9707c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
9717c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
9727c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
9737c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
9747c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
9757c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
9767c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp;
9777c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, (uint32_t)size);
9787c478bd9Sstevel@tonic-gate 			bcopy(da->da_name, ptr, size);
9797c478bd9Sstevel@tonic-gate 			rndup = BYTES_PER_XDR_UNIT -
9800a701b1eSRobert Gordon 			    (size % BYTES_PER_XDR_UNIT);
9817c478bd9Sstevel@tonic-gate 			if (rndup != BYTES_PER_XDR_UNIT) {
9827c478bd9Sstevel@tonic-gate 				cptr = (char *)ptr + size;
9837c478bd9Sstevel@tonic-gate 				for (i = 0; i < rndup; i++)
9847c478bd9Sstevel@tonic-gate 					*cptr++ = '\0';
9857c478bd9Sstevel@tonic-gate 			}
9867c478bd9Sstevel@tonic-gate 			return (TRUE);
9877c478bd9Sstevel@tonic-gate 		}
9887c478bd9Sstevel@tonic-gate 	}
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE) {
9917c478bd9Sstevel@tonic-gate 		if (da->da_name == NULL)
9927c478bd9Sstevel@tonic-gate 			return (TRUE);
9937c478bd9Sstevel@tonic-gate 		size = (uint32_t)strlen(da->da_name);
9947c478bd9Sstevel@tonic-gate 		if (size > NFS_MAXNAMLEN)
9957c478bd9Sstevel@tonic-gate 			return (FALSE);
9967c478bd9Sstevel@tonic-gate 		if (da->da_flags & DA_FREENAME)
9977c478bd9Sstevel@tonic-gate 			kmem_free(da->da_name, size + 1);
9987c478bd9Sstevel@tonic-gate 		da->da_name = NULL;
9997c478bd9Sstevel@tonic-gate 		return (TRUE);
10007c478bd9Sstevel@tonic-gate 	}
10017c478bd9Sstevel@tonic-gate 
10027c478bd9Sstevel@tonic-gate 	if (xdr_fhandle(xdrs, da->da_fhandle) &&
10037c478bd9Sstevel@tonic-gate 	    xdr_string(xdrs, &da->da_name, NFS_MAXNAMLEN)) {
10047c478bd9Sstevel@tonic-gate 		return (TRUE);
10057c478bd9Sstevel@tonic-gate 	}
10067c478bd9Sstevel@tonic-gate 	return (FALSE);
10077c478bd9Sstevel@tonic-gate }
10087c478bd9Sstevel@tonic-gate 
10097c478bd9Sstevel@tonic-gate /*
10107c478bd9Sstevel@tonic-gate  * NFS_OK part of directory operation result
10117c478bd9Sstevel@tonic-gate  */
10127c478bd9Sstevel@tonic-gate bool_t
xdr_drok(XDR * xdrs,struct nfsdrok * drok)10137c478bd9Sstevel@tonic-gate xdr_drok(XDR *xdrs, struct nfsdrok *drok)
10147c478bd9Sstevel@tonic-gate {
10157c478bd9Sstevel@tonic-gate 	int32_t *ptr;
10167c478bd9Sstevel@tonic-gate 	int32_t *fhp;
10177c478bd9Sstevel@tonic-gate 	struct nfsfattr *na;
10187c478bd9Sstevel@tonic-gate 
10197c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
10207c478bd9Sstevel@tonic-gate 		return (TRUE);
10217c478bd9Sstevel@tonic-gate 
10227c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs,
10237c478bd9Sstevel@tonic-gate 	    RNDUP(sizeof (fhandle_t)) + 17 * BYTES_PER_XDR_UNIT);
10247c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
10257c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
10267c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)&drok->drok_fhandle;
10277c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
10287c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
10297c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
10307c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
10317c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
10327c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
10337c478bd9Sstevel@tonic-gate 			*fhp++ = *ptr++;
10347c478bd9Sstevel@tonic-gate 			*fhp = *ptr++;
10357c478bd9Sstevel@tonic-gate 			na = &drok->drok_attr;
10367c478bd9Sstevel@tonic-gate 			na->na_type = IXDR_GET_ENUM(ptr, enum nfsftype);
10377c478bd9Sstevel@tonic-gate 			na->na_mode = IXDR_GET_U_INT32(ptr);
10387c478bd9Sstevel@tonic-gate 			na->na_nlink = IXDR_GET_U_INT32(ptr);
10397c478bd9Sstevel@tonic-gate 			na->na_uid = IXDR_GET_U_INT32(ptr);
10407c478bd9Sstevel@tonic-gate 			na->na_gid = IXDR_GET_U_INT32(ptr);
10417c478bd9Sstevel@tonic-gate 			na->na_size = IXDR_GET_U_INT32(ptr);
10427c478bd9Sstevel@tonic-gate 			na->na_blocksize = IXDR_GET_U_INT32(ptr);
10437c478bd9Sstevel@tonic-gate 			na->na_rdev = IXDR_GET_U_INT32(ptr);
10447c478bd9Sstevel@tonic-gate 			na->na_blocks = IXDR_GET_U_INT32(ptr);
10457c478bd9Sstevel@tonic-gate 			na->na_fsid = IXDR_GET_U_INT32(ptr);
10467c478bd9Sstevel@tonic-gate 			na->na_nodeid = IXDR_GET_U_INT32(ptr);
10477c478bd9Sstevel@tonic-gate 			na->na_atime.tv_sec = IXDR_GET_U_INT32(ptr);
10487c478bd9Sstevel@tonic-gate 			na->na_atime.tv_usec = IXDR_GET_U_INT32(ptr);
10497c478bd9Sstevel@tonic-gate 			na->na_mtime.tv_sec = IXDR_GET_U_INT32(ptr);
10507c478bd9Sstevel@tonic-gate 			na->na_mtime.tv_usec = IXDR_GET_U_INT32(ptr);
10517c478bd9Sstevel@tonic-gate 			na->na_ctime.tv_sec = IXDR_GET_U_INT32(ptr);
10527c478bd9Sstevel@tonic-gate 			na->na_ctime.tv_usec = IXDR_GET_U_INT32(ptr);
10537c478bd9Sstevel@tonic-gate 		} else {
10547c478bd9Sstevel@tonic-gate 			fhp = (int32_t *)&drok->drok_fhandle;
10557c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
10567c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
10577c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
10587c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
10597c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
10607c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
10617c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp++;
10627c478bd9Sstevel@tonic-gate 			*ptr++ = *fhp;
10637c478bd9Sstevel@tonic-gate 			na = &drok->drok_attr;
10647c478bd9Sstevel@tonic-gate 			IXDR_PUT_ENUM(ptr, na->na_type);
10657c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_mode);
10667c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_nlink);
10677c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_uid);
10687c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_gid);
10697c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_size);
10707c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_blocksize);
10717c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_rdev);
10727c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_blocks);
10737c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_fsid);
10747c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_nodeid);
10757c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_atime.tv_sec);
10767c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_atime.tv_usec);
10777c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_sec);
10787c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_usec);
10797c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_sec);
10807c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_usec);
10817c478bd9Sstevel@tonic-gate 		}
10827c478bd9Sstevel@tonic-gate 		return (TRUE);
10837c478bd9Sstevel@tonic-gate 	}
10847c478bd9Sstevel@tonic-gate 
10857c478bd9Sstevel@tonic-gate 	if (xdr_fhandle(xdrs, &drok->drok_fhandle) &&
10867c478bd9Sstevel@tonic-gate 	    xdr_fattr(xdrs, &drok->drok_attr)) {
10877c478bd9Sstevel@tonic-gate 		return (TRUE);
10887c478bd9Sstevel@tonic-gate 	}
10897c478bd9Sstevel@tonic-gate 	return (FALSE);
10907c478bd9Sstevel@tonic-gate }
10917c478bd9Sstevel@tonic-gate 
10927c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
10937c478bd9Sstevel@tonic-gate bool_t
xdr_fastdrok(XDR * xdrs,struct nfsdrok * drok)10947c478bd9Sstevel@tonic-gate xdr_fastdrok(XDR *xdrs, struct nfsdrok *drok)
10957c478bd9Sstevel@tonic-gate {
10967c478bd9Sstevel@tonic-gate 	struct nfsfattr *na;
10977c478bd9Sstevel@tonic-gate 
10987c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
10997c478bd9Sstevel@tonic-gate 		return (TRUE);
11007c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
11017c478bd9Sstevel@tonic-gate 		return (FALSE);
11027c478bd9Sstevel@tonic-gate 
11037c478bd9Sstevel@tonic-gate 	na = &drok->drok_attr;
11047c478bd9Sstevel@tonic-gate 	na->na_type = (enum nfsftype)htonl(na->na_type);
11057c478bd9Sstevel@tonic-gate 	na->na_mode = (uint32_t)htonl(na->na_mode);
11067c478bd9Sstevel@tonic-gate 	na->na_nlink = (uint32_t)htonl(na->na_nlink);
11077c478bd9Sstevel@tonic-gate 	na->na_uid = (uint32_t)htonl(na->na_uid);
11087c478bd9Sstevel@tonic-gate 	na->na_gid = (uint32_t)htonl(na->na_gid);
11097c478bd9Sstevel@tonic-gate 	na->na_size = (uint32_t)htonl(na->na_size);
11107c478bd9Sstevel@tonic-gate 	na->na_blocksize = (uint32_t)htonl(na->na_blocksize);
11117c478bd9Sstevel@tonic-gate 	na->na_rdev = (uint32_t)htonl(na->na_rdev);
11127c478bd9Sstevel@tonic-gate 	na->na_blocks = (uint32_t)htonl(na->na_blocks);
11137c478bd9Sstevel@tonic-gate 	na->na_fsid = (uint32_t)htonl(na->na_fsid);
11147c478bd9Sstevel@tonic-gate 	na->na_nodeid = (uint32_t)htonl(na->na_nodeid);
11157c478bd9Sstevel@tonic-gate 	na->na_atime.tv_sec = htonl(na->na_atime.tv_sec);
11167c478bd9Sstevel@tonic-gate 	na->na_atime.tv_usec = htonl(na->na_atime.tv_usec);
11177c478bd9Sstevel@tonic-gate 	na->na_mtime.tv_sec = htonl(na->na_mtime.tv_sec);
11187c478bd9Sstevel@tonic-gate 	na->na_mtime.tv_usec = htonl(na->na_mtime.tv_usec);
11197c478bd9Sstevel@tonic-gate 	na->na_ctime.tv_sec = htonl(na->na_ctime.tv_sec);
11207c478bd9Sstevel@tonic-gate 	na->na_ctime.tv_usec = htonl(na->na_ctime.tv_usec);
11217c478bd9Sstevel@tonic-gate 	return (TRUE);
11227c478bd9Sstevel@tonic-gate }
11237c478bd9Sstevel@tonic-gate #endif
11247c478bd9Sstevel@tonic-gate 
11257c478bd9Sstevel@tonic-gate static struct xdr_discrim diropres_discrim[2] = {
11267c478bd9Sstevel@tonic-gate 	{ NFS_OK, xdr_drok },
11277c478bd9Sstevel@tonic-gate 	{ __dontcare__, NULL_xdrproc_t }
11287c478bd9Sstevel@tonic-gate };
11297c478bd9Sstevel@tonic-gate 
11307c478bd9Sstevel@tonic-gate /*
11317c478bd9Sstevel@tonic-gate  * Results from directory operation
11327c478bd9Sstevel@tonic-gate  */
11337c478bd9Sstevel@tonic-gate bool_t
xdr_diropres(XDR * xdrs,struct nfsdiropres * dr)11347c478bd9Sstevel@tonic-gate xdr_diropres(XDR *xdrs, struct nfsdiropres *dr)
11357c478bd9Sstevel@tonic-gate {
11367c478bd9Sstevel@tonic-gate 	return (xdr_union(xdrs, (enum_t *)&(dr->dr_status),
11377c478bd9Sstevel@tonic-gate 	    (caddr_t)&(dr->dr_drok), diropres_discrim, xdr_void));
11387c478bd9Sstevel@tonic-gate }
11397c478bd9Sstevel@tonic-gate 
11407c478bd9Sstevel@tonic-gate /*
11417c478bd9Sstevel@tonic-gate  * Results from directory operation
11427c478bd9Sstevel@tonic-gate  */
11437c478bd9Sstevel@tonic-gate bool_t
xdr_fastdiropres(XDR * xdrs,struct nfsdiropres * dr)11447c478bd9Sstevel@tonic-gate xdr_fastdiropres(XDR *xdrs, struct nfsdiropres *dr)
11457c478bd9Sstevel@tonic-gate {
11467c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
11477c478bd9Sstevel@tonic-gate 	/*
11487c478bd9Sstevel@tonic-gate 	 * we deal with the discriminator;  it's an enum
11497c478bd9Sstevel@tonic-gate 	 */
11507c478bd9Sstevel@tonic-gate 	if (!xdr_fastenum(xdrs, (enum_t *)&dr->dr_status))
11517c478bd9Sstevel@tonic-gate 		return (FALSE);
11527c478bd9Sstevel@tonic-gate 
11537c478bd9Sstevel@tonic-gate 	if (dr->dr_status == NFS_OK)
11547c478bd9Sstevel@tonic-gate 		return (xdr_fastdrok(xdrs, &dr->dr_drok));
11557c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
11567c478bd9Sstevel@tonic-gate 	if (dr->dr_status == NFS_OK)
11577c478bd9Sstevel@tonic-gate 		return (TRUE);
11587c478bd9Sstevel@tonic-gate #endif
11597c478bd9Sstevel@tonic-gate 	return (xdr_fastshorten(xdrs, sizeof (*dr)));
11607c478bd9Sstevel@tonic-gate }
11617c478bd9Sstevel@tonic-gate 
11627c478bd9Sstevel@tonic-gate /*
11637c478bd9Sstevel@tonic-gate  * Time Structure, unsigned
11647c478bd9Sstevel@tonic-gate  */
11657c478bd9Sstevel@tonic-gate bool_t
xdr_nfs2_timeval(XDR * xdrs,struct nfs2_timeval * tv)11667c478bd9Sstevel@tonic-gate xdr_nfs2_timeval(XDR *xdrs, struct nfs2_timeval *tv)
11677c478bd9Sstevel@tonic-gate {
11687c478bd9Sstevel@tonic-gate 	if (xdr_u_int(xdrs, &tv->tv_sec) &&
11697c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &tv->tv_usec))
11707c478bd9Sstevel@tonic-gate 		return (TRUE);
11717c478bd9Sstevel@tonic-gate 	return (FALSE);
11727c478bd9Sstevel@tonic-gate }
11737c478bd9Sstevel@tonic-gate 
11747c478bd9Sstevel@tonic-gate /*
11757c478bd9Sstevel@tonic-gate  * arguments to setattr
11767c478bd9Sstevel@tonic-gate  */
11777c478bd9Sstevel@tonic-gate bool_t
xdr_saargs(XDR * xdrs,struct nfssaargs * argp)11787c478bd9Sstevel@tonic-gate xdr_saargs(XDR *xdrs, struct nfssaargs *argp)
11797c478bd9Sstevel@tonic-gate {
11807c478bd9Sstevel@tonic-gate 	int32_t *ptr;
11817c478bd9Sstevel@tonic-gate 	int32_t *arg;
11827c478bd9Sstevel@tonic-gate 	struct nfssattr *sa;
11837c478bd9Sstevel@tonic-gate 
11847c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
11857c478bd9Sstevel@tonic-gate 		return (TRUE);
11867c478bd9Sstevel@tonic-gate 
11877c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs,
11887c478bd9Sstevel@tonic-gate 	    RNDUP(sizeof (fhandle_t)) + 8 * BYTES_PER_XDR_UNIT);
11897c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
11907c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
11917c478bd9Sstevel@tonic-gate 			arg = (int32_t *)&argp->saa_fh;
11927c478bd9Sstevel@tonic-gate 			*arg++ = *ptr++;
11937c478bd9Sstevel@tonic-gate 			*arg++ = *ptr++;
11947c478bd9Sstevel@tonic-gate 			*arg++ = *ptr++;
11957c478bd9Sstevel@tonic-gate 			*arg++ = *ptr++;
11967c478bd9Sstevel@tonic-gate 			*arg++ = *ptr++;
11977c478bd9Sstevel@tonic-gate 			*arg++ = *ptr++;
11987c478bd9Sstevel@tonic-gate 			*arg++ = *ptr++;
11997c478bd9Sstevel@tonic-gate 			*arg = *ptr++;
12007c478bd9Sstevel@tonic-gate 			sa = &argp->saa_sa;
12017c478bd9Sstevel@tonic-gate 			sa->sa_mode = IXDR_GET_U_INT32(ptr);
12027c478bd9Sstevel@tonic-gate 			sa->sa_uid = IXDR_GET_U_INT32(ptr);
12037c478bd9Sstevel@tonic-gate 			sa->sa_gid = IXDR_GET_U_INT32(ptr);
12047c478bd9Sstevel@tonic-gate 			sa->sa_size = IXDR_GET_U_INT32(ptr);
12057c478bd9Sstevel@tonic-gate 			sa->sa_atime.tv_sec = IXDR_GET_U_INT32(ptr);
12067c478bd9Sstevel@tonic-gate 			sa->sa_atime.tv_usec = IXDR_GET_U_INT32(ptr);
12077c478bd9Sstevel@tonic-gate 			sa->sa_mtime.tv_sec = IXDR_GET_U_INT32(ptr);
12087c478bd9Sstevel@tonic-gate 			sa->sa_mtime.tv_usec = IXDR_GET_U_INT32(ptr);
12097c478bd9Sstevel@tonic-gate 		} else {
12107c478bd9Sstevel@tonic-gate 			arg = (int32_t *)&argp->saa_fh;
12117c478bd9Sstevel@tonic-gate 			*ptr++ = *arg++;
12127c478bd9Sstevel@tonic-gate 			*ptr++ = *arg++;
12137c478bd9Sstevel@tonic-gate 			*ptr++ = *arg++;
12147c478bd9Sstevel@tonic-gate 			*ptr++ = *arg++;
12157c478bd9Sstevel@tonic-gate 			*ptr++ = *arg++;
12167c478bd9Sstevel@tonic-gate 			*ptr++ = *arg++;
12177c478bd9Sstevel@tonic-gate 			*ptr++ = *arg++;
12187c478bd9Sstevel@tonic-gate 			*ptr++ = *arg;
12197c478bd9Sstevel@tonic-gate 			sa = &argp->saa_sa;
12207c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, sa->sa_mode);
12217c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, sa->sa_uid);
12227c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, sa->sa_gid);
12237c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, sa->sa_size);
12247c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, sa->sa_atime.tv_sec);
12257c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, sa->sa_atime.tv_usec);
12267c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, sa->sa_mtime.tv_sec);
12277c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, sa->sa_mtime.tv_usec);
12287c478bd9Sstevel@tonic-gate 		}
12297c478bd9Sstevel@tonic-gate 		return (TRUE);
12307c478bd9Sstevel@tonic-gate 	}
12317c478bd9Sstevel@tonic-gate 
12327c478bd9Sstevel@tonic-gate 	if (xdr_fhandle(xdrs, &argp->saa_fh) &&
12337c478bd9Sstevel@tonic-gate 	    xdr_sattr(xdrs, &argp->saa_sa)) {
12347c478bd9Sstevel@tonic-gate 		return (TRUE);
12357c478bd9Sstevel@tonic-gate 	}
12367c478bd9Sstevel@tonic-gate 	return (FALSE);
12377c478bd9Sstevel@tonic-gate }
12387c478bd9Sstevel@tonic-gate 
12397c478bd9Sstevel@tonic-gate 
12407c478bd9Sstevel@tonic-gate /*
12417c478bd9Sstevel@tonic-gate  * arguments to create and mkdir
12427c478bd9Sstevel@tonic-gate  */
12437c478bd9Sstevel@tonic-gate bool_t
xdr_creatargs(XDR * xdrs,struct nfscreatargs * argp)12447c478bd9Sstevel@tonic-gate xdr_creatargs(XDR *xdrs, struct nfscreatargs *argp)
12457c478bd9Sstevel@tonic-gate {
12467c478bd9Sstevel@tonic-gate 	argp->ca_sa = &argp->ca_sa_buf;
12477c478bd9Sstevel@tonic-gate 
12487c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
12497c478bd9Sstevel@tonic-gate 		argp->ca_sa = &argp->ca_sa_buf;
12507c478bd9Sstevel@tonic-gate 	if (xdr_diropargs(xdrs, &argp->ca_da) &&
12517c478bd9Sstevel@tonic-gate 	    xdr_sattr(xdrs, argp->ca_sa)) {
12527c478bd9Sstevel@tonic-gate 		return (TRUE);
12537c478bd9Sstevel@tonic-gate 	}
12547c478bd9Sstevel@tonic-gate 	return (FALSE);
12557c478bd9Sstevel@tonic-gate }
12567c478bd9Sstevel@tonic-gate 
12577c478bd9Sstevel@tonic-gate /*
12587c478bd9Sstevel@tonic-gate  * arguments to link
12597c478bd9Sstevel@tonic-gate  */
12607c478bd9Sstevel@tonic-gate bool_t
xdr_linkargs(XDR * xdrs,struct nfslinkargs * argp)12617c478bd9Sstevel@tonic-gate xdr_linkargs(XDR *xdrs, struct nfslinkargs *argp)
12627c478bd9Sstevel@tonic-gate {
12637c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
12647c478bd9Sstevel@tonic-gate 		argp->la_from = &argp->la_from_buf;
12657c478bd9Sstevel@tonic-gate 	if (xdr_fhandle(xdrs, argp->la_from) &&
12667c478bd9Sstevel@tonic-gate 	    xdr_diropargs(xdrs, &argp->la_to)) {
12677c478bd9Sstevel@tonic-gate 		return (TRUE);
12687c478bd9Sstevel@tonic-gate 	}
12697c478bd9Sstevel@tonic-gate 	return (FALSE);
12707c478bd9Sstevel@tonic-gate }
12717c478bd9Sstevel@tonic-gate 
12727c478bd9Sstevel@tonic-gate /*
12737c478bd9Sstevel@tonic-gate  * arguments to rename
12747c478bd9Sstevel@tonic-gate  */
12757c478bd9Sstevel@tonic-gate bool_t
xdr_rnmargs(XDR * xdrs,struct nfsrnmargs * argp)12767c478bd9Sstevel@tonic-gate xdr_rnmargs(XDR *xdrs, struct nfsrnmargs *argp)
12777c478bd9Sstevel@tonic-gate {
12787c478bd9Sstevel@tonic-gate 	if (xdr_diropargs(xdrs, &argp->rna_from) &&
12797c478bd9Sstevel@tonic-gate 	    xdr_diropargs(xdrs, &argp->rna_to))
12807c478bd9Sstevel@tonic-gate 		return (TRUE);
12817c478bd9Sstevel@tonic-gate 	return (FALSE);
12827c478bd9Sstevel@tonic-gate }
12837c478bd9Sstevel@tonic-gate 
12847c478bd9Sstevel@tonic-gate 
12857c478bd9Sstevel@tonic-gate /*
12867c478bd9Sstevel@tonic-gate  * arguments to symlink
12877c478bd9Sstevel@tonic-gate  */
12887c478bd9Sstevel@tonic-gate bool_t
xdr_slargs(XDR * xdrs,struct nfsslargs * argp)12897c478bd9Sstevel@tonic-gate xdr_slargs(XDR *xdrs, struct nfsslargs *argp)
12907c478bd9Sstevel@tonic-gate {
12917c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE) {
12927c478bd9Sstevel@tonic-gate 		if (!xdr_diropargs(xdrs, &argp->sla_from))
12937c478bd9Sstevel@tonic-gate 			return (FALSE);
12947c478bd9Sstevel@tonic-gate 		if ((argp->sla_tnm_flags & SLA_FREETNM) &&
12957c478bd9Sstevel@tonic-gate 		    !xdr_string(xdrs, &argp->sla_tnm, (uint_t)NFS_MAXPATHLEN))
12967c478bd9Sstevel@tonic-gate 			return (FALSE);
12977c478bd9Sstevel@tonic-gate 		return (TRUE);
12987c478bd9Sstevel@tonic-gate 	}
12997c478bd9Sstevel@tonic-gate 
13007c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
13017c478bd9Sstevel@tonic-gate 		argp->sla_sa = &argp->sla_sa_buf;
13027c478bd9Sstevel@tonic-gate 		if (argp->sla_tnm == NULL)
13037c478bd9Sstevel@tonic-gate 			argp->sla_tnm_flags |= SLA_FREETNM;
13047c478bd9Sstevel@tonic-gate 	}
13057c478bd9Sstevel@tonic-gate 
13067c478bd9Sstevel@tonic-gate 	if (xdr_diropargs(xdrs, &argp->sla_from) &&
13077c478bd9Sstevel@tonic-gate 	    xdr_string(xdrs, &argp->sla_tnm, (uint_t)NFS_MAXPATHLEN) &&
13087c478bd9Sstevel@tonic-gate 	    xdr_sattr(xdrs, argp->sla_sa)) {
13097c478bd9Sstevel@tonic-gate 		return (TRUE);
13107c478bd9Sstevel@tonic-gate 	}
13117c478bd9Sstevel@tonic-gate 	return (FALSE);
13127c478bd9Sstevel@tonic-gate }
13137c478bd9Sstevel@tonic-gate 
13147c478bd9Sstevel@tonic-gate 
13157c478bd9Sstevel@tonic-gate /*
13167c478bd9Sstevel@tonic-gate  * NFS_OK part of statfs operation
13177c478bd9Sstevel@tonic-gate  */
13187c478bd9Sstevel@tonic-gate bool_t
xdr_fsok(XDR * xdrs,struct nfsstatfsok * fsok)13197c478bd9Sstevel@tonic-gate xdr_fsok(XDR *xdrs, struct nfsstatfsok *fsok)
13207c478bd9Sstevel@tonic-gate {
13217c478bd9Sstevel@tonic-gate 	int32_t *ptr;
13227c478bd9Sstevel@tonic-gate 
13237c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
13247c478bd9Sstevel@tonic-gate 		return (TRUE);
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT);
13277c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
13287c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
13297c478bd9Sstevel@tonic-gate 			fsok->fsok_tsize = IXDR_GET_INT32(ptr);
13307c478bd9Sstevel@tonic-gate 			fsok->fsok_bsize = IXDR_GET_INT32(ptr);
13317c478bd9Sstevel@tonic-gate 			fsok->fsok_blocks = IXDR_GET_INT32(ptr);
13327c478bd9Sstevel@tonic-gate 			fsok->fsok_bfree = IXDR_GET_INT32(ptr);
13337c478bd9Sstevel@tonic-gate 			fsok->fsok_bavail = IXDR_GET_INT32(ptr);
13347c478bd9Sstevel@tonic-gate 		} else {
13357c478bd9Sstevel@tonic-gate 			IXDR_PUT_INT32(ptr, fsok->fsok_tsize);
13367c478bd9Sstevel@tonic-gate 			IXDR_PUT_INT32(ptr, fsok->fsok_bsize);
13377c478bd9Sstevel@tonic-gate 			IXDR_PUT_INT32(ptr, fsok->fsok_blocks);
13387c478bd9Sstevel@tonic-gate 			IXDR_PUT_INT32(ptr, fsok->fsok_bfree);
13397c478bd9Sstevel@tonic-gate 			IXDR_PUT_INT32(ptr, fsok->fsok_bavail);
13407c478bd9Sstevel@tonic-gate 		}
13417c478bd9Sstevel@tonic-gate 		return (TRUE);
13427c478bd9Sstevel@tonic-gate 	}
13437c478bd9Sstevel@tonic-gate 
13447c478bd9Sstevel@tonic-gate 	if (xdr_u_int(xdrs, &fsok->fsok_tsize) &&
13457c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &fsok->fsok_bsize) &&
13467c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &fsok->fsok_blocks) &&
13477c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &fsok->fsok_bfree) &&
13487c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &fsok->fsok_bavail)) {
13497c478bd9Sstevel@tonic-gate 		return (TRUE);
13507c478bd9Sstevel@tonic-gate 	}
13517c478bd9Sstevel@tonic-gate 	return (FALSE);
13527c478bd9Sstevel@tonic-gate }
13537c478bd9Sstevel@tonic-gate 
13547c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
13557c478bd9Sstevel@tonic-gate bool_t
xdr_fastfsok(XDR * xdrs,struct nfsstatfsok * fsok)13567c478bd9Sstevel@tonic-gate xdr_fastfsok(XDR *xdrs, struct nfsstatfsok *fsok)
13577c478bd9Sstevel@tonic-gate {
13587c478bd9Sstevel@tonic-gate 
13597c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
13607c478bd9Sstevel@tonic-gate 		return (TRUE);
13617c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
13627c478bd9Sstevel@tonic-gate 		return (FALSE);
13637c478bd9Sstevel@tonic-gate 
13647c478bd9Sstevel@tonic-gate 	fsok->fsok_tsize = htonl(fsok->fsok_tsize);
13657c478bd9Sstevel@tonic-gate 	fsok->fsok_bsize = htonl(fsok->fsok_bsize);
13667c478bd9Sstevel@tonic-gate 	fsok->fsok_blocks = htonl(fsok->fsok_blocks);
13677c478bd9Sstevel@tonic-gate 	fsok->fsok_bfree = htonl(fsok->fsok_bfree);
13687c478bd9Sstevel@tonic-gate 	fsok->fsok_bavail = htonl(fsok->fsok_bavail);
13697c478bd9Sstevel@tonic-gate 	return (TRUE);
13707c478bd9Sstevel@tonic-gate }
13717c478bd9Sstevel@tonic-gate #endif
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate static struct xdr_discrim statfs_discrim[2] = {
13747c478bd9Sstevel@tonic-gate 	{ NFS_OK, xdr_fsok },
13757c478bd9Sstevel@tonic-gate 	{ __dontcare__, NULL_xdrproc_t }
13767c478bd9Sstevel@tonic-gate };
13777c478bd9Sstevel@tonic-gate 
13787c478bd9Sstevel@tonic-gate /*
13797c478bd9Sstevel@tonic-gate  * Results of statfs operation
13807c478bd9Sstevel@tonic-gate  */
13817c478bd9Sstevel@tonic-gate bool_t
xdr_statfs(XDR * xdrs,struct nfsstatfs * fs)13827c478bd9Sstevel@tonic-gate xdr_statfs(XDR *xdrs, struct nfsstatfs *fs)
13837c478bd9Sstevel@tonic-gate {
13847c478bd9Sstevel@tonic-gate 	return (xdr_union(xdrs, (enum_t *)&(fs->fs_status),
13857c478bd9Sstevel@tonic-gate 	    (caddr_t)&(fs->fs_fsok), statfs_discrim, xdr_void));
13867c478bd9Sstevel@tonic-gate }
13877c478bd9Sstevel@tonic-gate 
13887c478bd9Sstevel@tonic-gate /*
13897c478bd9Sstevel@tonic-gate  * Results of statfs operation
13907c478bd9Sstevel@tonic-gate  */
13917c478bd9Sstevel@tonic-gate bool_t
xdr_faststatfs(XDR * xdrs,struct nfsstatfs * fs)13927c478bd9Sstevel@tonic-gate xdr_faststatfs(XDR *xdrs, struct nfsstatfs *fs)
13937c478bd9Sstevel@tonic-gate {
13947c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
13957c478bd9Sstevel@tonic-gate 	/*
13967c478bd9Sstevel@tonic-gate 	 * we deal with the discriminator;  it's an enum
13977c478bd9Sstevel@tonic-gate 	 */
13987c478bd9Sstevel@tonic-gate 	if (!xdr_fastenum(xdrs, (enum_t *)&fs->fs_status))
13997c478bd9Sstevel@tonic-gate 		return (FALSE);
14007c478bd9Sstevel@tonic-gate 
14017c478bd9Sstevel@tonic-gate 	if (fs->fs_status == NFS_OK)
14027c478bd9Sstevel@tonic-gate 		return (xdr_fastfsok(xdrs, &fs->fs_fsok));
14037c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
14047c478bd9Sstevel@tonic-gate 	if (fs->fs_status == NFS_OK)
14057c478bd9Sstevel@tonic-gate 		return (TRUE);
14067c478bd9Sstevel@tonic-gate #endif
14077c478bd9Sstevel@tonic-gate 	return (xdr_fastshorten(xdrs, sizeof (*fs)));
14087c478bd9Sstevel@tonic-gate }
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
14117c478bd9Sstevel@tonic-gate /*
14127c478bd9Sstevel@tonic-gate  * XDR enumerations
14137c478bd9Sstevel@tonic-gate  */
14147c478bd9Sstevel@tonic-gate #ifndef lint
14157c478bd9Sstevel@tonic-gate static enum sizecheck { SIZEVAL } sizecheckvar;	/* used to find the size of */
14167c478bd9Sstevel@tonic-gate 						/* an enum */
14177c478bd9Sstevel@tonic-gate #endif
14187c478bd9Sstevel@tonic-gate bool_t
xdr_fastenum(XDR * xdrs,enum_t * ep)14197c478bd9Sstevel@tonic-gate xdr_fastenum(XDR *xdrs, enum_t *ep)
14207c478bd9Sstevel@tonic-gate {
14217c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
14227c478bd9Sstevel@tonic-gate 		return (TRUE);
14237c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
14247c478bd9Sstevel@tonic-gate 		return (FALSE);
14257c478bd9Sstevel@tonic-gate 
14267c478bd9Sstevel@tonic-gate #ifndef lint
14277c478bd9Sstevel@tonic-gate 	/*
14287c478bd9Sstevel@tonic-gate 	 * enums are treated as ints
14297c478bd9Sstevel@tonic-gate 	 */
14307c478bd9Sstevel@tonic-gate 	if (sizeof (sizecheckvar) == sizeof (int32_t)) {
14317c478bd9Sstevel@tonic-gate 		*ep = (enum_t)htonl((int32_t)(*ep));
14327c478bd9Sstevel@tonic-gate 	} else if (sizeof (sizecheckvar) == sizeof (short)) {
14337c478bd9Sstevel@tonic-gate 		*ep = (enum_t)htons((short)(*ep));
14347c478bd9Sstevel@tonic-gate 	} else {
14357c478bd9Sstevel@tonic-gate 		return (FALSE);
14367c478bd9Sstevel@tonic-gate 	}
14377c478bd9Sstevel@tonic-gate 	return (TRUE);
14387c478bd9Sstevel@tonic-gate #else
14397c478bd9Sstevel@tonic-gate 	(void) (xdr_short(xdrs, (short *)ep));
14407c478bd9Sstevel@tonic-gate 	return (xdr_int(xdrs, (int *)ep));
14417c478bd9Sstevel@tonic-gate #endif
14427c478bd9Sstevel@tonic-gate }
14437c478bd9Sstevel@tonic-gate #endif
14447c478bd9Sstevel@tonic-gate 
14457c478bd9Sstevel@tonic-gate static bool_t
xdr_fastshorten(XDR * xdrs,uint_t ressize)14467c478bd9Sstevel@tonic-gate xdr_fastshorten(XDR *xdrs, uint_t ressize)
14477c478bd9Sstevel@tonic-gate {
14487c478bd9Sstevel@tonic-gate 	uint_t curpos;
14497c478bd9Sstevel@tonic-gate 
14507c478bd9Sstevel@tonic-gate 	curpos = XDR_GETPOS(xdrs);
14517c478bd9Sstevel@tonic-gate 	ressize -= BYTES_PER_XDR_UNIT;
14527c478bd9Sstevel@tonic-gate 	curpos -= ressize;
14537c478bd9Sstevel@tonic-gate 	return (XDR_SETPOS(xdrs, curpos));
14547c478bd9Sstevel@tonic-gate }
1455