nfsm_subs.h revision 1.30
1/*	$OpenBSD: nfsm_subs.h,v 1.30 2008/06/14 22:44:07 blambert Exp $	*/
2/*	$NetBSD: nfsm_subs.h,v 1.10 1996/03/20 21:59:56 fvdl Exp $	*/
3
4/*
5 * Copyright (c) 1989, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Rick Macklem at The University of Guelph.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 *	@(#)nfsm_subs.h	8.2 (Berkeley) 3/30/95
36 */
37
38
39#ifndef _NFS_NFSM_SUBS_H_
40#define _NFS_NFSM_SUBS_H_
41
42
43/*
44 * These macros do strange and peculiar things to mbuf chains for
45 * the assistance of the nfs code. To attempt to use them for any
46 * other purpose will be dangerous. (they make weird assumptions)
47 */
48
49/*
50 * First define what the actual subs. return
51 */
52
53#define	M_HASCL(m)	((m)->m_flags & M_EXT)
54#define	NFSMADV(m, s)	(m)->m_data += (s)
55#define	NFSMSIZ(m)	((M_HASCL(m)) ? (m)->m_ext.ext_size : \
56				(((m)->m_flags & M_PKTHDR) ? MHLEN : MLEN))
57
58/*
59 * Now for the macros that do the simple stuff and call the functions
60 * for the hard stuff.
61 * These macros use several vars. declared in nfsm_reqhead and these
62 * vars. must not be used elsewhere unless you are careful not to corrupt
63 * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
64 * that may be used so long as the value is not expected to retained
65 * after a macro.
66 * I know, this is kind of dorkey, but it makes the actual op functions
67 * fairly clean and deals with the mess caused by the xdr discriminating
68 * unions.
69 */
70
71#define	nfsm_dissect(a, c, s) \
72		{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
73		if (t1 >= (s)) { \
74			(a) = (c)(dpos); \
75			dpos += (s); \
76		} else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \
77			error = t1; \
78			m_freem(mrep); \
79			goto nfsmout; \
80		} else { \
81			(a) = (c)cp2; \
82		} }
83
84#define nfsm_fhtom(v, v3) \
85	      { if (v3) { \
86			nfsm_strtombuf(&mb, VTONFS(v)->n_fhp, \
87			    VTONFS(v)->n_fhsize); \
88		} else { \
89			nfsm_buftombuf(&mb, VTONFS(v)->n_fhp, NFSX_V2FH); \
90		} }
91
92#define nfsm_srvfhtom(f, v3) \
93		{ if (v3) { \
94			nfsm_strtombuf(&mb, (f), NFSX_V3FH); \
95		} else { \
96			nfsm_buftombuf(&mb, (f), NFSX_V2FH); \
97		} }
98
99#define nfsm_srvpostop_fh(f) \
100		{ tl = nfsm_build(&mb, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
101		*tl++ = nfs_true; \
102		*tl++ = txdr_unsigned(NFSX_V3FH); \
103		bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
104		}
105
106#define nfsm_mtofh(d, v, v3, f) \
107		{ struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \
108		if (v3) { \
109			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
110			(f) = fxdr_unsigned(int, *tl); \
111		} else \
112			(f) = 1; \
113		if (f) { \
114			nfsm_getfh(ttfhp, ttfhsize, (v3)); \
115			if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
116				&ttnp)) != 0) { \
117				error = t1; \
118				m_freem(mrep); \
119				goto nfsmout; \
120			} \
121			(v) = NFSTOV(ttnp); \
122		} \
123		if (v3) { \
124			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
125			if (f) \
126				(f) = fxdr_unsigned(int, *tl); \
127			else if (fxdr_unsigned(int, *tl)) \
128				nfsm_adv(NFSX_V3FATTR); \
129		} \
130		if (f) \
131			nfsm_loadattr((v), (struct vattr *)0); \
132		}
133
134#define nfsm_getfh(f, s, v3) \
135		{ if (v3) { \
136			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
137			if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \
138				(s) > NFSX_V3FHMAX) { \
139				m_freem(mrep); \
140				error = EBADRPC; \
141				goto nfsmout; \
142			} \
143		} else \
144			(s) = NFSX_V2FH; \
145		nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); }
146
147#define	nfsm_loadattr(v, a) \
148		{ struct vnode *ttvp = (v); \
149		if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
150			error = t1; \
151			m_freem(mrep); \
152			goto nfsmout; \
153		} \
154		(v) = ttvp; }
155
156#define	nfsm_postop_attr(v, f) \
157		{ struct vnode *ttvp = (v); \
158		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
159		if (((f) = fxdr_unsigned(int, *tl)) != 0) { \
160			if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
161				(struct vattr *)0)) != 0) { \
162				error = t1; \
163				(f) = 0; \
164				m_freem(mrep); \
165				goto nfsmout; \
166			} \
167			(v) = ttvp; \
168		} }
169
170/* Used as (f) for nfsm_wcc_data() */
171#define NFSV3_WCCRATTR	0
172#define NFSV3_WCCCHK	1
173
174#define	nfsm_wcc_data(v, f) \
175		{ int ttattrf, ttretf = 0; \
176		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
177		if (*tl == nfs_true) { \
178			nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); \
179			if (f) \
180				ttretf = (VTONFS(v)->n_mtime == \
181					fxdr_unsigned(u_int32_t, *(tl + 2))); \
182		} \
183		nfsm_postop_attr((v), ttattrf); \
184		if (f) { \
185			(f) = ttretf; \
186		} else { \
187			(f) = ttattrf; \
188		} }
189
190#define	nfsm_strsiz(s,m) \
191		{ nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
192		if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \
193			m_freem(mrep); \
194			error = EBADRPC; \
195			goto nfsmout; \
196		} }
197
198#define	nfsm_srvstrsiz(s,m) \
199		{ nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
200		if (((s) = fxdr_unsigned(int32_t,*tl)) > (m) || (s) <= 0) { \
201			error = EBADRPC; \
202			nfsm_reply(0); \
203		} }
204
205#define	nfsm_srvnamesiz(s) \
206		{ nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
207		if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) \
208			error = NFSERR_NAMETOL; \
209		if ((s) <= 0) \
210			error = EBADRPC; \
211		if (error) \
212			nfsm_reply(0); \
213		}
214
215#define nfsm_mtouio(p,s) \
216		if ((s) > 0 && \
217		   (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
218			error = t1; \
219			m_freem(mrep); \
220			goto nfsmout; \
221		}
222
223#define nfsm_rndup(a)	(((a)+3)&(~0x3))
224
225#define	nfsm_request(v, t, p, c)	\
226		if ((error = nfs_request((v), mreq, (t), (p), \
227		   (c), &mrep, &md, &dpos)) != 0) { \
228			if (error & NFSERR_RETERR) \
229				error &= ~NFSERR_RETERR; \
230			else \
231				goto nfsmout; \
232		}
233
234#define	nfsm_strtom(a,s,m) \
235		if ((s) > (m)) { \
236			m_freem(mreq); \
237			error = ENAMETOOLONG; \
238			goto nfsmout; \
239		} \
240		nfsm_strtombuf(&mb, (a), (s))
241
242#define	nfsm_reply(s) \
243		{ \
244		nfsd->nd_repstat = error; \
245		if (error && !(nfsd->nd_flag & ND_NFSV3)) \
246		   (void) nfs_rephead(0, nfsd, slp, error, \
247			mrq, &mb); \
248		else \
249		   (void) nfs_rephead((s), nfsd, slp, error, \
250			mrq, &mb); \
251		if (mrep != NULL) { \
252			m_freem(mrep); \
253			mrep = NULL; \
254		} \
255		mreq = *mrq; \
256		if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
257			error == EBADRPC)) \
258			return(0); \
259		}
260
261#define	nfsm_writereply(s, v3) \
262		{ \
263		nfsd->nd_repstat = error; \
264		if (error && !(v3)) \
265		   (void) nfs_rephead(0, nfsd, slp, error, \
266			&mreq, &mb); \
267		else \
268		   (void) nfs_rephead((s), nfsd, slp, error, \
269			&mreq, &mb); \
270		}
271
272#define	nfsm_adv(s) \
273		{ t1 = mtod(md, caddr_t)+md->m_len-dpos; \
274		if (t1 >= (s)) { \
275			dpos += (s); \
276		} else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \
277			error = t1; \
278			m_freem(mrep); \
279			goto nfsmout; \
280		} }
281
282#define nfsm_srvmtofh(f) \
283		{ if (nfsd->nd_flag & ND_NFSV3) { \
284			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
285			if (fxdr_unsigned(int, *tl) != NFSX_V3FH) { \
286				error = EBADRPC; \
287				nfsm_reply(0); \
288			} \
289		} \
290		nfsm_dissect(tl, u_int32_t *, NFSX_V3FH); \
291		bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
292		if ((nfsd->nd_flag & ND_NFSV3) == 0) \
293			nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
294		}
295
296#define nfsm_srvsattr(a) \
297		{ nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
298		if (*tl == nfs_true) { \
299			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
300			(a)->va_mode = nfstov_mode(*tl); \
301		} \
302		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
303		if (*tl == nfs_true) { \
304			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
305			(a)->va_uid = fxdr_unsigned(uid_t, *tl); \
306		} \
307		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
308		if (*tl == nfs_true) { \
309			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
310			(a)->va_gid = fxdr_unsigned(gid_t, *tl); \
311		} \
312		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
313		if (*tl == nfs_true) { \
314			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
315			(a)->va_size = fxdr_hyper(tl); \
316		} \
317		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
318		switch (fxdr_unsigned(int, *tl)) { \
319		case NFSV3SATTRTIME_TOCLIENT: \
320			(a)->va_vaflags &= ~VA_UTIMES_NULL; \
321			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
322			fxdr_nfsv3time(tl, &(a)->va_atime); \
323			break; \
324		case NFSV3SATTRTIME_TOSERVER: \
325			getnanotime(&(a)->va_atime); \
326			break; \
327		}; \
328		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
329		switch (fxdr_unsigned(int, *tl)) { \
330		case NFSV3SATTRTIME_TOCLIENT: \
331			(a)->va_vaflags &= ~VA_UTIMES_NULL; \
332			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
333			fxdr_nfsv3time(tl, &(a)->va_mtime); \
334			break; \
335		case NFSV3SATTRTIME_TOSERVER: \
336			getnanotime(&(a)->va_mtime); \
337			break; \
338		}; }
339
340#endif
341