nfs_common.h revision 27446
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
3727446Sdfr * $Id: nfsm_subs.h,v 1.12 1997/02/22 09:42:48 peter Exp $
381541Srgrimes */
391541Srgrimes
4022521Sdyson
412175Spaul#ifndef _NFS_NFSM_SUBS_H_
422175Spaul#define _NFS_NFSM_SUBS_H_
432175Spaul
449336Sdfr
451541Srgrimes/*
461541Srgrimes * These macros do strange and peculiar things to mbuf chains for
471541Srgrimes * the assistance of the nfs code. To attempt to use them for any
481541Srgrimes * other purpose will be dangerous. (they make weird assumptions)
491541Srgrimes */
501541Srgrimes
511541Srgrimes/*
521541Srgrimes * First define what the actual subs. return
531541Srgrimes */
5410222Sdfrstruct mbuf *nfsm_reqh __P((struct vnode *vp, u_long procid, int hsiz,
5510222Sdfr			    caddr_t *bposp));
5610222Sdfrstruct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
5710222Sdfr			       int auth_type, int auth_len, char *auth_str,
5810222Sdfr			       int verf_len, char *verf_str,
5910222Sdfr			       struct mbuf *mrest, int mrest_len,
6010222Sdfr			       struct mbuf **mbp, u_long *xidp));
611541Srgrimes
621541Srgrimes#define	M_HASCL(m)	((m)->m_flags & M_EXT)
631541Srgrimes#define	NFSMINOFF(m) \
641541Srgrimes		if (M_HASCL(m)) \
651541Srgrimes			(m)->m_data = (m)->m_ext.ext_buf; \
661541Srgrimes		else if ((m)->m_flags & M_PKTHDR) \
671541Srgrimes			(m)->m_data = (m)->m_pktdat; \
681541Srgrimes		else \
691541Srgrimes			(m)->m_data = (m)->m_dat
701541Srgrimes#define	NFSMADV(m, s)	(m)->m_data += (s)
711541Srgrimes#define	NFSMSIZ(m)	((M_HASCL(m))?MCLBYTES: \
721541Srgrimes				(((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
731541Srgrimes
741541Srgrimes/*
751541Srgrimes * Now for the macros that do the simple stuff and call the functions
761541Srgrimes * for the hard stuff.
771541Srgrimes * These macros use several vars. declared in nfsm_reqhead and these
781541Srgrimes * vars. must not be used elsewhere unless you are careful not to corrupt
791541Srgrimes * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
801541Srgrimes * that may be used so long as the value is not expected to retained
811541Srgrimes * after a macro.
821541Srgrimes * I know, this is kind of dorkey, but it makes the actual op functions
831541Srgrimes * fairly clean and deals with the mess caused by the xdr discriminating
841541Srgrimes * unions.
851541Srgrimes */
861541Srgrimes
871541Srgrimes#define	nfsm_build(a,c,s) \
881541Srgrimes		{ if ((s) > M_TRAILINGSPACE(mb)) { \
891541Srgrimes			MGET(mb2, M_WAIT, MT_DATA); \
901541Srgrimes			if ((s) > MLEN) \
911541Srgrimes				panic("build > MLEN"); \
921541Srgrimes			mb->m_next = mb2; \
931541Srgrimes			mb = mb2; \
941541Srgrimes			mb->m_len = 0; \
951541Srgrimes			bpos = mtod(mb, caddr_t); \
961541Srgrimes		} \
971541Srgrimes		(a) = (c)(bpos); \
981541Srgrimes		mb->m_len += (s); \
991541Srgrimes		bpos += (s); }
1001541Srgrimes
1019336Sdfr#define	nfsm_dissect(a, c, s) \
1021541Srgrimes		{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
1031541Srgrimes		if (t1 >= (s)) { \
1041541Srgrimes			(a) = (c)(dpos); \
1051541Srgrimes			dpos += (s); \
1069336Sdfr		} else if (t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) { \
1079336Sdfr			error = t1; \
1089336Sdfr			m_freem(mrep); \
1099336Sdfr			goto nfsmout; \
1101541Srgrimes		} else { \
1119336Sdfr			(a) = (c)cp2; \
1129336Sdfr		} }
1139336Sdfr
1149336Sdfr#define nfsm_fhtom(v, v3) \
1159336Sdfr	      { if (v3) { \
1169336Sdfr			t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \
1179336Sdfr			if (t2 <= M_TRAILINGSPACE(mb)) { \
1189336Sdfr				nfsm_build(tl, u_long *, t2); \
1199336Sdfr				*tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \
1209336Sdfr				*(tl + ((t2>>2) - 2)) = 0; \
1219336Sdfr				bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
1229336Sdfr					VTONFS(v)->n_fhsize); \
1239336Sdfr			} else if (t2 = nfsm_strtmbuf(&mb, &bpos, \
1249336Sdfr				(caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize)) { \
1259336Sdfr				error = t2; \
1269336Sdfr				m_freem(mreq); \
1273305Sphk				goto nfsmout; \
1283305Sphk			} \
1299336Sdfr		} else { \
1309336Sdfr			nfsm_build(cp, caddr_t, NFSX_V2FH); \
1319336Sdfr			bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \
1321541Srgrimes		} }
1331541Srgrimes
1349336Sdfr#define nfsm_srvfhtom(f, v3) \
1359336Sdfr		{ if (v3) { \
1369336Sdfr			nfsm_build(tl, u_long *, NFSX_UNSIGNED + NFSX_V3FH); \
1379336Sdfr			*tl++ = txdr_unsigned(NFSX_V3FH); \
1389336Sdfr			bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
1399336Sdfr		} else { \
1409336Sdfr			nfsm_build(cp, caddr_t, NFSX_V2FH); \
1419336Sdfr			bcopy((caddr_t)(f), cp, NFSX_V2FH); \
1429336Sdfr		} }
1431541Srgrimes
1449336Sdfr#define nfsm_srvpostop_fh(f) \
1459336Sdfr		{ nfsm_build(tl, u_long *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
1469336Sdfr		*tl++ = nfs_true; \
1479336Sdfr		*tl++ = txdr_unsigned(NFSX_V3FH); \
1489336Sdfr		bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
1499336Sdfr		}
1501541Srgrimes
1519336Sdfr#define nfsm_mtofh(d, v, v3, f) \
1529336Sdfr		{ struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \
1539336Sdfr		if (v3) { \
1549336Sdfr			nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
1559336Sdfr			(f) = fxdr_unsigned(int, *tl); \
1569336Sdfr		} else \
1579336Sdfr			(f) = 1; \
1589336Sdfr		if (f) { \
1599336Sdfr			nfsm_getfh(ttfhp, ttfhsize, (v3)); \
1609336Sdfr			if (t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
1619336Sdfr				&ttnp)) { \
1629336Sdfr				error = t1; \
1639336Sdfr				m_freem(mrep); \
1649336Sdfr				goto nfsmout; \
1659336Sdfr			} \
1669336Sdfr			(v) = NFSTOV(ttnp); \
1671541Srgrimes		} \
1689336Sdfr		if (v3) { \
1699336Sdfr			nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
1709336Sdfr			if (f) \
1719336Sdfr				(f) = fxdr_unsigned(int, *tl); \
1729336Sdfr			else if (fxdr_unsigned(int, *tl)) \
1739336Sdfr				nfsm_adv(NFSX_V3FATTR); \
1749336Sdfr		} \
1759336Sdfr		if (f) \
1769336Sdfr			nfsm_loadattr((v), (struct vattr *)0); \
1771541Srgrimes		}
1781541Srgrimes
1799336Sdfr#define nfsm_getfh(f, s, v3) \
1809336Sdfr		{ if (v3) { \
1819336Sdfr			nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
1829336Sdfr			if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \
1839336Sdfr				(s) > NFSX_V3FHMAX) { \
1849336Sdfr				m_freem(mrep); \
1859336Sdfr				error = EBADRPC; \
1869336Sdfr				goto nfsmout; \
1879336Sdfr			} \
1889336Sdfr		} else \
1899336Sdfr			(s) = NFSX_V2FH; \
1909336Sdfr		nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); }
1919336Sdfr
1929336Sdfr#define	nfsm_loadattr(v, a) \
1939336Sdfr		{ struct vnode *ttvp = (v); \
1949336Sdfr		if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) { \
1959336Sdfr			error = t1; \
1961541Srgrimes			m_freem(mrep); \
1971541Srgrimes			goto nfsmout; \
1981541Srgrimes		} \
1999336Sdfr		(v) = ttvp; }
2001541Srgrimes
2019336Sdfr#define	nfsm_postop_attr(v, f) \
2029336Sdfr		{ struct vnode *ttvp = (v); \
2039336Sdfr		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
2049336Sdfr		if ((f) = fxdr_unsigned(int, *tl)) { \
2059336Sdfr			if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
2069336Sdfr				(struct vattr *)0)) { \
2079336Sdfr				error = t1; \
2089336Sdfr				(f) = 0; \
2099336Sdfr				m_freem(mrep); \
2109336Sdfr				goto nfsmout; \
2119336Sdfr			} \
2129336Sdfr			(v) = ttvp; \
2139336Sdfr		} }
2149336Sdfr
2159336Sdfr/* Used as (f) for nfsm_wcc_data() */
2169336Sdfr#define NFSV3_WCCRATTR	0
2179336Sdfr#define NFSV3_WCCCHK	1
2189336Sdfr
2199336Sdfr#define	nfsm_wcc_data(v, f) \
2209336Sdfr		{ int ttattrf, ttretf = 0; \
2219336Sdfr		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
2229336Sdfr		if (*tl == nfs_true) { \
2239336Sdfr			nfsm_dissect(tl, u_long *, 6 * NFSX_UNSIGNED); \
2249336Sdfr			if (f) \
2259336Sdfr				ttretf = (VTONFS(v)->n_mtime == \
2269336Sdfr					fxdr_unsigned(u_long, *(tl + 2))); \
2279336Sdfr		} \
2289336Sdfr		nfsm_postop_attr((v), ttattrf); \
2299336Sdfr		if (f) { \
2309336Sdfr			(f) = ttretf; \
2319336Sdfr		} else { \
2329336Sdfr			(f) = ttattrf; \
2339336Sdfr		} }
2349336Sdfr
2359336Sdfr#define nfsm_v3sattr(s, a, u, g) \
2369336Sdfr		{ (s)->sa_modetrue = nfs_true; \
2379336Sdfr		(s)->sa_mode = vtonfsv3_mode((a)->va_mode); \
2389336Sdfr		(s)->sa_uidtrue = nfs_true; \
2399336Sdfr		(s)->sa_uid = txdr_unsigned(u); \
2409336Sdfr		(s)->sa_gidtrue = nfs_true; \
2419336Sdfr		(s)->sa_gid = txdr_unsigned(g); \
2429336Sdfr		(s)->sa_sizefalse = nfs_false; \
2439336Sdfr		(s)->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
2449336Sdfr		txdr_nfsv3time(&(a)->va_atime, &(s)->sa_atime); \
2459336Sdfr		(s)->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
2469336Sdfr		txdr_nfsv3time(&(a)->va_mtime, &(s)->sa_mtime); \
2479336Sdfr		}
2489336Sdfr
2491541Srgrimes#define	nfsm_strsiz(s,m) \
2501541Srgrimes		{ nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
2511541Srgrimes		if (((s) = fxdr_unsigned(long,*tl)) > (m)) { \
2521541Srgrimes			m_freem(mrep); \
2531541Srgrimes			error = EBADRPC; \
2541541Srgrimes			goto nfsmout; \
2551541Srgrimes		} }
2561541Srgrimes
2571541Srgrimes#define	nfsm_srvstrsiz(s,m) \
2581541Srgrimes		{ nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
2591541Srgrimes		if (((s) = fxdr_unsigned(long,*tl)) > (m) || (s) <= 0) { \
2601541Srgrimes			error = EBADRPC; \
2611541Srgrimes			nfsm_reply(0); \
2621541Srgrimes		} }
2631541Srgrimes
2649336Sdfr#define	nfsm_srvnamesiz(s) \
2659336Sdfr		{ nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
2669336Sdfr		if (((s) = fxdr_unsigned(long,*tl)) > NFS_MAXNAMLEN) \
2679336Sdfr			error = NFSERR_NAMETOL; \
2689336Sdfr		if ((s) <= 0) \
2699336Sdfr			error = EBADRPC; \
2709336Sdfr		if (error) \
2719336Sdfr			nfsm_reply(0); \
2729336Sdfr		}
2739336Sdfr
2741541Srgrimes#define nfsm_mtouio(p,s) \
2751541Srgrimes		if ((s) > 0 && \
2769336Sdfr		   (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
2779336Sdfr			error = t1; \
2781541Srgrimes			m_freem(mrep); \
2791541Srgrimes			goto nfsmout; \
2801541Srgrimes		}
2811541Srgrimes
2821541Srgrimes#define nfsm_uiotom(p,s) \
2839336Sdfr		if (t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
2849336Sdfr			error = t1; \
2851541Srgrimes			m_freem(mreq); \
2861541Srgrimes			goto nfsmout; \
2871541Srgrimes		}
2881541Srgrimes
2891541Srgrimes#define	nfsm_reqhead(v,a,s) \
2901541Srgrimes		mb = mreq = nfsm_reqh((v),(a),(s),&bpos)
2911541Srgrimes
2921541Srgrimes#define nfsm_reqdone	m_freem(mrep); \
2938876Srgrimes		nfsmout:
2941541Srgrimes
2951541Srgrimes#define nfsm_rndup(a)	(((a)+3)&(~0x3))
2961541Srgrimes
2971541Srgrimes#define	nfsm_request(v, t, p, c)	\
2989336Sdfr		if (error = nfs_request((v), mreq, (t), (p), \
2999336Sdfr		   (c), &mrep, &md, &dpos)) { \
3009336Sdfr			if (error & NFSERR_RETERR) \
3019336Sdfr				error &= ~NFSERR_RETERR; \
3029336Sdfr			else \
3039336Sdfr				goto nfsmout; \
3049336Sdfr		}
3051541Srgrimes
3061541Srgrimes#define	nfsm_strtom(a,s,m) \
3071541Srgrimes		if ((s) > (m)) { \
3081541Srgrimes			m_freem(mreq); \
3091541Srgrimes			error = ENAMETOOLONG; \
3101541Srgrimes			goto nfsmout; \
3111541Srgrimes		} \
3121541Srgrimes		t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
3131541Srgrimes		if (t2 <= M_TRAILINGSPACE(mb)) { \
3141541Srgrimes			nfsm_build(tl,u_long *,t2); \
3151541Srgrimes			*tl++ = txdr_unsigned(s); \
3161541Srgrimes			*(tl+((t2>>2)-2)) = 0; \
3171541Srgrimes			bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
3189336Sdfr		} else if (t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
3199336Sdfr			error = t2; \
3209336Sdfr			m_freem(mreq); \
3219336Sdfr			goto nfsmout; \
3221541Srgrimes		}
3231541Srgrimes
3241541Srgrimes#define	nfsm_srvdone \
3251541Srgrimes		nfsmout: \
3261541Srgrimes		return(error)
3271541Srgrimes
3281541Srgrimes#define	nfsm_reply(s) \
3291541Srgrimes		{ \
3301541Srgrimes		nfsd->nd_repstat = error; \
3319336Sdfr		if (error && !(nfsd->nd_flag & ND_NFSV3)) \
3329336Sdfr		   (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
3331541Srgrimes			mrq, &mb, &bpos); \
3341541Srgrimes		else \
3359336Sdfr		   (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
3361541Srgrimes			mrq, &mb, &bpos); \
3371541Srgrimes		m_freem(mrep); \
3381541Srgrimes		mreq = *mrq; \
3399336Sdfr		if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
3409336Sdfr			error == EBADRPC)) \
3411541Srgrimes			return(0); \
3421541Srgrimes		}
3431541Srgrimes
3449336Sdfr#define	nfsm_writereply(s, v3) \
3459336Sdfr		{ \
3469336Sdfr		nfsd->nd_repstat = error; \
3479336Sdfr		if (error && !(v3)) \
3489336Sdfr		   (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
3499336Sdfr			&mreq, &mb, &bpos); \
3509336Sdfr		else \
3519336Sdfr		   (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
3529336Sdfr			&mreq, &mb, &bpos); \
3539336Sdfr		}
3549336Sdfr
3551541Srgrimes#define	nfsm_adv(s) \
3569336Sdfr		{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
3571541Srgrimes		if (t1 >= (s)) { \
3581541Srgrimes			dpos += (s); \
3599336Sdfr		} else if (t1 = nfs_adv(&md, &dpos, (s), t1)) { \
3609336Sdfr			error = t1; \
3619336Sdfr			m_freem(mrep); \
3629336Sdfr			goto nfsmout; \
3639336Sdfr		} }
3649336Sdfr
3659336Sdfr#define nfsm_srvmtofh(f) \
36627446Sdfr	{ int fhlen = NFSX_V3FH; \
36727446Sdfr		if (nfsd->nd_flag & ND_NFSV3) { \
3689336Sdfr			nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
36927446Sdfr			fhlen = fxdr_unsigned(int, *tl); \
37027446Sdfr			if (fhlen == 0) { \
37127446Sdfr				bzero((caddr_t)(f), NFSX_V3FH); \
37227446Sdfr			} else if (fhlen != NFSX_V3FH) { \
3739336Sdfr				error = EBADRPC; \
3749336Sdfr				nfsm_reply(0); \
3753305Sphk			} \
3769336Sdfr		} \
37727446Sdfr		if (fhlen != 0) { \
37827446Sdfr			nfsm_dissect(tl, u_long *, NFSX_V3FH); \
37927446Sdfr			bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
38027446Sdfr			if ((nfsd->nd_flag & ND_NFSV3) == 0) \
38127446Sdfr				nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
38227446Sdfr		} \
38327446Sdfr	}
3841541Srgrimes
3851541Srgrimes#define	nfsm_clget \
3861541Srgrimes		if (bp >= be) { \
3871541Srgrimes			if (mp == mb) \
3881541Srgrimes				mp->m_len += bp-bpos; \
3891541Srgrimes			MGET(mp, M_WAIT, MT_DATA); \
3901541Srgrimes			MCLGET(mp, M_WAIT); \
3911541Srgrimes			mp->m_len = NFSMSIZ(mp); \
3921541Srgrimes			mp2->m_next = mp; \
3931541Srgrimes			mp2 = mp; \
3941541Srgrimes			bp = mtod(mp, caddr_t); \
3951541Srgrimes			be = bp+mp->m_len; \
3961541Srgrimes		} \
3971541Srgrimes		tl = (u_long *)bp
3981541Srgrimes
3999336Sdfr#define	nfsm_srvfillattr(a, f) \
4009336Sdfr		nfsm_srvfattr(nfsd, (a), (f))
4011541Srgrimes
4029336Sdfr#define nfsm_srvwcc_data(br, b, ar, a) \
4039336Sdfr		nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos)
4049336Sdfr
4059336Sdfr#define nfsm_srvpostop_attr(r, a) \
4069336Sdfr		nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos)
4079336Sdfr
4089336Sdfr#define nfsm_srvsattr(a) \
4099336Sdfr		{ nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
4109336Sdfr		if (*tl == nfs_true) { \
4119336Sdfr			nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
4129336Sdfr			(a)->va_mode = nfstov_mode(*tl); \
4139336Sdfr		} \
4149336Sdfr		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
4159336Sdfr		if (*tl == nfs_true) { \
4169336Sdfr			nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
4179336Sdfr			(a)->va_uid = fxdr_unsigned(uid_t, *tl); \
4189336Sdfr		} \
4199336Sdfr		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
4209336Sdfr		if (*tl == nfs_true) { \
4219336Sdfr			nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
4229336Sdfr			(a)->va_gid = fxdr_unsigned(gid_t, *tl); \
4239336Sdfr		} \
4249336Sdfr		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
4259336Sdfr		if (*tl == nfs_true) { \
4269336Sdfr			nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
4279336Sdfr			fxdr_hyper(tl, &(a)->va_size); \
4289336Sdfr		} \
4299336Sdfr		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
4309336Sdfr		switch (fxdr_unsigned(int, *tl)) { \
4319336Sdfr		case NFSV3SATTRTIME_TOCLIENT: \
4329336Sdfr			nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
4339336Sdfr			fxdr_nfsv3time(tl, &(a)->va_atime); \
4349336Sdfr			break; \
4359336Sdfr		case NFSV3SATTRTIME_TOSERVER: \
43618397Snate			(a)->va_atime.tv_sec = time.tv_sec; \
43718397Snate			(a)->va_atime.tv_nsec = time.tv_usec * 1000; \
4389336Sdfr			break; \
4399336Sdfr		}; \
4409336Sdfr		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
4419336Sdfr		switch (fxdr_unsigned(int, *tl)) { \
4429336Sdfr		case NFSV3SATTRTIME_TOCLIENT: \
4439336Sdfr			nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
4449336Sdfr			fxdr_nfsv3time(tl, &(a)->va_mtime); \
4459336Sdfr			break; \
4469336Sdfr		case NFSV3SATTRTIME_TOSERVER: \
44718397Snate			(a)->va_mtime.tv_sec = time.tv_sec; \
44818397Snate			(a)->va_mtime.tv_nsec = time.tv_usec * 1000; \
4499336Sdfr			break; \
4509336Sdfr		}; }
4519336Sdfr
4522175Spaul#endif
453