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