nfs_common.h revision 50477
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
3750477Speter * $FreeBSD: head/sys/nfs/nfs_common.h 50477 1999-08-28 01:08:13Z peter $
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) \
6650053Speter	do { \
671541Srgrimes		if (M_HASCL(m)) \
681541Srgrimes			(m)->m_data = (m)->m_ext.ext_buf; \
691541Srgrimes		else if ((m)->m_flags & M_PKTHDR) \
701541Srgrimes			(m)->m_data = (m)->m_pktdat; \
711541Srgrimes		else \
7250053Speter			(m)->m_data = (m)->m_dat; \
7350053Speter	} while (0)
7450053Speter#define	NFSMADV(m, s) \
7550053Speter	do { \
7650053Speter		(m)->m_data += (s); \
7750053Speter	} while (0)
781541Srgrimes#define	NFSMSIZ(m)	((M_HASCL(m))?MCLBYTES: \
791541Srgrimes				(((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
801541Srgrimes
811541Srgrimes/*
821541Srgrimes * Now for the macros that do the simple stuff and call the functions
831541Srgrimes * for the hard stuff.
841541Srgrimes * These macros use several vars. declared in nfsm_reqhead and these
851541Srgrimes * vars. must not be used elsewhere unless you are careful not to corrupt
861541Srgrimes * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
871541Srgrimes * that may be used so long as the value is not expected to retained
881541Srgrimes * after a macro.
891541Srgrimes * I know, this is kind of dorkey, but it makes the actual op functions
901541Srgrimes * fairly clean and deals with the mess caused by the xdr discriminating
911541Srgrimes * unions.
921541Srgrimes */
931541Srgrimes
941541Srgrimes#define	nfsm_build(a,c,s) \
9550053Speter	do { \
9650053Speter		if ((s) > M_TRAILINGSPACE(mb)) { \
971541Srgrimes			MGET(mb2, M_WAIT, MT_DATA); \
981541Srgrimes			if ((s) > MLEN) \
991541Srgrimes				panic("build > MLEN"); \
1001541Srgrimes			mb->m_next = mb2; \
1011541Srgrimes			mb = mb2; \
1021541Srgrimes			mb->m_len = 0; \
1031541Srgrimes			bpos = mtod(mb, caddr_t); \
1041541Srgrimes		} \
1051541Srgrimes		(a) = (c)(bpos); \
1061541Srgrimes		mb->m_len += (s); \
10750053Speter		bpos += (s); \
10850053Speter	} while (0)
1091541Srgrimes
1109336Sdfr#define	nfsm_dissect(a, c, s) \
11150053Speter	do { \
11250053Speter		t1 = mtod(md, caddr_t)+md->m_len-dpos; \
1131541Srgrimes		if (t1 >= (s)) { \
1141541Srgrimes			(a) = (c)(dpos); \
1151541Srgrimes			dpos += (s); \
11636503Speter		} else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \
1179336Sdfr			error = t1; \
1189336Sdfr			m_freem(mrep); \
1199336Sdfr			goto nfsmout; \
1201541Srgrimes		} else { \
1219336Sdfr			(a) = (c)cp2; \
12250053Speter		} \
12350053Speter	} while (0)
1249336Sdfr
1259336Sdfr#define nfsm_fhtom(v, v3) \
12650053Speter	do { \
12750053Speter		if (v3) { \
1289336Sdfr			t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \
1299336Sdfr			if (t2 <= M_TRAILINGSPACE(mb)) { \
13036541Speter				nfsm_build(tl, u_int32_t *, t2); \
1319336Sdfr				*tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \
1329336Sdfr				*(tl + ((t2>>2) - 2)) = 0; \
1339336Sdfr				bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
1349336Sdfr					VTONFS(v)->n_fhsize); \
13536503Speter			} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \
13636503Speter				(caddr_t)VTONFS(v)->n_fhp, \
13736503Speter				VTONFS(v)->n_fhsize)) != 0) { \
1389336Sdfr				error = t2; \
1399336Sdfr				m_freem(mreq); \
1403305Sphk				goto nfsmout; \
1413305Sphk			} \
1429336Sdfr		} else { \
1439336Sdfr			nfsm_build(cp, caddr_t, NFSX_V2FH); \
1449336Sdfr			bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \
14550053Speter		} \
14650053Speter	} while (0)
1471541Srgrimes
1489336Sdfr#define nfsm_srvfhtom(f, v3) \
14950053Speter	do { \
15050053Speter		if (v3) { \
15150053Speter			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3FH);\
1529336Sdfr			*tl++ = txdr_unsigned(NFSX_V3FH); \
1539336Sdfr			bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
1549336Sdfr		} else { \
1559336Sdfr			nfsm_build(cp, caddr_t, NFSX_V2FH); \
1569336Sdfr			bcopy((caddr_t)(f), cp, NFSX_V2FH); \
15750053Speter		} \
15850053Speter	} while (0)
1591541Srgrimes
1609336Sdfr#define nfsm_srvpostop_fh(f) \
16150053Speter	do { \
16250053Speter		nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
1639336Sdfr		*tl++ = nfs_true; \
1649336Sdfr		*tl++ = txdr_unsigned(NFSX_V3FH); \
1659336Sdfr		bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
16650053Speter	} while (0)
1671541Srgrimes
1689336Sdfr#define nfsm_mtofh(d, v, v3, f) \
16950053Speter	do { \
17050053Speter		struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \
1719336Sdfr		if (v3) { \
17236541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
1739336Sdfr			(f) = fxdr_unsigned(int, *tl); \
1749336Sdfr		} else \
1759336Sdfr			(f) = 1; \
1769336Sdfr		if (f) { \
1779336Sdfr			nfsm_getfh(ttfhp, ttfhsize, (v3)); \
17836503Speter			if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
17936503Speter				&ttnp)) != 0) { \
1809336Sdfr				error = t1; \
1819336Sdfr				m_freem(mrep); \
1829336Sdfr				goto nfsmout; \
1839336Sdfr			} \
1849336Sdfr			(v) = NFSTOV(ttnp); \
1851541Srgrimes		} \
1869336Sdfr		if (v3) { \
18736541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
1889336Sdfr			if (f) \
1899336Sdfr				(f) = fxdr_unsigned(int, *tl); \
1909336Sdfr			else if (fxdr_unsigned(int, *tl)) \
1919336Sdfr				nfsm_adv(NFSX_V3FATTR); \
1929336Sdfr		} \
1939336Sdfr		if (f) \
1949336Sdfr			nfsm_loadattr((v), (struct vattr *)0); \
19550053Speter	} while (0)
1961541Srgrimes
1979336Sdfr#define nfsm_getfh(f, s, v3) \
19850053Speter	do { \
19950053Speter		if (v3) { \
20036541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
2019336Sdfr			if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \
2029336Sdfr				(s) > NFSX_V3FHMAX) { \
2039336Sdfr				m_freem(mrep); \
2049336Sdfr				error = EBADRPC; \
2059336Sdfr				goto nfsmout; \
2069336Sdfr			} \
2079336Sdfr		} else \
2089336Sdfr			(s) = NFSX_V2FH; \
20950053Speter		nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); \
21050053Speter	} while (0)
2119336Sdfr
2129336Sdfr#define	nfsm_loadattr(v, a) \
21350053Speter	do { \
21450053Speter		struct vnode *ttvp = (v); \
21536503Speter		if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
2169336Sdfr			error = t1; \
2171541Srgrimes			m_freem(mrep); \
2181541Srgrimes			goto nfsmout; \
2191541Srgrimes		} \
22050053Speter		(v) = ttvp; \
22150053Speter	} while (0)
2221541Srgrimes
2239336Sdfr#define	nfsm_postop_attr(v, f) \
22450053Speter	do { \
22550053Speter		struct vnode *ttvp = (v); \
22636541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
22736541Speter		if (((f) = fxdr_unsigned(int, *tl)) != 0) { \
22836503Speter			if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
22936503Speter				(struct vattr *)0)) != 0) { \
2309336Sdfr				error = t1; \
2319336Sdfr				(f) = 0; \
2329336Sdfr				m_freem(mrep); \
2339336Sdfr				goto nfsmout; \
2349336Sdfr			} \
2359336Sdfr			(v) = ttvp; \
23650053Speter		} \
23750053Speter	} while (0)
2389336Sdfr
2399336Sdfr/* Used as (f) for nfsm_wcc_data() */
2409336Sdfr#define NFSV3_WCCRATTR	0
2419336Sdfr#define NFSV3_WCCCHK	1
2429336Sdfr
2439336Sdfr#define	nfsm_wcc_data(v, f) \
24450053Speter	do { \
24550053Speter		int ttattrf, ttretf = 0; \
24636541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
2479336Sdfr		if (*tl == nfs_true) { \
24836541Speter			nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); \
2499336Sdfr			if (f) \
2509336Sdfr				ttretf = (VTONFS(v)->n_mtime == \
25136541Speter					fxdr_unsigned(u_int32_t, *(tl + 2))); \
2529336Sdfr		} \
2539336Sdfr		nfsm_postop_attr((v), ttattrf); \
2549336Sdfr		if (f) { \
2559336Sdfr			(f) = ttretf; \
2569336Sdfr		} else { \
2579336Sdfr			(f) = ttattrf; \
25850053Speter		} \
25950053Speter	} while (0)
2609336Sdfr
26142060Sdfr/* If full is true, set all fields, otherwise just set mode and time fields */
26250053Speter#define nfsm_v3attrbuild(a, full) \
26350053Speter	do { \
26450053Speter		if ((a)->va_mode != (mode_t)VNOVAL) {			\
26550053Speter			nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);	\
26650053Speter			*tl++ = nfs_true;				\
26750053Speter			*tl = txdr_unsigned((a)->va_mode);		\
26850053Speter		} else {						\
26950053Speter			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);	\
27050053Speter			*tl = nfs_false;				\
27150053Speter		}							\
27250053Speter		if ((full) && (a)->va_uid != (uid_t)VNOVAL) {		\
27350053Speter			nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);	\
27450053Speter			*tl++ = nfs_true;				\
27550053Speter			*tl = txdr_unsigned((a)->va_uid);		\
27650053Speter		} else {						\
27750053Speter			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);	\
27850053Speter			*tl = nfs_false;				\
27950053Speter		}							\
28050053Speter		if ((full) && (a)->va_gid != (gid_t)VNOVAL) {		\
28150053Speter			nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);	\
28250053Speter			*tl++ = nfs_true;				\
28350053Speter			*tl = txdr_unsigned((a)->va_gid);		\
28450053Speter		} else {						\
28550053Speter			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);	\
28650053Speter			*tl = nfs_false;				\
28750053Speter		}							\
28850053Speter		if ((full) && (a)->va_size != VNOVAL) {			\
28950053Speter			nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);	\
29050053Speter			*tl++ = nfs_true;				\
29150053Speter			txdr_hyper((a)->va_size, tl);			\
29250053Speter		} else {						\
29350053Speter			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);	\
29450053Speter			*tl = nfs_false;				\
29550053Speter		}							\
29650053Speter		if ((a)->va_atime.tv_sec != VNOVAL) {			\
29750053Speter			if ((a)->va_atime.tv_sec != time_second) {	\
29850053Speter				nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);\
29950053Speter				*tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);\
30050053Speter				txdr_nfsv3time(&(a)->va_atime, tl);	\
30150053Speter			} else {					\
30250053Speter				nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
30350053Speter				*tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \
30450053Speter			}						\
30550053Speter		} else {						\
30650053Speter			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);	\
30750053Speter			*tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE);	\
30850053Speter		}							\
30950053Speter		if ((a)->va_mtime.tv_sec != VNOVAL) {			\
31050053Speter			if ((a)->va_mtime.tv_sec != time_second) {	\
31150053Speter				nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);\
31250053Speter				*tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);\
31350053Speter				txdr_nfsv3time(&(a)->va_mtime, tl);	\
31450053Speter			} else {					\
31550053Speter				nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
31650053Speter				*tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \
31750053Speter			}						\
31850053Speter		} else {						\
31950053Speter			nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);	\
32050053Speter			*tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE);	\
32150053Speter		}							\
32250053Speter	} while (0)
32342060Sdfr
3249336Sdfr
3251541Srgrimes#define	nfsm_strsiz(s,m) \
32650053Speter	do { \
32750053Speter		nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
32836541Speter		if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \
3291541Srgrimes			m_freem(mrep); \
3301541Srgrimes			error = EBADRPC; \
3311541Srgrimes			goto nfsmout; \
33250053Speter		} \
33350053Speter	} while (0)
3341541Srgrimes
3351541Srgrimes#define	nfsm_srvstrsiz(s,m) \
33650053Speter	do { \
33750053Speter		nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
33836541Speter		if (((s) = fxdr_unsigned(int32_t,*tl)) > (m) || (s) <= 0) { \
3391541Srgrimes			error = EBADRPC; \
3401541Srgrimes			nfsm_reply(0); \
34150053Speter		} \
34250053Speter	} while (0)
3431541Srgrimes
3449336Sdfr#define	nfsm_srvnamesiz(s) \
34550053Speter	do { \
34650053Speter		nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
34736541Speter		if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) \
3489336Sdfr			error = NFSERR_NAMETOL; \
3499336Sdfr		if ((s) <= 0) \
3509336Sdfr			error = EBADRPC; \
3519336Sdfr		if (error) \
3529336Sdfr			nfsm_reply(0); \
35350053Speter	} while (0)
3549336Sdfr
3551541Srgrimes#define nfsm_mtouio(p,s) \
35650053Speter	do {\
3571541Srgrimes		if ((s) > 0 && \
35836503Speter		   (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
3599336Sdfr			error = t1; \
3601541Srgrimes			m_freem(mrep); \
3611541Srgrimes			goto nfsmout; \
36250053Speter		} \
36350053Speter	} while (0)
3641541Srgrimes
3651541Srgrimes#define nfsm_uiotom(p,s) \
36650053Speter	do { \
36736503Speter		if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \
3689336Sdfr			error = t1; \
3691541Srgrimes			m_freem(mreq); \
3701541Srgrimes			goto nfsmout; \
37150053Speter		} \
37250053Speter	} while (0)
3731541Srgrimes
3741541Srgrimes#define	nfsm_reqhead(v,a,s) \
37550053Speter	do { \
37650053Speter		mb = mreq = nfsm_reqh((v),(a),(s),&bpos); \
37750053Speter	} while (0)
3781541Srgrimes
37950053Speter#define nfsm_reqdone \
38050053Speter	do { \
38150053Speter		m_freem(mrep); \
38250053Speter		nfsmout: \
38350053Speter	} while (0)
3841541Srgrimes
3851541Srgrimes#define nfsm_rndup(a)	(((a)+3)&(~0x3))
3861541Srgrimes
38750053Speter#define	nfsm_request(v, t, p, c) \
38850053Speter	do { \
38936503Speter		if ((error = nfs_request((v), mreq, (t), (p), \
39036503Speter		   (c), &mrep, &md, &dpos)) != 0) { \
3919336Sdfr			if (error & NFSERR_RETERR) \
3929336Sdfr				error &= ~NFSERR_RETERR; \
3939336Sdfr			else \
3949336Sdfr				goto nfsmout; \
39550053Speter		} \
39650053Speter	} while (0)
3971541Srgrimes
3981541Srgrimes#define	nfsm_strtom(a,s,m) \
39950053Speter	do {\
4001541Srgrimes		if ((s) > (m)) { \
4011541Srgrimes			m_freem(mreq); \
4021541Srgrimes			error = ENAMETOOLONG; \
4031541Srgrimes			goto nfsmout; \
4041541Srgrimes		} \
4051541Srgrimes		t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
4061541Srgrimes		if (t2 <= M_TRAILINGSPACE(mb)) { \
40736541Speter			nfsm_build(tl,u_int32_t *,t2); \
4081541Srgrimes			*tl++ = txdr_unsigned(s); \
4091541Srgrimes			*(tl+((t2>>2)-2)) = 0; \
41036511Speter			bcopy((const char *)(a), (caddr_t)tl, (s)); \
41136503Speter		} else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \
4129336Sdfr			error = t2; \
4139336Sdfr			m_freem(mreq); \
4149336Sdfr			goto nfsmout; \
41550053Speter		} \
41650053Speter	} while (0)
4171541Srgrimes
4181541Srgrimes#define	nfsm_srvdone \
41950053Speter	do { \
4201541Srgrimes		nfsmout: \
42150053Speter		return (error); \
42250053Speter	} while (0)
4231541Srgrimes
4241541Srgrimes#define	nfsm_reply(s) \
42550053Speter	do { \
4261541Srgrimes		nfsd->nd_repstat = error; \
4279336Sdfr		if (error && !(nfsd->nd_flag & ND_NFSV3)) \
4289336Sdfr		   (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
4291541Srgrimes			mrq, &mb, &bpos); \
4301541Srgrimes		else \
4319336Sdfr		   (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
4321541Srgrimes			mrq, &mb, &bpos); \
43336520Speter		if (mrep != NULL) { \
43436520Speter			m_freem(mrep); \
43536520Speter			mrep = NULL; \
43636520Speter		} \
4371541Srgrimes		mreq = *mrq; \
4389336Sdfr		if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
43948125Sjulian			error == EBADRPC)) { \
44048125Sjulian			error = 0; \
44148125Sjulian			goto nfsmout; \
44250053Speter		} \
44350053Speter	} while (0)
4441541Srgrimes
4459336Sdfr#define	nfsm_writereply(s, v3) \
44650053Speter	do { \
4479336Sdfr		nfsd->nd_repstat = error; \
4489336Sdfr		if (error && !(v3)) \
4499336Sdfr		   (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
4509336Sdfr			&mreq, &mb, &bpos); \
4519336Sdfr		else \
4529336Sdfr		   (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
4539336Sdfr			&mreq, &mb, &bpos); \
45450053Speter	} while (0)
4559336Sdfr
4561541Srgrimes#define	nfsm_adv(s) \
45750053Speter	do { \
45850053Speter		t1 = mtod(md, caddr_t)+md->m_len-dpos; \
4591541Srgrimes		if (t1 >= (s)) { \
4601541Srgrimes			dpos += (s); \
46136503Speter		} else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \
4629336Sdfr			error = t1; \
4639336Sdfr			m_freem(mrep); \
4649336Sdfr			goto nfsmout; \
46550053Speter		} \
46650053Speter	} while (0)
4679336Sdfr
4689336Sdfr#define nfsm_srvmtofh(f) \
46949405Speter	do { \
47049405Speter		int fhlen; \
47127446Sdfr		if (nfsd->nd_flag & ND_NFSV3) { \
47236541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
47327446Sdfr			fhlen = fxdr_unsigned(int, *tl); \
47449405Speter			if (fhlen != 0 && fhlen != NFSX_V3FH) { \
4759336Sdfr				error = EBADRPC; \
4769336Sdfr				nfsm_reply(0); \
4773305Sphk			} \
47849405Speter		} else { \
47949405Speter			fhlen = NFSX_V2FH; \
4809336Sdfr		} \
48127446Sdfr		if (fhlen != 0) { \
48249405Speter			nfsm_dissect(tl, u_int32_t *, fhlen); \
48349405Speter			bcopy((caddr_t)tl, (caddr_t)(f), fhlen); \
48449405Speter		} else {\
48549405Speter			bzero((caddr_t)(f), NFSX_V3FH); \
48627446Sdfr		} \
48749405Speter	} while (0)
4881541Srgrimes
4891541Srgrimes#define	nfsm_clget \
49050053Speter	do { \
4911541Srgrimes		if (bp >= be) { \
4921541Srgrimes			if (mp == mb) \
4931541Srgrimes				mp->m_len += bp-bpos; \
4941541Srgrimes			MGET(mp, M_WAIT, MT_DATA); \
4951541Srgrimes			MCLGET(mp, M_WAIT); \
4961541Srgrimes			mp->m_len = NFSMSIZ(mp); \
4971541Srgrimes			mp2->m_next = mp; \
4981541Srgrimes			mp2 = mp; \
4991541Srgrimes			bp = mtod(mp, caddr_t); \
5001541Srgrimes			be = bp+mp->m_len; \
5011541Srgrimes		} \
50250053Speter		tl = (u_int32_t *)bp; \
50350053Speter	} while (0)
5041541Srgrimes
5059336Sdfr#define	nfsm_srvfillattr(a, f) \
50650053Speter	do { \
50750053Speter		nfsm_srvfattr(nfsd, (a), (f)); \
50850053Speter	} while (0)
5091541Srgrimes
5109336Sdfr#define nfsm_srvwcc_data(br, b, ar, a) \
51150053Speter	do { \
51250053Speter		nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos); \
51350053Speter	} while (0)
5149336Sdfr
5159336Sdfr#define nfsm_srvpostop_attr(r, a) \
51650053Speter	do { \
51750053Speter		nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos); \
51850053Speter	} while (0)
5199336Sdfr
5209336Sdfr#define nfsm_srvsattr(a) \
52150053Speter	do { \
52250053Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
5239336Sdfr		if (*tl == nfs_true) { \
52436541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
5259336Sdfr			(a)->va_mode = nfstov_mode(*tl); \
5269336Sdfr		} \
52736541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
5289336Sdfr		if (*tl == nfs_true) { \
52936541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
5309336Sdfr			(a)->va_uid = fxdr_unsigned(uid_t, *tl); \
5319336Sdfr		} \
53236541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
5339336Sdfr		if (*tl == nfs_true) { \
53436541Speter			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
5359336Sdfr			(a)->va_gid = fxdr_unsigned(gid_t, *tl); \
5369336Sdfr		} \
53736541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
5389336Sdfr		if (*tl == nfs_true) { \
53936541Speter			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
54047751Speter			(a)->va_size = fxdr_hyper(tl); \
5419336Sdfr		} \
54236541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
5439336Sdfr		switch (fxdr_unsigned(int, *tl)) { \
5449336Sdfr		case NFSV3SATTRTIME_TOCLIENT: \
54536541Speter			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
5469336Sdfr			fxdr_nfsv3time(tl, &(a)->va_atime); \
5479336Sdfr			break; \
54836097Sbde		case NFSV3SATTRTIME_TOSERVER: \
54936097Sbde			getnanotime(&(a)->va_atime); \
55036097Sbde			break; \
5519336Sdfr		}; \
55236541Speter		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
5539336Sdfr		switch (fxdr_unsigned(int, *tl)) { \
5549336Sdfr		case NFSV3SATTRTIME_TOCLIENT: \
55536541Speter			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
5569336Sdfr			fxdr_nfsv3time(tl, &(a)->va_mtime); \
5579336Sdfr			break; \
55836097Sbde		case NFSV3SATTRTIME_TOSERVER: \
55936097Sbde			getnanotime(&(a)->va_mtime); \
56036097Sbde			break; \
56150053Speter		} \
56250053Speter	} while (0)
5639336Sdfr
5642175Spaul#endif
565