xref: /original-bsd/sys/nfs/nfsm_subs.h (revision 37acaaf2)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rick Macklem at The University of Guelph.
7  *
8  * %sccs.include.redist.c%
9  *
10  *	@(#)nfsm_subs.h	7.11 (Berkeley) 04/16/91
11  */
12 
13 /*
14  * These macros do strange and peculiar things to mbuf chains for
15  * the assistance of the nfs code. To attempt to use them for any
16  * other purpose will be dangerous. (they make weird assumptions)
17  */
18 
19 /*
20  * First define what the actual subs. return
21  */
22 extern struct mbuf *nfsm_reqh();
23 
24 #define	M_HASCL(m)	((m)->m_flags & M_EXT)
25 #define	NFSMGETHDR(m) \
26 		MGETHDR(m, M_WAIT, MT_DATA); \
27 		(m)->m_pkthdr.len = 0; \
28 		(m)->m_pkthdr.rcvif = (struct ifnet *)0
29 #define	NFSMINOFF(m) \
30 		if (M_HASCL(m)) \
31 			(m)->m_data = (m)->m_ext.ext_buf; \
32 		else \
33 			(m)->m_data = (m)->m_dat
34 #define	NFSMADV(m, s)	(m)->m_data += (s)
35 #define	NFSMSIZ(m)	((M_HASCL(m))?MCLBYTES: \
36 				(((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
37 
38 /*
39  * Now for the macros that do the simple stuff and call the functions
40  * for the hard stuff.
41  * These macros use several vars. declared in nfsm_reqhead and these
42  * vars. must not be used elsewhere unless you are careful not to corrupt
43  * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
44  * that may be used so long as the value is not expected to retained
45  * after a macro.
46  * I know, this is kind of dorkey, but it makes the actual op functions
47  * fairly clean and deals with the mess caused by the xdr discriminating
48  * unions.
49  */
50 
51 #ifndef lint
52 #define	nfsm_build(a,c,s) \
53 		t1 = NFSMSIZ(mb); \
54 		if ((s) > (t1-mb->m_len)) { \
55 			MGET(mb2, M_WAIT, MT_DATA); \
56 			if ((s) > MLEN) \
57 				panic("build > MLEN"); \
58 			mb->m_next = mb2; \
59 			mb = mb2; \
60 			mb->m_len = 0; \
61 			bpos = mtod(mb, caddr_t); \
62 		} \
63 		(a) = (c)(bpos); \
64 		mb->m_len += (s); \
65 		bpos += (s)
66 #else /* lint */
67 #define	nfsm_build(a,c,s) \
68 		t1 = NFSMSIZ(mb); \
69 		if ((s) > (t1-mb->m_len)) { \
70 			MGET(mb2, M_WAIT, MT_DATA); \
71 			mb->m_next = mb2; \
72 			mb = mb2; \
73 			mb->m_len = 0; \
74 			bpos = mtod(mb, caddr_t); \
75 		} \
76 		(a) = (c)(bpos); \
77 		mb->m_len += (s); \
78 		bpos += (s)
79 #endif /* lint */
80 
81 #define	nfsm_disect(a,c,s) \
82 		t1 = mtod(md, caddr_t)+md->m_len-dpos; \
83 		if (t1 >= (s)) { \
84 			(a) = (c)(dpos); \
85 			dpos += (s); \
86 		} else if (error = nfsm_disct(&md, &dpos, (s), t1, TRUE, &cp2)) { \
87 			m_freem(mrep); \
88 			goto nfsmout; \
89 		} else { \
90 			(a) = (c)cp2; \
91 		}
92 
93 #define	nfsm_disecton(a,c,s) \
94 		t1 = mtod(md, caddr_t)+md->m_len-dpos; \
95 		if (t1 >= (s)) { \
96 			(a) = (c)(dpos); \
97 			dpos += (s); \
98 		} else if (error = nfsm_disct(&md, &dpos, (s), t1, FALSE, &cp2)) { \
99 			m_freem(mrep); \
100 			goto nfsmout; \
101 		} else { \
102 			(a) = (c)cp2; \
103 		}
104 
105 #define nfsm_fhtom(v) \
106 		nfsm_build(cp,caddr_t,NFSX_FH); \
107 		bcopy((caddr_t)&(VTONFS(v)->n_fh), cp, NFSX_FH)
108 
109 #define nfsm_srvfhtom(f) \
110 		nfsm_build(cp,caddr_t,NFSX_FH); \
111 		bcopy((caddr_t)(f), cp, NFSX_FH)
112 
113 #define nfsm_mtofh(d,v) \
114 		{ struct nfsnode *np; nfsv2fh_t *fhp; \
115 		nfsm_disect(fhp,nfsv2fh_t *,NFSX_FH); \
116 		if (error = nfs_nget((d)->v_mount, fhp, &np)) { \
117 			m_freem(mrep); \
118 			goto nfsmout; \
119 		} \
120 		(v) = NFSTOV(np); \
121 		nfsm_loadattr(v, (struct vattr *)0); \
122 		}
123 
124 #define	nfsm_loadattr(v,a) \
125 		{ struct vnode *tvp = (v); \
126 		if (error = nfs_loadattrcache(&tvp, &md, &dpos, (a))) { \
127 			m_freem(mrep); \
128 			goto nfsmout; \
129 		} \
130 		(v) = tvp; }
131 
132 #define	nfsm_strsiz(s,m) \
133 		nfsm_disect(tl,u_long *,NFSX_UNSIGNED); \
134 		if (((s) = fxdr_unsigned(long,*tl)) > (m)) { \
135 			m_freem(mrep); \
136 			error = EBADRPC; \
137 			goto nfsmout; \
138 		}
139 
140 #define	nfsm_srvstrsiz(s,m) \
141 		nfsm_disect(tl,u_long *,NFSX_UNSIGNED); \
142 		if (((s) = fxdr_unsigned(long,*tl)) > (m) || (s) <= 0) { \
143 			error = EBADRPC; \
144 			nfsm_reply(0); \
145 		}
146 
147 #define nfsm_mtouio(p,s) \
148 		if ((s) > 0 && \
149 		   (error = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
150 			m_freem(mrep); \
151 			goto nfsmout; \
152 		}
153 
154 #define nfsm_uiotom(p,s) \
155 		if (error = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
156 			m_freem(mreq); \
157 			goto nfsmout; \
158 		}
159 
160 #define	nfsm_reqhead(a,c,s) \
161 		if ((mreq = nfsm_reqh(nfs_prog,nfs_vers,(a),(c),(s),&bpos,&mb,&xid)) == NULL) { \
162 			error = ENOBUFS; \
163 			goto nfsmout; \
164 		}
165 
166 #define nfsm_reqdone	m_freem(mrep); \
167 		nfsmout:
168 
169 #define nfsm_rndup(a)	(((a)+3)&(~0x3))
170 
171 #define	nfsm_request(v, t, p, h)	\
172 		if (error = nfs_request((v), mreq, xid, (t), (p), (h), \
173 		   (v)->v_mount, &mrep, &md, &dpos)) \
174 			goto nfsmout
175 
176 #define	nfsm_strtom(a,s,m) \
177 		if ((s) > (m)) { \
178 			m_freem(mreq); \
179 			error = ENAMETOOLONG; \
180 			goto nfsmout; \
181 		} \
182 		t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
183 		if(t2<=(NFSMSIZ(mb)-mb->m_len)){ \
184 			nfsm_build(tl,u_long *,t2); \
185 			*tl++ = txdr_unsigned(s); \
186 			*(tl+((t2>>2)-2)) = 0; \
187 			bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
188 		} else if (error = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
189 			m_freem(mreq); \
190 			goto nfsmout; \
191 		}
192 
193 #define	nfsm_srvdone \
194 		nfsmout: \
195 		return(error)
196 
197 #ifndef lint
198 #define	nfsm_reply(s) \
199 		{ \
200 		*repstat = error; \
201 		if (error) \
202 			nfs_rephead(0, xid, error, mrq, &mb, &bpos); \
203 		else \
204 			nfs_rephead((s), xid, error, mrq, &mb, &bpos); \
205 		m_freem(mrep); \
206 		mreq = *mrq; \
207 		if (error) \
208 			return(0); \
209 		}
210 #else	/* lint */
211 #define	nfsm_reply(s) \
212 		{ \
213 		*repstat = error; \
214 		if (error) \
215 			nfs_rephead(0, xid, error, mrq, &mb, &bpos); \
216 		else \
217 			nfs_rephead((s), xid, error, mrq, &mb, &bpos); \
218 		m_freem(mrep); \
219 		mreq = *mrq; \
220 		mrep = mreq; \
221 		if (error) \
222 			return(0); \
223 		}
224 #endif	/* lint */
225 
226 #define	nfsm_adv(s) \
227 		t1 = mtod(md, caddr_t)+md->m_len-dpos; \
228 		if (t1 >= (s)) { \
229 			dpos += (s); \
230 		} else if (error = nfs_adv(&md, &dpos, (s), t1)) { \
231 			m_freem(mrep); \
232 			goto nfsmout; \
233 		}
234 
235 #define nfsm_srvmtofh(f) \
236 		nfsm_disecton(tl, u_long *, NFSX_FH); \
237 		bcopy((caddr_t)tl, (caddr_t)f, NFSX_FH)
238 
239 #define	nfsm_clget \
240 		if (bp >= be) { \
241 			MGET(mp, M_WAIT, MT_DATA); \
242 			MCLGET(mp, M_WAIT); \
243 			mp->m_len = NFSMSIZ(mp); \
244 			if (mp3 == NULL) \
245 				mp3 = mp2 = mp; \
246 			else { \
247 				mp2->m_next = mp; \
248 				mp2 = mp; \
249 			} \
250 			bp = mtod(mp, caddr_t); \
251 			be = bp+mp->m_len; \
252 		} \
253 		tl = (u_long *)bp
254 
255 #define	nfsm_srvfillattr \
256 	fp->fa_type = vtonfs_type(vap->va_type); \
257 	fp->fa_mode = vtonfs_mode(vap->va_type, vap->va_mode); \
258 	fp->fa_nlink = txdr_unsigned(vap->va_nlink); \
259 	fp->fa_uid = txdr_unsigned(vap->va_uid); \
260 	fp->fa_gid = txdr_unsigned(vap->va_gid); \
261 	fp->fa_size = txdr_unsigned(vap->va_size); \
262 	fp->fa_blocksize = txdr_unsigned(vap->va_blocksize); \
263 	if (vap->va_type == VFIFO) \
264 		fp->fa_rdev = 0xffffffff; \
265 	else \
266 		fp->fa_rdev = txdr_unsigned(vap->va_rdev); \
267 	fp->fa_blocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); \
268 	fp->fa_fsid = txdr_unsigned(vap->va_fsid); \
269 	fp->fa_fileid = txdr_unsigned(vap->va_fileid); \
270 	fp->fa_atime.tv_sec = txdr_unsigned(vap->va_atime.tv_sec); \
271 	fp->fa_atime.tv_usec = txdr_unsigned(vap->va_flags); \
272 	txdr_time(&vap->va_mtime, &fp->fa_mtime); \
273 	fp->fa_ctime.tv_sec = txdr_unsigned(vap->va_ctime.tv_sec); \
274 	fp->fa_ctime.tv_usec = txdr_unsigned(vap->va_gen)
275 
276