nfs_common.h revision 48125
11541Srgrimes/*
21541Srgrimes * Copyright (c) 1989, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * This code is derived from software contributed to Berkeley by
61541Srgrimes * Rick Macklem at The University of Guelph.
71541Srgrimes *
81541Srgrimes * Redistribution and use in source and binary forms, with or without
91541Srgrimes * modification, are permitted provided that the following conditions
101541Srgrimes * are met:
111541Srgrimes * 1. Redistributions of source code must retain the above copyright
121541Srgrimes *    notice, this list of conditions and the following disclaimer.
131541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
141541Srgrimes *    notice, this list of conditions and the following disclaimer in the
151541Srgrimes *    documentation and/or other materials provided with the distribution.
161541Srgrimes * 3. All advertising materials mentioning features or use of this software
171541Srgrimes *    must display the following acknowledgement:
181541Srgrimes *	This product includes software developed by the University of
191541Srgrimes *	California, Berkeley and its contributors.
201541Srgrimes * 4. Neither the name of the University nor the names of its contributors
211541Srgrimes *    may be used to endorse or promote products derived from this software
221541Srgrimes *    without specific prior written permission.
231541Srgrimes *
241541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
251541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
271541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
281541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
291541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
301541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
311541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
321541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
331541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
341541Srgrimes * SUCH DAMAGE.
351541Srgrimes *
3622521Sdyson *	@(#)nfsm_subs.h	8.2 (Berkeley) 3/30/95
3748125Sjulian * $Id: nfsm_subs.h,v 1.23 1999/06/05 05:35:03 peter Exp $
381541Srgrimes */
391541Srgrimes
4022521Sdyson
412175Spaul#ifndef _NFS_NFSM_SUBS_H_
422175Spaul#define _NFS_NFSM_SUBS_H_
432175Spaul
4433054Sbdestruct ucred;
4533054Sbdestruct vnode;
469336Sdfr
471541Srgrimes/*
481541Srgrimes * These macros do strange and peculiar things to mbuf chains for
491541Srgrimes * the assistance of the nfs code. To attempt to use them for any
501541Srgrimes * other purpose will be dangerous. (they make weird assumptions)
511541Srgrimes */
521541Srgrimes
531541Srgrimes/*
541541Srgrimes * First define what the actual subs. return
551541Srgrimes */
5610222Sdfrstruct mbuf *nfsm_reqh __P((struct vnode *vp, u_long procid, int hsiz,
5710222Sdfr			    caddr_t *bposp));
5810222Sdfrstruct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
5910222Sdfr			       int auth_type, int auth_len, char *auth_str,
6010222Sdfr			       int verf_len, char *verf_str,
6110222Sdfr			       struct mbuf *mrest, int mrest_len,
6236541Speter			       struct mbuf **mbp, u_int32_t *xidp));
631541Srgrimes
641541Srgrimes#define	M_HASCL(m)	((m)->m_flags & M_EXT)
651541Srgrimes#define	NFSMINOFF(m) \
661541Srgrimes		if (M_HASCL(m)) \
671541Srgrimes			(m)->m_data = (m)->m_ext.ext_buf; \
681541Srgrimes		else if ((m)->m_flags & M_PKTHDR) \
691541Srgrimes			(m)->m_data = (m)->m_pktdat; \
701541Srgrimes		else \
711541Srgrimes			(m)->m_data = (m)->m_dat
721541Srgrimes#define	NFSMADV(m, s)	(m)->m_data += (s)
731541Srgrimes#define	NFSMSIZ(m)	((M_HASCL(m))?MCLBYTES: \
741541Srgrimes				(((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
751541Srgrimes
761541Srgrimes/*
771541Srgrimes * Now for the macros that do the simple stuff and call the functions
781541Srgrimes * for the hard stuff.
791541Srgrimes * These macros use several vars. declared in nfsm_reqhead and these
801541Srgrimes * vars. must not be used elsewhere unless you are careful not to corrupt
811541Srgrimes * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
821541Srgrimes * that may be used so long as the value is not expected to retained
831541Srgrimes * after a macro.
841541Srgrimes * I know, this is kind of dorkey, but it makes the actual op functions
851541Srgrimes * fairly clean and deals with the mess caused by the xdr discriminating
861541Srgrimes * unions.
871541Srgrimes */
881541Srgrimes
891541Srgrimes#define	nfsm_build(a,c,s) \
901541Srgrimes		{ if ((s) > M_TRAILINGSPACE(mb)) { \
911541Srgrimes			MGET(mb2, M_WAIT, MT_DATA); \
921541Srgrimes			if ((s) > MLEN) \
931541Srgrimes				panic("build > MLEN"); \
941541Srgrimes			mb->m_next = mb2; \
951541Srgrimes			mb = mb2; \
961541Srgrimes			mb->m_len = 0; \
971541Srgrimes			bpos = mtod(mb, caddr_t); \
981541Srgrimes		} \
991541Srgrimes		(a) = (c)(bpos); \
1001541Srgrimes		mb->m_len += (s); \
1011541Srgrimes		bpos += (s); }
1021541Srgrimes
1039336Sdfr#define	nfsm_dissect(a, c, s) \
1041541Srgrimes		{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
1051541Srgrimes		if (t1 >= (s)) { \
1061541Srgrimes			(a) = (c)(dpos); \
1071541Srgrimes			dpos += (s); \
10836503Speter		} else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \
1099336Sdfr			error = t1; \
1109336Sdfr			m_freem(mrep); \
1119336Sdfr			goto nfsmout; \
1121541Srgrimes		} else { \
1139336Sdfr			(a) = (c)cp2; \
1149336Sdfr		} }
1159336Sdfr
1169336Sdfr#define nfsm_fhtom(v, v3) \
1179336Sdfr	      { if (v3) { \
1189336Sdfr			t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \
1199336Sdfr			if (t2 <= M_TRAILINGSPACE(mb)) { \
12036541Speter				nfsm_build(tl, u_int32_t *, t2); \
1219336Sdfr				*tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \
1229336Sdfr				*(tl + ((t2>>2) - 2)) = 0; \
1239336Sdfr				bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
1249336Sdfr					VTONFS(v)->n_fhsize); \
12536503Speter			} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \
12636503Speter				(caddr_t)VTONFS(v)->n_fhp, \
12736503Speter				VTONFS(v)->n_fhsize)) != 0) { \
1289336Sdfr				error = t2; \
1299336Sdfr				m_freem(mreq); \
1303305Sphk				goto nfsmout; \
1313305Sphk			} \
1329336Sdfr		} else { \
1339336Sdfr			nfsm_build(cp, caddr_t, NFSX_V2FH); \
1349336Sdfr			bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \
1351541Srgrimes		} }
1361541Srgrimes
1379336Sdfr#define nfsm_srvfhtom(f, v3) \
1389336Sdfr		{ if (v3) { \
13936541Speter			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3FH); \
1409336Sdfr			*tl++ = txdr_unsigned(NFSX_V3FH); \
1419336Sdfr			bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
1429336Sdfr		} else { \
1439336Sdfr			nfsm_build(cp, caddr_t, NFSX_V2FH); \
1449336Sdfr			bcopy((caddr_t)(f), cp, NFSX_V2FH); \
1459336Sdfr		} }
1461541Srgrimes
1479336Sdfr#define nfsm_srvpostop_fh(f) \
14836541Speter		{ nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
1499336Sdfr		*tl++ = nfs_true; \
1509336Sdfr		*tl++ = txdr_unsigned(NFSX_V3FH); \
1519336Sdfr		bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
1529336Sdfr		}
1531541Srgrimes
1549336Sdfr#define nfsm_mtofh(d, v, v3, f) \
1559336Sdfr		{ struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \
1569336Sdfr		if (v3) { \
15736541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
1589336Sdfr			(f) = fxdr_unsigned(int, *tl); \
1599336Sdfr		} else \
1609336Sdfr			(f) = 1; \
1619336Sdfr		if (f) { \
1629336Sdfr			nfsm_getfh(ttfhp, ttfhsize, (v3)); \
16336503Speter			if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
16436503Speter				&ttnp)) != 0) { \
1659336Sdfr				error = t1; \
1669336Sdfr				m_freem(mrep); \
1679336Sdfr				goto nfsmout; \
1689336Sdfr			} \
1699336Sdfr			(v) = NFSTOV(ttnp); \
1701541Srgrimes		} \
1719336Sdfr		if (v3) { \
17236541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
1739336Sdfr			if (f) \
1749336Sdfr				(f) = fxdr_unsigned(int, *tl); \
1759336Sdfr			else if (fxdr_unsigned(int, *tl)) \
1769336Sdfr				nfsm_adv(NFSX_V3FATTR); \
1779336Sdfr		} \
1789336Sdfr		if (f) \
1799336Sdfr			nfsm_loadattr((v), (struct vattr *)0); \
1801541Srgrimes		}
1811541Srgrimes
1829336Sdfr#define nfsm_getfh(f, s, v3) \
1839336Sdfr		{ if (v3) { \
18436541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
1859336Sdfr			if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \
1869336Sdfr				(s) > NFSX_V3FHMAX) { \
1879336Sdfr				m_freem(mrep); \
1889336Sdfr				error = EBADRPC; \
1899336Sdfr				goto nfsmout; \
1909336Sdfr			} \
1919336Sdfr		} else \
1929336Sdfr			(s) = NFSX_V2FH; \
1939336Sdfr		nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); }
1949336Sdfr
1959336Sdfr#define	nfsm_loadattr(v, a) \
1969336Sdfr		{ struct vnode *ttvp = (v); \
19736503Speter		if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
1989336Sdfr			error = t1; \
1991541Srgrimes			m_freem(mrep); \
2001541Srgrimes			goto nfsmout; \
2011541Srgrimes		} \
2029336Sdfr		(v) = ttvp; }
2031541Srgrimes
2049336Sdfr#define	nfsm_postop_attr(v, f) \
2059336Sdfr		{ struct vnode *ttvp = (v); \
20636541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
20736541Speter		if (((f) = fxdr_unsigned(int, *tl)) != 0) { \
20836503Speter			if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
20936503Speter				(struct vattr *)0)) != 0) { \
2109336Sdfr				error = t1; \
2119336Sdfr				(f) = 0; \
2129336Sdfr				m_freem(mrep); \
2139336Sdfr				goto nfsmout; \
2149336Sdfr			} \
2159336Sdfr			(v) = ttvp; \
2169336Sdfr		} }
2179336Sdfr
2189336Sdfr/* Used as (f) for nfsm_wcc_data() */
2199336Sdfr#define NFSV3_WCCRATTR	0
2209336Sdfr#define NFSV3_WCCCHK	1
2219336Sdfr
2229336Sdfr#define	nfsm_wcc_data(v, f) \
2239336Sdfr		{ int ttattrf, ttretf = 0; \
22436541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
2259336Sdfr		if (*tl == nfs_true) { \
22636541Speter			nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); \
2279336Sdfr			if (f) \
2289336Sdfr				ttretf = (VTONFS(v)->n_mtime == \
22936541Speter					fxdr_unsigned(u_int32_t, *(tl + 2))); \
2309336Sdfr		} \
2319336Sdfr		nfsm_postop_attr((v), ttattrf); \
2329336Sdfr		if (f) { \
2339336Sdfr			(f) = ttretf; \
2349336Sdfr		} else { \
2359336Sdfr			(f) = ttattrf; \
2369336Sdfr		} }
2379336Sdfr
23842060Sdfr/* If full is true, set all fields, otherwise just set mode and time fields */
23942060Sdfr#define nfsm_v3attrbuild(a, full)						\
24042060Sdfr		{ if ((a)->va_mode != (mode_t)VNOVAL) {				\
24142060Sdfr			nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);		\
24242060Sdfr			*tl++ = nfs_true;					\
24342060Sdfr			*tl = txdr_unsigned((a)->va_mode);			\
24442060Sdfr		} else {							\
24542060Sdfr			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);		\
24642060Sdfr			*tl = nfs_false;					\
24742060Sdfr		}								\
24842060Sdfr		if ((full) && (a)->va_uid != (uid_t)VNOVAL) {			\
24942060Sdfr			nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);		\
25042060Sdfr			*tl++ = nfs_true;					\
25142060Sdfr			*tl = txdr_unsigned((a)->va_uid);			\
25242060Sdfr		} else {							\
25342060Sdfr			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);		\
25442060Sdfr			*tl = nfs_false;					\
25542060Sdfr		}								\
25642060Sdfr		if ((full) && (a)->va_gid != (gid_t)VNOVAL) {			\
25742060Sdfr			nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);		\
25842060Sdfr			*tl++ = nfs_true;					\
25942060Sdfr			*tl = txdr_unsigned((a)->va_gid);			\
26042060Sdfr		} else {							\
26142060Sdfr			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);		\
26242060Sdfr			*tl = nfs_false;					\
26342060Sdfr		}								\
26442060Sdfr		if ((full) && (a)->va_size != VNOVAL) {				\
26542060Sdfr			nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);		\
26642060Sdfr			*tl++ = nfs_true;					\
26747751Speter			txdr_hyper((a)->va_size, tl);				\
26842060Sdfr		} else {							\
26942060Sdfr			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);		\
27042060Sdfr			*tl = nfs_false;					\
27142060Sdfr		}								\
27242060Sdfr		if ((a)->va_atime.tv_sec != VNOVAL) {				\
27342060Sdfr			if ((a)->va_atime.tv_sec != time_second) {		\
27442060Sdfr				nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);	\
27542060Sdfr				*tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);	\
27642060Sdfr				txdr_nfsv3time(&(a)->va_atime, tl);		\
27742060Sdfr			} else {						\
27842060Sdfr				nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);	\
27942060Sdfr				*tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER);	\
28042060Sdfr			}							\
28142060Sdfr		} else {							\
28242060Sdfr			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);		\
28342060Sdfr			*tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE);		\
28442060Sdfr		}								\
28542060Sdfr		if ((a)->va_mtime.tv_sec != VNOVAL) {				\
28642060Sdfr			if ((a)->va_mtime.tv_sec != time_second) {		\
28742060Sdfr				nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);	\
28842060Sdfr				*tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);	\
28942060Sdfr				txdr_nfsv3time(&(a)->va_mtime, tl);		\
29042060Sdfr			} else {						\
29142060Sdfr				nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);	\
29242060Sdfr				*tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER);	\
29342060Sdfr			}							\
29442060Sdfr		} else {							\
29542060Sdfr			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);		\
29642060Sdfr			*tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE);		\
29742060Sdfr		}								\
2989336Sdfr		}
29942060Sdfr
3009336Sdfr
3011541Srgrimes#define	nfsm_strsiz(s,m) \
30236541Speter		{ nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
30336541Speter		if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \
3041541Srgrimes			m_freem(mrep); \
3051541Srgrimes			error = EBADRPC; \
3061541Srgrimes			goto nfsmout; \
3071541Srgrimes		} }
3081541Srgrimes
3091541Srgrimes#define	nfsm_srvstrsiz(s,m) \
31036541Speter		{ nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
31136541Speter		if (((s) = fxdr_unsigned(int32_t,*tl)) > (m) || (s) <= 0) { \
3121541Srgrimes			error = EBADRPC; \
3131541Srgrimes			nfsm_reply(0); \
3141541Srgrimes		} }
3151541Srgrimes
3169336Sdfr#define	nfsm_srvnamesiz(s) \
31736541Speter		{ nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
31836541Speter		if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) \
3199336Sdfr			error = NFSERR_NAMETOL; \
3209336Sdfr		if ((s) <= 0) \
3219336Sdfr			error = EBADRPC; \
3229336Sdfr		if (error) \
3239336Sdfr			nfsm_reply(0); \
3249336Sdfr		}
3259336Sdfr
3261541Srgrimes#define nfsm_mtouio(p,s) \
3271541Srgrimes		if ((s) > 0 && \
32836503Speter		   (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
3299336Sdfr			error = t1; \
3301541Srgrimes			m_freem(mrep); \
3311541Srgrimes			goto nfsmout; \
3321541Srgrimes		}
3331541Srgrimes
3341541Srgrimes#define nfsm_uiotom(p,s) \
33536503Speter		if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \
3369336Sdfr			error = t1; \
3371541Srgrimes			m_freem(mreq); \
3381541Srgrimes			goto nfsmout; \
3391541Srgrimes		}
3401541Srgrimes
3411541Srgrimes#define	nfsm_reqhead(v,a,s) \
3421541Srgrimes		mb = mreq = nfsm_reqh((v),(a),(s),&bpos)
3431541Srgrimes
3441541Srgrimes#define nfsm_reqdone	m_freem(mrep); \
3458876Srgrimes		nfsmout:
3461541Srgrimes
3471541Srgrimes#define nfsm_rndup(a)	(((a)+3)&(~0x3))
3481541Srgrimes
3491541Srgrimes#define	nfsm_request(v, t, p, c)	\
35036503Speter		if ((error = nfs_request((v), mreq, (t), (p), \
35136503Speter		   (c), &mrep, &md, &dpos)) != 0) { \
3529336Sdfr			if (error & NFSERR_RETERR) \
3539336Sdfr				error &= ~NFSERR_RETERR; \
3549336Sdfr			else \
3559336Sdfr				goto nfsmout; \
3569336Sdfr		}
3571541Srgrimes
3581541Srgrimes#define	nfsm_strtom(a,s,m) \
3591541Srgrimes		if ((s) > (m)) { \
3601541Srgrimes			m_freem(mreq); \
3611541Srgrimes			error = ENAMETOOLONG; \
3621541Srgrimes			goto nfsmout; \
3631541Srgrimes		} \
3641541Srgrimes		t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
3651541Srgrimes		if (t2 <= M_TRAILINGSPACE(mb)) { \
36636541Speter			nfsm_build(tl,u_int32_t *,t2); \
3671541Srgrimes			*tl++ = txdr_unsigned(s); \
3681541Srgrimes			*(tl+((t2>>2)-2)) = 0; \
36936511Speter			bcopy((const char *)(a), (caddr_t)tl, (s)); \
37036503Speter		} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \
3719336Sdfr			error = t2; \
3729336Sdfr			m_freem(mreq); \
3739336Sdfr			goto nfsmout; \
3741541Srgrimes		}
3751541Srgrimes
3761541Srgrimes#define	nfsm_srvdone \
3771541Srgrimes		nfsmout: \
3781541Srgrimes		return(error)
3791541Srgrimes
3801541Srgrimes#define	nfsm_reply(s) \
3811541Srgrimes		{ \
3821541Srgrimes		nfsd->nd_repstat = error; \
3839336Sdfr		if (error && !(nfsd->nd_flag & ND_NFSV3)) \
3849336Sdfr		   (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
3851541Srgrimes			mrq, &mb, &bpos); \
3861541Srgrimes		else \
3879336Sdfr		   (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
3881541Srgrimes			mrq, &mb, &bpos); \
38936520Speter		if (mrep != NULL) { \
39036520Speter			m_freem(mrep); \
39136520Speter			mrep = NULL; \
39236520Speter		} \
3931541Srgrimes		mreq = *mrq; \
3949336Sdfr		if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
39548125Sjulian			error == EBADRPC)) { \
39648125Sjulian			error = 0; \
39748125Sjulian			goto nfsmout; \
39848125Sjulian		} }
3991541Srgrimes
4009336Sdfr#define	nfsm_writereply(s, v3) \
4019336Sdfr		{ \
4029336Sdfr		nfsd->nd_repstat = error; \
4039336Sdfr		if (error && !(v3)) \
4049336Sdfr		   (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
4059336Sdfr			&mreq, &mb, &bpos); \
4069336Sdfr		else \
4079336Sdfr		   (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
4089336Sdfr			&mreq, &mb, &bpos); \
4099336Sdfr		}
4109336Sdfr
4111541Srgrimes#define	nfsm_adv(s) \
4129336Sdfr		{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
4131541Srgrimes		if (t1 >= (s)) { \
4141541Srgrimes			dpos += (s); \
41536503Speter		} else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \
4169336Sdfr			error = t1; \
4179336Sdfr			m_freem(mrep); \
4189336Sdfr			goto nfsmout; \
4199336Sdfr		} }
4209336Sdfr
4219336Sdfr#define nfsm_srvmtofh(f) \
42227446Sdfr	{ int fhlen = NFSX_V3FH; \
42327446Sdfr		if (nfsd->nd_flag & ND_NFSV3) { \
42436541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
42527446Sdfr			fhlen = fxdr_unsigned(int, *tl); \
42627446Sdfr			if (fhlen == 0) { \
42727446Sdfr				bzero((caddr_t)(f), NFSX_V3FH); \
42827446Sdfr			} else if (fhlen != NFSX_V3FH) { \
4299336Sdfr				error = EBADRPC; \
4309336Sdfr				nfsm_reply(0); \
4313305Sphk			} \
4329336Sdfr		} \
43327446Sdfr		if (fhlen != 0) { \
43436541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_V3FH); \
43527446Sdfr			bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
43627446Sdfr			if ((nfsd->nd_flag & ND_NFSV3) == 0) \
43727446Sdfr				nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
43827446Sdfr		} \
43927446Sdfr	}
4401541Srgrimes
4411541Srgrimes#define	nfsm_clget \
4421541Srgrimes		if (bp >= be) { \
4431541Srgrimes			if (mp == mb) \
4441541Srgrimes				mp->m_len += bp-bpos; \
4451541Srgrimes			MGET(mp, M_WAIT, MT_DATA); \
4461541Srgrimes			MCLGET(mp, M_WAIT); \
4471541Srgrimes			mp->m_len = NFSMSIZ(mp); \
4481541Srgrimes			mp2->m_next = mp; \
4491541Srgrimes			mp2 = mp; \
4501541Srgrimes			bp = mtod(mp, caddr_t); \
4511541Srgrimes			be = bp+mp->m_len; \
4521541Srgrimes		} \
45336541Speter		tl = (u_int32_t *)bp
4541541Srgrimes
4559336Sdfr#define	nfsm_srvfillattr(a, f) \
4569336Sdfr		nfsm_srvfattr(nfsd, (a), (f))
4571541Srgrimes
4589336Sdfr#define nfsm_srvwcc_data(br, b, ar, a) \
4599336Sdfr		nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos)
4609336Sdfr
4619336Sdfr#define nfsm_srvpostop_attr(r, a) \
4629336Sdfr		nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos)
4639336Sdfr
4649336Sdfr#define nfsm_srvsattr(a) \
46536541Speter		{ nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
4669336Sdfr		if (*tl == nfs_true) { \
46736541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
4689336Sdfr			(a)->va_mode = nfstov_mode(*tl); \
4699336Sdfr		} \
47036541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
4719336Sdfr		if (*tl == nfs_true) { \
47236541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
4739336Sdfr			(a)->va_uid = fxdr_unsigned(uid_t, *tl); \
4749336Sdfr		} \
47536541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
4769336Sdfr		if (*tl == nfs_true) { \
47736541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
4789336Sdfr			(a)->va_gid = fxdr_unsigned(gid_t, *tl); \
4799336Sdfr		} \
48036541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
4819336Sdfr		if (*tl == nfs_true) { \
48236541Speter			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
48347751Speter			(a)->va_size = fxdr_hyper(tl); \
4849336Sdfr		} \
48536541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
4869336Sdfr		switch (fxdr_unsigned(int, *tl)) { \
4879336Sdfr		case NFSV3SATTRTIME_TOCLIENT: \
48836541Speter			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
4899336Sdfr			fxdr_nfsv3time(tl, &(a)->va_atime); \
4909336Sdfr			break; \
49136097Sbde		case NFSV3SATTRTIME_TOSERVER: \
49236097Sbde			getnanotime(&(a)->va_atime); \
49336097Sbde			break; \
4949336Sdfr		}; \
49536541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
4969336Sdfr		switch (fxdr_unsigned(int, *tl)) { \
4979336Sdfr		case NFSV3SATTRTIME_TOCLIENT: \
49836541Speter			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
4999336Sdfr			fxdr_nfsv3time(tl, &(a)->va_mtime); \
5009336Sdfr			break; \
50136097Sbde		case NFSV3SATTRTIME_TOSERVER: \
50236097Sbde			getnanotime(&(a)->va_mtime); \
50336097Sbde			break; \
5049336Sdfr		}; }
5059336Sdfr
5062175Spaul#endif
507