nfsm_subs.h revision 1.41
1/*	$OpenBSD: nfsm_subs.h,v 1.41 2009/08/04 17:12:39 thib 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#define	NFSMSIZ(m)	(((m)->m_flags & M_EXT) ? (m)->m_ext.ext_size : \
44			    (((m)->m_flags & M_PKTHDR) ? MHLEN : MLEN))
45
46struct nfsm_info {
47	struct mbuf	 *nmi_mreq;
48	struct mbuf	 *nmi_mrep;
49
50	struct proc	 *nmi_procp;	/* XXX XXX XXX */
51	struct ucred	 *nmi_cred;	/* XXX XXX XXX */
52
53	/* Setting up / Tearing down. */
54	struct mbuf	 *nmi_md;
55	struct mbuf	 *nmi_mb;
56	caddr_t		  nmi_dpos;
57
58	int		  nmi_v3;
59};
60
61#define nfsm_dissect(a, c, s) {						\
62	t1 = mtod(info.nmi_md, caddr_t) + info.nmi_md->m_len -		\
63	    info.nmi_dpos;						\
64	if (t1 >= (s)) {						\
65		(a) = (c)(info.nmi_dpos);				\
66		info.nmi_dpos += (s);					\
67	} else if ((t1 =						\
68		  nfsm_disct(&info.nmi_md, &info.nmi_dpos, (s), t1,	\
69		      &cp2)) != 0) {					\
70		error = t1;						\
71		m_freem(info.nmi_mrep);					\
72		goto nfsmout;						\
73	} else {							\
74		(a) = (c)cp2;						\
75	}								\
76}
77
78#define nfsm_srvpostop_fh(f) {						\
79	tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED + NFSX_V3FH);	\
80	*tl++ = nfs_true;						\
81	*tl++ = txdr_unsigned(NFSX_V3FH);				\
82	bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH);			\
83}
84
85#define nfsm_mtofh(d, v, v3, f)	{					\
86	struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize;		\
87	if (v3) {							\
88		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);		\
89		(f) = fxdr_unsigned(int, *tl);				\
90	} else								\
91		(f) = 1;						\
92	if (f) {							\
93		nfsm_getfh(ttfhp, ttfhsize, (v3));			\
94		if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, 	\
95		    &ttnp)) != 0) {					\
96			error = t1;					\
97			m_freem(info.nmi_mrep);				\
98			goto nfsmout;					\
99		}							\
100		(v) = NFSTOV(ttnp);					\
101	}								\
102	if (v3) {							\
103		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);		\
104		if (f)							\
105			(f) = fxdr_unsigned(int, *tl);			\
106		else if (fxdr_unsigned(int, *tl))			\
107			nfsm_adv(NFSX_V3FATTR);				\
108	}								\
109	if (f)								\
110		nfsm_loadattr((v), NULL);				\
111}
112
113#define nfsm_getfh(f, s, v3) {						\
114	if (v3) {							\
115		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);		\
116		if (((s) = fxdr_unsigned(int, *tl)) <= 0 ||		\
117			(s) > NFSX_V3FHMAX) {				\
118			m_freem(info.nmi_mrep);				\
119			error = EBADRPC;				\
120			goto nfsmout;					\
121		}							\
122	} else								\
123		(s) = NFSX_V2FH;					\
124	nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); 			\
125}
126
127#define nfsm_loadattr(v, a) {						\
128	struct vnode *ttvp = (v);					\
129	if ((t1 = nfs_loadattrcache(&ttvp, &info.nmi_md,		\
130	    &info.nmi_dpos, (a))) != 0) {				\
131		error = t1;						\
132		m_freem(info.nmi_mrep);					\
133		goto nfsmout;						\
134	}								\
135	(v) = ttvp;							\
136}
137
138#define nfsm_postop_attr(v, f) { if (info.nmi_mrep != NULL) {		\
139	struct vnode *ttvp = (v);					\
140	nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);			\
141	if (((f) = fxdr_unsigned(int, *tl)) != 0) {			\
142		if ((t1 = nfs_loadattrcache(&ttvp, &info.nmi_md,	\
143		    &info.nmi_dpos, NULL)) != 0) {			\
144			error = t1;					\
145			(f) = 0;					\
146			m_freem(info.nmi_mrep);				\
147			goto nfsmout;					\
148		}							\
149		(v) = ttvp;						\
150	}								\
151} }
152
153/* Used as (f) for nfsm_wcc_data() */
154#define NFSV3_WCCRATTR	0
155#define NFSV3_WCCCHK	1
156
157#define nfsm_wcc_data(v, f) do { if (info.nmi_mrep != NULL) {		\
158	struct timespec	 _mtime;					\
159	int		 ttattrf, ttretf = 0;				\
160									\
161	nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);			\
162	if (*tl == nfs_true) {						\
163		nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED);	\
164		fxdr_nfsv3time(tl + 2, &_mtime);			\
165		if (f) {						\
166			ttretf = timespeccmp(&VTONFS(v)->n_mtime,	\
167			    &_mtime, !=);				\
168		}							\
169	}								\
170	nfsm_postop_attr((v), ttattrf);					\
171	if (f) {							\
172		(f) = ttretf;						\
173	} else {							\
174		(f) = ttattrf;						\
175	}								\
176} } while (0)
177
178#define nfsm_strsiz(s,m) {						\
179	nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED);			\
180	if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) {			\
181		m_freem(info.nmi_mrep);					\
182		error = EBADRPC;					\
183		goto nfsmout;						\
184	}								\
185}
186
187#define nfsm_srvnamesiz(s) {						\
188	nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED);			\
189	if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) 	\
190		error = NFSERR_NAMETOL;					\
191	if ((s) <= 0)							\
192		error = EBADRPC;					\
193	if (error)							\
194		nfsm_reply(0);						\
195}
196
197#define nfsm_mtouio(p,s)						\
198	if ((s) > 0 &&							\
199	    (t1 = nfsm_mbuftouio(&info.nmi_md,(p),(s),			\
200	        &info.nmi_dpos)) != 0) {				\
201		error = t1;						\
202		m_freem(info.nmi_mrep);					\
203		goto nfsmout;						\
204	}
205
206#define nfsm_rndup(a)	(((a)+3)&(~0x3))
207
208#define nfsm_strtom(a,s,m)						\
209	if ((s) > (m)) {						\
210		m_freem(info.nmi_mreq);					\
211		error = ENAMETOOLONG;					\
212		goto nfsmout;						\
213	}								\
214	nfsm_strtombuf(&info.nmi_mb, (a), (s))
215
216#define nfsm_reply(s) {							\
217	nfsd->nd_repstat = error;					\
218	if (error && !(nfsd->nd_flag & ND_NFSV3))			\
219	   (void) nfs_rephead(0, nfsd, slp, error,			\
220		&info.nmi_mreq, &info.nmi_mb);				\
221	else								\
222	   (void) nfs_rephead((s), nfsd, slp, error,			\
223		&info.nmi_mreq, &info.nmi_mb);				\
224	if (info.nmi_mrep != NULL) {					\
225		m_freem(info.nmi_mrep);					\
226		info.nmi_mrep = NULL;					\
227	}								\
228	if (error && (!(nfsd->nd_flag & ND_NFSV3) || error == EBADRPC))	\
229		return(0);						\
230}
231
232#define nfsm_writereply(s, v3) {					\
233	nfsd->nd_repstat = error;					\
234	if (error && !(v3))						\
235	   (void) nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq,	\
236	       &info.nmi_mb);						\
237	else								\
238	   (void) nfs_rephead((s), nfsd, slp, error, &info.nmi_mreq,	\
239	       &info.nmi_mb);						\
240}
241
242#define nfsm_adv(s) {							\
243	t1 = mtod(info.nmi_md, caddr_t) + info.nmi_md->m_len -		\
244	    info.nmi_dpos;						\
245	if (t1 >= (s)) {						\
246		info.nmi_dpos += (s);					\
247	} else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos,		\
248	      (s), t1)) != 0) {						\
249		error = t1;						\
250		m_freem(info.nmi_mrep);					\
251		goto nfsmout;						\
252	}								\
253}
254
255#define nfsm_srvmtofh(f) {						\
256	if (nfsd->nd_flag & ND_NFSV3) {					\
257		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);		\
258		if (fxdr_unsigned(int, *tl) != NFSX_V3FH) {		\
259			error = EBADRPC;				\
260			nfsm_reply(0);					\
261		}							\
262	}								\
263	nfsm_dissect(tl, u_int32_t *, NFSX_V3FH);			\
264	bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH);			\
265	if ((nfsd->nd_flag & ND_NFSV3) == 0)				\
266	nfsm_adv(NFSX_V2FH - NFSX_V3FH);				\
267}
268
269#endif
270