xref: /csrg-svn/sys/nfs/nfsm_subs.h (revision 39494)
138414Smckusick /*
238414Smckusick  * Copyright (c) 1989 The Regents of the University of California.
338414Smckusick  * All rights reserved.
438414Smckusick  *
538414Smckusick  * This code is derived from software contributed to Berkeley by
638414Smckusick  * Rick Macklem at The University of Guelph.
738414Smckusick  *
838414Smckusick  * Redistribution and use in source and binary forms are permitted
938414Smckusick  * provided that the above copyright notice and this paragraph are
1038414Smckusick  * duplicated in all such forms and that any documentation,
1138414Smckusick  * advertising materials, and other materials related to such
1238414Smckusick  * distribution and use acknowledge that the software was developed
1338414Smckusick  * by the University of California, Berkeley.  The name of the
1438414Smckusick  * University may not be used to endorse or promote products derived
1538414Smckusick  * from this software without specific prior written permission.
1638414Smckusick  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1738414Smckusick  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1838414Smckusick  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1938414Smckusick  *
20*39494Smckusick  *	@(#)nfsm_subs.h	7.4 (Berkeley) 11/03/89
2138414Smckusick  */
2238414Smckusick 
2338414Smckusick /*
2438414Smckusick  * These macros do strange and peculiar things to mbuf chains for
2538414Smckusick  * the assistance of the nfs code. To attempt to use them for any
2638414Smckusick  * other purpose will be dangerous. (they make weird assumptions)
2738414Smckusick  */
2838414Smckusick 
2938414Smckusick /*
3038414Smckusick  * First define what the actual subs. return
3138414Smckusick  */
32*39494Smckusick extern struct mbuf *nfsm_reqh();
33*39494Smckusick extern struct vnode *nfs_fhtovp();
3438414Smckusick 
3538414Smckusick /*
3638414Smckusick  * To try and deal with different variants of mbuf.h, I have used the
3738414Smckusick  * following defs. If M_HASCL is not defined in an older the 4.4bsd mbuf.h,
3838414Smckusick  * you will have to use a different ifdef
3938414Smckusick  */
4038414Smckusick #ifdef M_HASCL
4138414Smckusick #define	NFSMCLGET(m, w)	MCLGET(m)
4238414Smckusick #define	NFSMGETHDR(m)	MGET(m, M_WAIT, MT_DATA)
4338414Smckusick #define	MHLEN		MLEN
4438414Smckusick #define	NFSMINOFF(m) \
4538414Smckusick 		if (M_HASCL(m)) \
4638414Smckusick 			(m)->m_off = ((int)MTOCL(m))-(int)(m); \
4738414Smckusick 		else \
4838414Smckusick 			(m)->m_off = MMINOFF
4938414Smckusick #define	NFSMADV(m, s)	(m)->m_off += (s)
5038414Smckusick #define	NFSMSIZ(m)	((M_HASCL(m))?MCLBYTES:MLEN)
5138414Smckusick #define	m_nextpkt	m_act
5238414Smckusick #define	NFSMCOPY(m, o, l, w)	m_copy((m), (o), (l))
5338414Smckusick #else
5438414Smckusick #define	M_HASCL(m)	((m)->m_flags & M_EXT)
5538414Smckusick #define	NFSMCLGET	MCLGET
5638414Smckusick #define	NFSMGETHDR(m) \
5738414Smckusick 		MGETHDR(m, M_WAIT, MT_DATA); \
5838414Smckusick 		(m)->m_pkthdr.len = 0; \
5938414Smckusick 		(m)->m_pkthdr.rcvif = (struct ifnet *)0
6038414Smckusick #define	NFSMINOFF(m) \
6138414Smckusick 		if (M_HASCL(m)) \
6238414Smckusick 			(m)->m_data = (m)->m_ext.ext_buf; \
6338414Smckusick 		else \
6438414Smckusick 			(m)->m_data = (m)->m_dat
6538414Smckusick #define	NFSMADV(m, s)	(m)->m_data += (s)
6638425Smckusick #define	NFSMSIZ(m)	((M_HASCL(m))?MCLBYTES: \
6738414Smckusick 				(((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
6838414Smckusick #define	NFSMCOPY	m_copym
6938414Smckusick #endif
7038414Smckusick 
7138414Smckusick #ifndef MCLBYTES
7238414Smckusick #define	MCLBYTES	CLBYTES
7338414Smckusick #endif
7438414Smckusick 
7538414Smckusick #ifndef MT_CONTROL
7638414Smckusick #define	MT_CONTROL	MT_RIGHTS
7738414Smckusick #endif
7838414Smckusick 
7938414Smckusick /*
8038414Smckusick  * Now for the macros that do the simple stuff and call the functions
8138414Smckusick  * for the hard stuff.
8238414Smckusick  * These macros use several vars. declared in nfsm_reqhead and these
8338414Smckusick  * vars. must not be used elsewhere unless you are careful not to corrupt
8438414Smckusick  * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
8538414Smckusick  * that may be used so long as the value is not expected to retained
8638414Smckusick  * after a macro.
8738414Smckusick  * I know, this is kind of dorkey, but it makes the actual op functions
8838414Smckusick  * fairly clean and deals with the mess caused by the xdr discriminating
8938414Smckusick  * unions.
9038414Smckusick  */
9138414Smckusick 
92*39494Smckusick #ifndef lint
9338414Smckusick #define	nfsm_build(a,c,s) \
9438414Smckusick 		t1 = NFSMSIZ(mb); \
9538414Smckusick 		if ((s) > (t1-mb->m_len)) { \
9638414Smckusick 			MGET(mb2, M_WAIT, MT_DATA); \
9738414Smckusick 			if ((s) > MLEN) \
9838414Smckusick 				panic("build > MLEN"); \
9938414Smckusick 			mb->m_next = mb2; \
10038414Smckusick 			mb = mb2; \
10138414Smckusick 			mb->m_len = 0; \
10238414Smckusick 			bpos = mtod(mb, caddr_t); \
10338414Smckusick 		} \
10438414Smckusick 		(a) = (c)(bpos); \
10538414Smckusick 		mb->m_len += (s); \
10638414Smckusick 		bpos += (s)
107*39494Smckusick #else /* lint */
108*39494Smckusick #define	nfsm_build(a,c,s) \
109*39494Smckusick 		t1 = NFSMSIZ(mb); \
110*39494Smckusick 		if ((s) > (t1-mb->m_len)) { \
111*39494Smckusick 			MGET(mb2, M_WAIT, MT_DATA); \
112*39494Smckusick 			mb->m_next = mb2; \
113*39494Smckusick 			mb = mb2; \
114*39494Smckusick 			mb->m_len = 0; \
115*39494Smckusick 			bpos = mtod(mb, caddr_t); \
116*39494Smckusick 		} \
117*39494Smckusick 		(a) = (c)(bpos); \
118*39494Smckusick 		mb->m_len += (s); \
119*39494Smckusick 		bpos += (s)
120*39494Smckusick #endif /* lint */
12138414Smckusick 
12238414Smckusick #define	nfsm_disect(a,c,s) \
12338414Smckusick 		t1 = mtod(md, caddr_t)+md->m_len-dpos; \
12438414Smckusick 		if (t1 >= (s)) { \
12538414Smckusick 			(a) = (c)(dpos); \
12638414Smckusick 			dpos += (s); \
12738414Smckusick 		} else if (error = nfsm_disct(&md, &dpos, (s), t1, TRUE, &cp2)) { \
12838414Smckusick 			m_freem(mrep); \
12938414Smckusick 			goto nfsmout; \
13038414Smckusick 		} else { \
13138414Smckusick 			(a) = (c)cp2; \
13238414Smckusick 		}
13338414Smckusick 
13438414Smckusick #define	nfsm_disecton(a,c,s) \
13538414Smckusick 		t1 = mtod(md, caddr_t)+md->m_len-dpos; \
13638414Smckusick 		if (t1 >= (s)) { \
13738414Smckusick 			(a) = (c)(dpos); \
13838414Smckusick 			dpos += (s); \
13938414Smckusick 		} else if (error = nfsm_disct(&md, &dpos, (s), t1, FALSE, &cp2)) { \
14038414Smckusick 			m_freem(mrep); \
14138414Smckusick 			goto nfsmout; \
14238414Smckusick 		} else { \
14338414Smckusick 			(a) = (c)cp2; \
14438414Smckusick 		}
14538414Smckusick 
14638414Smckusick #define nfsm_fhtom(v) \
14738414Smckusick 		nfsm_build(cp,caddr_t,NFSX_FH); \
14838414Smckusick 		bcopy((caddr_t)&(VTONFS(v)->n_fh), cp, NFSX_FH)
14938414Smckusick 
15038414Smckusick #define nfsm_srvfhtom(f) \
15138414Smckusick 		nfsm_build(cp,caddr_t,NFSX_FH); \
15238414Smckusick 		bcopy((caddr_t)(f), cp, NFSX_FH)
15338414Smckusick 
15438414Smckusick #define nfsm_mtofh(d,v) \
15538414Smckusick 		{ struct nfsnode *np; nfsv2fh_t *fhp; \
15638414Smckusick 		nfsm_disect(fhp,nfsv2fh_t *,NFSX_FH); \
15738414Smckusick 		if (error = nfs_nget((d)->v_mount, fhp, &np)) { \
15838414Smckusick 			m_freem(mrep); \
15938414Smckusick 			goto nfsmout; \
16038414Smckusick 		} \
16138414Smckusick 		(v) = NFSTOV(np); \
16238414Smckusick 		nfsm_loadattr(v, (struct vattr *)0); \
16338414Smckusick 		(v)->v_type = np->n_vattr.va_type; \
16438414Smckusick 		}
16538414Smckusick 
16638414Smckusick #define	nfsm_loadattr(v,a) \
167*39494Smckusick 		{ struct vnode *tvp = (v); \
168*39494Smckusick 		if (error = nfs_loadattrcache(&tvp, &md, &dpos, (a))) { \
16938414Smckusick 			m_freem(mrep); \
17038414Smckusick 			goto nfsmout; \
171*39494Smckusick 		} \
172*39494Smckusick 		(v) = tvp; }
17338414Smckusick 
17438414Smckusick #define	nfsm_strsiz(s,m) \
17538414Smckusick 		nfsm_disect(p,u_long *,NFSX_UNSIGNED); \
17638414Smckusick 		if (((s) = fxdr_unsigned(long,*p)) > (m)) { \
17738414Smckusick 			m_freem(mrep); \
17838414Smckusick 			error = EBADRPC; \
17938414Smckusick 			goto nfsmout; \
18038414Smckusick 		}
18138414Smckusick 
18238414Smckusick #define	nfsm_srvstrsiz(s,m) \
18338414Smckusick 		nfsm_disect(p,u_long *,NFSX_UNSIGNED); \
18438414Smckusick 		if (((s) = fxdr_unsigned(long,*p)) > (m) || (s) <= 0) { \
18538414Smckusick 			error = EBADRPC; \
18638414Smckusick 			nfsm_reply(0); \
18738414Smckusick 		}
18838414Smckusick 
18938414Smckusick #define nfsm_mtouio(p,s) \
19038414Smckusick 		if ((s) > 0 && \
19138414Smckusick 		   (error = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
19238414Smckusick 			m_freem(mrep); \
19338414Smckusick 			goto nfsmout; \
19438414Smckusick 		}
19538414Smckusick 
19638414Smckusick #define nfsm_uiotom(p,s) \
19738414Smckusick 		if (error = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
19838414Smckusick 			m_freem(mreq); \
19938414Smckusick 			goto nfsmout; \
20038414Smckusick 		}
20138414Smckusick 
20238414Smckusick #define	nfsm_reqhead(a,c,s) \
20338414Smckusick 		if ((mreq = nfsm_reqh(nfs_prog,nfs_vers,(a),(c),(s),&bpos,&mb,&xid)) == NULL) { \
20438414Smckusick 			error = ENOBUFS; \
20538414Smckusick 			goto nfsmout; \
20638414Smckusick 		}
20738414Smckusick 
20838414Smckusick #define nfsm_reqdone	m_freem(mrep); \
20938414Smckusick 		nfsmout:
21038414Smckusick 
21138414Smckusick #define nfsm_rndup(a)	(((a)+3)&(~0x3))
21238414Smckusick 
21338414Smckusick #define	nfsm_request(v)	\
21438414Smckusick 		if (error = nfs_request((v), mreq, xid, \
21538414Smckusick 		   (v)->v_mount, &mrep, &md, &dpos)) \
21638414Smckusick 			goto nfsmout
21738414Smckusick 
21838414Smckusick #define	nfsm_strtom(a,s,m) \
21938414Smckusick 		if ((s) > (m)) { \
22038414Smckusick 			m_freem(mreq); \
22138414Smckusick 			error = ENAMETOOLONG; \
22238414Smckusick 			goto nfsmout; \
22338414Smckusick 		} \
22438414Smckusick 		t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
22538414Smckusick 		if(t2<=(NFSMSIZ(mb)-mb->m_len)){ \
22638414Smckusick 			nfsm_build(p,u_long *,t2); \
22738414Smckusick 			*p++ = txdr_unsigned(s); \
22838414Smckusick 			*(p+((t2>>2)-2)) = 0; \
22938414Smckusick 			bcopy((caddr_t)(a), (caddr_t)p, (s)); \
23038414Smckusick 		} else if (error = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
23138414Smckusick 			m_freem(mreq); \
23238414Smckusick 			goto nfsmout; \
23338414Smckusick 		}
23438414Smckusick 
23538414Smckusick #define	nfsm_srverr \
23638414Smckusick 		{ \
23738414Smckusick 			m_freem(mrep); \
23838414Smckusick 			return(ENOBUFS); \
23938414Smckusick 		}
24038414Smckusick 
24138414Smckusick #define	nfsm_srvdone \
24238414Smckusick 		nfsmout: \
24338414Smckusick 		return(error)
24438414Smckusick 
24538414Smckusick #define	nfsm_reply(s) \
24638414Smckusick 		{ \
24738414Smckusick 		if (error) \
24838414Smckusick 			nfs_rephead(0, xid, error, mrq, &mb, &bpos); \
24938414Smckusick 		else \
25038414Smckusick 			nfs_rephead((s), xid, error, mrq, &mb, &bpos); \
25138414Smckusick 		m_freem(mrep); \
25238414Smckusick 		if (error) \
25338414Smckusick 			return(0); \
25438414Smckusick 		}
25538414Smckusick 
25638414Smckusick #define	nfsm_adv(s) \
25738414Smckusick 		t1 = mtod(md, caddr_t)+md->m_len-dpos; \
25838414Smckusick 		if (t1 >= (s)) { \
25938414Smckusick 			dpos += (s); \
26038414Smckusick 		} else if (error = nfs_adv(&md, &dpos, (s), t1)) { \
26138414Smckusick 			m_freem(mrep); \
26238414Smckusick 			goto nfsmout; \
26338414Smckusick 		}
26438414Smckusick 
26538414Smckusick #define nfsm_srvmtofh(f) \
26638414Smckusick 		nfsm_disecton(p, u_long *, NFSX_FH); \
26738414Smckusick 		bcopy((caddr_t)p, (caddr_t)f, NFSX_FH)
26838414Smckusick 
26938414Smckusick #define	nfsm_clget \
27038414Smckusick 		if (bp >= be) { \
27138414Smckusick 			MGET(mp, M_WAIT, MT_DATA); \
27238414Smckusick 			NFSMCLGET(mp, M_WAIT); \
27338414Smckusick 			mp->m_len = NFSMSIZ(mp); \
27438414Smckusick 			if (mp3 == NULL) \
27538414Smckusick 				mp3 = mp2 = mp; \
27638414Smckusick 			else { \
27738414Smckusick 				mp2->m_next = mp; \
27838414Smckusick 				mp2 = mp; \
27938414Smckusick 			} \
28038414Smckusick 			bp = mtod(mp, caddr_t); \
28138414Smckusick 			be = bp+mp->m_len; \
28238414Smckusick 		} \
28338414Smckusick 		p = (u_long *)bp
28438414Smckusick 
285