Deleted Added
full compact
nfsm_subs.h (27446) nfsm_subs.h (33054)
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. 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 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. 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 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95
37 * $Id: nfsm_subs.h,v 1.12 1997/02/22 09:42:48 peter Exp $
37 * $Id: nfsm_subs.h,v 1.13 1997/07/16 09:06:30 dfr Exp $
38 */
39
40
41#ifndef _NFS_NFSM_SUBS_H_
42#define _NFS_NFSM_SUBS_H_
43
38 */
39
40
41#ifndef _NFS_NFSM_SUBS_H_
42#define _NFS_NFSM_SUBS_H_
43
44struct ucred;
45struct vnode;
44
45/*
46 * These macros do strange and peculiar things to mbuf chains for
47 * the assistance of the nfs code. To attempt to use them for any
48 * other purpose will be dangerous. (they make weird assumptions)
49 */
50
51/*
52 * First define what the actual subs. return
53 */
54struct mbuf *nfsm_reqh __P((struct vnode *vp, u_long procid, int hsiz,
55 caddr_t *bposp));
56struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
57 int auth_type, int auth_len, char *auth_str,
58 int verf_len, char *verf_str,
59 struct mbuf *mrest, int mrest_len,
60 struct mbuf **mbp, u_long *xidp));
61
62#define M_HASCL(m) ((m)->m_flags & M_EXT)
63#define NFSMINOFF(m) \
64 if (M_HASCL(m)) \
65 (m)->m_data = (m)->m_ext.ext_buf; \
66 else if ((m)->m_flags & M_PKTHDR) \
67 (m)->m_data = (m)->m_pktdat; \
68 else \
69 (m)->m_data = (m)->m_dat
70#define NFSMADV(m, s) (m)->m_data += (s)
71#define NFSMSIZ(m) ((M_HASCL(m))?MCLBYTES: \
72 (((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
73
74/*
75 * Now for the macros that do the simple stuff and call the functions
76 * for the hard stuff.
77 * These macros use several vars. declared in nfsm_reqhead and these
78 * vars. must not be used elsewhere unless you are careful not to corrupt
79 * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
80 * that may be used so long as the value is not expected to retained
81 * after a macro.
82 * I know, this is kind of dorkey, but it makes the actual op functions
83 * fairly clean and deals with the mess caused by the xdr discriminating
84 * unions.
85 */
86
87#define nfsm_build(a,c,s) \
88 { if ((s) > M_TRAILINGSPACE(mb)) { \
89 MGET(mb2, M_WAIT, MT_DATA); \
90 if ((s) > MLEN) \
91 panic("build > MLEN"); \
92 mb->m_next = mb2; \
93 mb = mb2; \
94 mb->m_len = 0; \
95 bpos = mtod(mb, caddr_t); \
96 } \
97 (a) = (c)(bpos); \
98 mb->m_len += (s); \
99 bpos += (s); }
100
101#define nfsm_dissect(a, c, s) \
102 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
103 if (t1 >= (s)) { \
104 (a) = (c)(dpos); \
105 dpos += (s); \
106 } else if (t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) { \
107 error = t1; \
108 m_freem(mrep); \
109 goto nfsmout; \
110 } else { \
111 (a) = (c)cp2; \
112 } }
113
114#define nfsm_fhtom(v, v3) \
115 { if (v3) { \
116 t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \
117 if (t2 <= M_TRAILINGSPACE(mb)) { \
118 nfsm_build(tl, u_long *, t2); \
119 *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \
120 *(tl + ((t2>>2) - 2)) = 0; \
121 bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
122 VTONFS(v)->n_fhsize); \
123 } else if (t2 = nfsm_strtmbuf(&mb, &bpos, \
124 (caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize)) { \
125 error = t2; \
126 m_freem(mreq); \
127 goto nfsmout; \
128 } \
129 } else { \
130 nfsm_build(cp, caddr_t, NFSX_V2FH); \
131 bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \
132 } }
133
134#define nfsm_srvfhtom(f, v3) \
135 { if (v3) { \
136 nfsm_build(tl, u_long *, NFSX_UNSIGNED + NFSX_V3FH); \
137 *tl++ = txdr_unsigned(NFSX_V3FH); \
138 bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
139 } else { \
140 nfsm_build(cp, caddr_t, NFSX_V2FH); \
141 bcopy((caddr_t)(f), cp, NFSX_V2FH); \
142 } }
143
144#define nfsm_srvpostop_fh(f) \
145 { nfsm_build(tl, u_long *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
146 *tl++ = nfs_true; \
147 *tl++ = txdr_unsigned(NFSX_V3FH); \
148 bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
149 }
150
151#define nfsm_mtofh(d, v, v3, f) \
152 { struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \
153 if (v3) { \
154 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
155 (f) = fxdr_unsigned(int, *tl); \
156 } else \
157 (f) = 1; \
158 if (f) { \
159 nfsm_getfh(ttfhp, ttfhsize, (v3)); \
160 if (t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
161 &ttnp)) { \
162 error = t1; \
163 m_freem(mrep); \
164 goto nfsmout; \
165 } \
166 (v) = NFSTOV(ttnp); \
167 } \
168 if (v3) { \
169 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
170 if (f) \
171 (f) = fxdr_unsigned(int, *tl); \
172 else if (fxdr_unsigned(int, *tl)) \
173 nfsm_adv(NFSX_V3FATTR); \
174 } \
175 if (f) \
176 nfsm_loadattr((v), (struct vattr *)0); \
177 }
178
179#define nfsm_getfh(f, s, v3) \
180 { if (v3) { \
181 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
182 if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \
183 (s) > NFSX_V3FHMAX) { \
184 m_freem(mrep); \
185 error = EBADRPC; \
186 goto nfsmout; \
187 } \
188 } else \
189 (s) = NFSX_V2FH; \
190 nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); }
191
192#define nfsm_loadattr(v, a) \
193 { struct vnode *ttvp = (v); \
194 if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) { \
195 error = t1; \
196 m_freem(mrep); \
197 goto nfsmout; \
198 } \
199 (v) = ttvp; }
200
201#define nfsm_postop_attr(v, f) \
202 { struct vnode *ttvp = (v); \
203 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
204 if ((f) = fxdr_unsigned(int, *tl)) { \
205 if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
206 (struct vattr *)0)) { \
207 error = t1; \
208 (f) = 0; \
209 m_freem(mrep); \
210 goto nfsmout; \
211 } \
212 (v) = ttvp; \
213 } }
214
215/* Used as (f) for nfsm_wcc_data() */
216#define NFSV3_WCCRATTR 0
217#define NFSV3_WCCCHK 1
218
219#define nfsm_wcc_data(v, f) \
220 { int ttattrf, ttretf = 0; \
221 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
222 if (*tl == nfs_true) { \
223 nfsm_dissect(tl, u_long *, 6 * NFSX_UNSIGNED); \
224 if (f) \
225 ttretf = (VTONFS(v)->n_mtime == \
226 fxdr_unsigned(u_long, *(tl + 2))); \
227 } \
228 nfsm_postop_attr((v), ttattrf); \
229 if (f) { \
230 (f) = ttretf; \
231 } else { \
232 (f) = ttattrf; \
233 } }
234
235#define nfsm_v3sattr(s, a, u, g) \
236 { (s)->sa_modetrue = nfs_true; \
237 (s)->sa_mode = vtonfsv3_mode((a)->va_mode); \
238 (s)->sa_uidtrue = nfs_true; \
239 (s)->sa_uid = txdr_unsigned(u); \
240 (s)->sa_gidtrue = nfs_true; \
241 (s)->sa_gid = txdr_unsigned(g); \
242 (s)->sa_sizefalse = nfs_false; \
243 (s)->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
244 txdr_nfsv3time(&(a)->va_atime, &(s)->sa_atime); \
245 (s)->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
246 txdr_nfsv3time(&(a)->va_mtime, &(s)->sa_mtime); \
247 }
248
249#define nfsm_strsiz(s,m) \
250 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
251 if (((s) = fxdr_unsigned(long,*tl)) > (m)) { \
252 m_freem(mrep); \
253 error = EBADRPC; \
254 goto nfsmout; \
255 } }
256
257#define nfsm_srvstrsiz(s,m) \
258 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
259 if (((s) = fxdr_unsigned(long,*tl)) > (m) || (s) <= 0) { \
260 error = EBADRPC; \
261 nfsm_reply(0); \
262 } }
263
264#define nfsm_srvnamesiz(s) \
265 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
266 if (((s) = fxdr_unsigned(long,*tl)) > NFS_MAXNAMLEN) \
267 error = NFSERR_NAMETOL; \
268 if ((s) <= 0) \
269 error = EBADRPC; \
270 if (error) \
271 nfsm_reply(0); \
272 }
273
274#define nfsm_mtouio(p,s) \
275 if ((s) > 0 && \
276 (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
277 error = t1; \
278 m_freem(mrep); \
279 goto nfsmout; \
280 }
281
282#define nfsm_uiotom(p,s) \
283 if (t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
284 error = t1; \
285 m_freem(mreq); \
286 goto nfsmout; \
287 }
288
289#define nfsm_reqhead(v,a,s) \
290 mb = mreq = nfsm_reqh((v),(a),(s),&bpos)
291
292#define nfsm_reqdone m_freem(mrep); \
293 nfsmout:
294
295#define nfsm_rndup(a) (((a)+3)&(~0x3))
296
297#define nfsm_request(v, t, p, c) \
298 if (error = nfs_request((v), mreq, (t), (p), \
299 (c), &mrep, &md, &dpos)) { \
300 if (error & NFSERR_RETERR) \
301 error &= ~NFSERR_RETERR; \
302 else \
303 goto nfsmout; \
304 }
305
306#define nfsm_strtom(a,s,m) \
307 if ((s) > (m)) { \
308 m_freem(mreq); \
309 error = ENAMETOOLONG; \
310 goto nfsmout; \
311 } \
312 t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
313 if (t2 <= M_TRAILINGSPACE(mb)) { \
314 nfsm_build(tl,u_long *,t2); \
315 *tl++ = txdr_unsigned(s); \
316 *(tl+((t2>>2)-2)) = 0; \
317 bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
318 } else if (t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
319 error = t2; \
320 m_freem(mreq); \
321 goto nfsmout; \
322 }
323
324#define nfsm_srvdone \
325 nfsmout: \
326 return(error)
327
328#define nfsm_reply(s) \
329 { \
330 nfsd->nd_repstat = error; \
331 if (error && !(nfsd->nd_flag & ND_NFSV3)) \
332 (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
333 mrq, &mb, &bpos); \
334 else \
335 (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
336 mrq, &mb, &bpos); \
337 m_freem(mrep); \
338 mreq = *mrq; \
339 if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
340 error == EBADRPC)) \
341 return(0); \
342 }
343
344#define nfsm_writereply(s, v3) \
345 { \
346 nfsd->nd_repstat = error; \
347 if (error && !(v3)) \
348 (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
349 &mreq, &mb, &bpos); \
350 else \
351 (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
352 &mreq, &mb, &bpos); \
353 }
354
355#define nfsm_adv(s) \
356 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
357 if (t1 >= (s)) { \
358 dpos += (s); \
359 } else if (t1 = nfs_adv(&md, &dpos, (s), t1)) { \
360 error = t1; \
361 m_freem(mrep); \
362 goto nfsmout; \
363 } }
364
365#define nfsm_srvmtofh(f) \
366 { int fhlen = NFSX_V3FH; \
367 if (nfsd->nd_flag & ND_NFSV3) { \
368 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
369 fhlen = fxdr_unsigned(int, *tl); \
370 if (fhlen == 0) { \
371 bzero((caddr_t)(f), NFSX_V3FH); \
372 } else if (fhlen != NFSX_V3FH) { \
373 error = EBADRPC; \
374 nfsm_reply(0); \
375 } \
376 } \
377 if (fhlen != 0) { \
378 nfsm_dissect(tl, u_long *, NFSX_V3FH); \
379 bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
380 if ((nfsd->nd_flag & ND_NFSV3) == 0) \
381 nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
382 } \
383 }
384
385#define nfsm_clget \
386 if (bp >= be) { \
387 if (mp == mb) \
388 mp->m_len += bp-bpos; \
389 MGET(mp, M_WAIT, MT_DATA); \
390 MCLGET(mp, M_WAIT); \
391 mp->m_len = NFSMSIZ(mp); \
392 mp2->m_next = mp; \
393 mp2 = mp; \
394 bp = mtod(mp, caddr_t); \
395 be = bp+mp->m_len; \
396 } \
397 tl = (u_long *)bp
398
399#define nfsm_srvfillattr(a, f) \
400 nfsm_srvfattr(nfsd, (a), (f))
401
402#define nfsm_srvwcc_data(br, b, ar, a) \
403 nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos)
404
405#define nfsm_srvpostop_attr(r, a) \
406 nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos)
407
408#define nfsm_srvsattr(a) \
409 { nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
410 if (*tl == nfs_true) { \
411 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
412 (a)->va_mode = nfstov_mode(*tl); \
413 } \
414 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
415 if (*tl == nfs_true) { \
416 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
417 (a)->va_uid = fxdr_unsigned(uid_t, *tl); \
418 } \
419 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
420 if (*tl == nfs_true) { \
421 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
422 (a)->va_gid = fxdr_unsigned(gid_t, *tl); \
423 } \
424 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
425 if (*tl == nfs_true) { \
426 nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
427 fxdr_hyper(tl, &(a)->va_size); \
428 } \
429 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
430 switch (fxdr_unsigned(int, *tl)) { \
431 case NFSV3SATTRTIME_TOCLIENT: \
432 nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
433 fxdr_nfsv3time(tl, &(a)->va_atime); \
434 break; \
435 case NFSV3SATTRTIME_TOSERVER: \
436 (a)->va_atime.tv_sec = time.tv_sec; \
437 (a)->va_atime.tv_nsec = time.tv_usec * 1000; \
438 break; \
439 }; \
440 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
441 switch (fxdr_unsigned(int, *tl)) { \
442 case NFSV3SATTRTIME_TOCLIENT: \
443 nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
444 fxdr_nfsv3time(tl, &(a)->va_mtime); \
445 break; \
446 case NFSV3SATTRTIME_TOSERVER: \
447 (a)->va_mtime.tv_sec = time.tv_sec; \
448 (a)->va_mtime.tv_nsec = time.tv_usec * 1000; \
449 break; \
450 }; }
451
452#endif
46
47/*
48 * These macros do strange and peculiar things to mbuf chains for
49 * the assistance of the nfs code. To attempt to use them for any
50 * other purpose will be dangerous. (they make weird assumptions)
51 */
52
53/*
54 * First define what the actual subs. return
55 */
56struct mbuf *nfsm_reqh __P((struct vnode *vp, u_long procid, int hsiz,
57 caddr_t *bposp));
58struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
59 int auth_type, int auth_len, char *auth_str,
60 int verf_len, char *verf_str,
61 struct mbuf *mrest, int mrest_len,
62 struct mbuf **mbp, u_long *xidp));
63
64#define M_HASCL(m) ((m)->m_flags & M_EXT)
65#define NFSMINOFF(m) \
66 if (M_HASCL(m)) \
67 (m)->m_data = (m)->m_ext.ext_buf; \
68 else if ((m)->m_flags & M_PKTHDR) \
69 (m)->m_data = (m)->m_pktdat; \
70 else \
71 (m)->m_data = (m)->m_dat
72#define NFSMADV(m, s) (m)->m_data += (s)
73#define NFSMSIZ(m) ((M_HASCL(m))?MCLBYTES: \
74 (((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
75
76/*
77 * Now for the macros that do the simple stuff and call the functions
78 * for the hard stuff.
79 * These macros use several vars. declared in nfsm_reqhead and these
80 * vars. must not be used elsewhere unless you are careful not to corrupt
81 * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
82 * that may be used so long as the value is not expected to retained
83 * after a macro.
84 * I know, this is kind of dorkey, but it makes the actual op functions
85 * fairly clean and deals with the mess caused by the xdr discriminating
86 * unions.
87 */
88
89#define nfsm_build(a,c,s) \
90 { if ((s) > M_TRAILINGSPACE(mb)) { \
91 MGET(mb2, M_WAIT, MT_DATA); \
92 if ((s) > MLEN) \
93 panic("build > MLEN"); \
94 mb->m_next = mb2; \
95 mb = mb2; \
96 mb->m_len = 0; \
97 bpos = mtod(mb, caddr_t); \
98 } \
99 (a) = (c)(bpos); \
100 mb->m_len += (s); \
101 bpos += (s); }
102
103#define nfsm_dissect(a, c, s) \
104 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
105 if (t1 >= (s)) { \
106 (a) = (c)(dpos); \
107 dpos += (s); \
108 } else if (t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) { \
109 error = t1; \
110 m_freem(mrep); \
111 goto nfsmout; \
112 } else { \
113 (a) = (c)cp2; \
114 } }
115
116#define nfsm_fhtom(v, v3) \
117 { if (v3) { \
118 t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \
119 if (t2 <= M_TRAILINGSPACE(mb)) { \
120 nfsm_build(tl, u_long *, t2); \
121 *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \
122 *(tl + ((t2>>2) - 2)) = 0; \
123 bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
124 VTONFS(v)->n_fhsize); \
125 } else if (t2 = nfsm_strtmbuf(&mb, &bpos, \
126 (caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize)) { \
127 error = t2; \
128 m_freem(mreq); \
129 goto nfsmout; \
130 } \
131 } else { \
132 nfsm_build(cp, caddr_t, NFSX_V2FH); \
133 bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \
134 } }
135
136#define nfsm_srvfhtom(f, v3) \
137 { if (v3) { \
138 nfsm_build(tl, u_long *, NFSX_UNSIGNED + NFSX_V3FH); \
139 *tl++ = txdr_unsigned(NFSX_V3FH); \
140 bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
141 } else { \
142 nfsm_build(cp, caddr_t, NFSX_V2FH); \
143 bcopy((caddr_t)(f), cp, NFSX_V2FH); \
144 } }
145
146#define nfsm_srvpostop_fh(f) \
147 { nfsm_build(tl, u_long *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
148 *tl++ = nfs_true; \
149 *tl++ = txdr_unsigned(NFSX_V3FH); \
150 bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
151 }
152
153#define nfsm_mtofh(d, v, v3, f) \
154 { struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \
155 if (v3) { \
156 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
157 (f) = fxdr_unsigned(int, *tl); \
158 } else \
159 (f) = 1; \
160 if (f) { \
161 nfsm_getfh(ttfhp, ttfhsize, (v3)); \
162 if (t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
163 &ttnp)) { \
164 error = t1; \
165 m_freem(mrep); \
166 goto nfsmout; \
167 } \
168 (v) = NFSTOV(ttnp); \
169 } \
170 if (v3) { \
171 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
172 if (f) \
173 (f) = fxdr_unsigned(int, *tl); \
174 else if (fxdr_unsigned(int, *tl)) \
175 nfsm_adv(NFSX_V3FATTR); \
176 } \
177 if (f) \
178 nfsm_loadattr((v), (struct vattr *)0); \
179 }
180
181#define nfsm_getfh(f, s, v3) \
182 { if (v3) { \
183 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
184 if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \
185 (s) > NFSX_V3FHMAX) { \
186 m_freem(mrep); \
187 error = EBADRPC; \
188 goto nfsmout; \
189 } \
190 } else \
191 (s) = NFSX_V2FH; \
192 nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); }
193
194#define nfsm_loadattr(v, a) \
195 { struct vnode *ttvp = (v); \
196 if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) { \
197 error = t1; \
198 m_freem(mrep); \
199 goto nfsmout; \
200 } \
201 (v) = ttvp; }
202
203#define nfsm_postop_attr(v, f) \
204 { struct vnode *ttvp = (v); \
205 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
206 if ((f) = fxdr_unsigned(int, *tl)) { \
207 if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
208 (struct vattr *)0)) { \
209 error = t1; \
210 (f) = 0; \
211 m_freem(mrep); \
212 goto nfsmout; \
213 } \
214 (v) = ttvp; \
215 } }
216
217/* Used as (f) for nfsm_wcc_data() */
218#define NFSV3_WCCRATTR 0
219#define NFSV3_WCCCHK 1
220
221#define nfsm_wcc_data(v, f) \
222 { int ttattrf, ttretf = 0; \
223 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
224 if (*tl == nfs_true) { \
225 nfsm_dissect(tl, u_long *, 6 * NFSX_UNSIGNED); \
226 if (f) \
227 ttretf = (VTONFS(v)->n_mtime == \
228 fxdr_unsigned(u_long, *(tl + 2))); \
229 } \
230 nfsm_postop_attr((v), ttattrf); \
231 if (f) { \
232 (f) = ttretf; \
233 } else { \
234 (f) = ttattrf; \
235 } }
236
237#define nfsm_v3sattr(s, a, u, g) \
238 { (s)->sa_modetrue = nfs_true; \
239 (s)->sa_mode = vtonfsv3_mode((a)->va_mode); \
240 (s)->sa_uidtrue = nfs_true; \
241 (s)->sa_uid = txdr_unsigned(u); \
242 (s)->sa_gidtrue = nfs_true; \
243 (s)->sa_gid = txdr_unsigned(g); \
244 (s)->sa_sizefalse = nfs_false; \
245 (s)->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
246 txdr_nfsv3time(&(a)->va_atime, &(s)->sa_atime); \
247 (s)->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
248 txdr_nfsv3time(&(a)->va_mtime, &(s)->sa_mtime); \
249 }
250
251#define nfsm_strsiz(s,m) \
252 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
253 if (((s) = fxdr_unsigned(long,*tl)) > (m)) { \
254 m_freem(mrep); \
255 error = EBADRPC; \
256 goto nfsmout; \
257 } }
258
259#define nfsm_srvstrsiz(s,m) \
260 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
261 if (((s) = fxdr_unsigned(long,*tl)) > (m) || (s) <= 0) { \
262 error = EBADRPC; \
263 nfsm_reply(0); \
264 } }
265
266#define nfsm_srvnamesiz(s) \
267 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
268 if (((s) = fxdr_unsigned(long,*tl)) > NFS_MAXNAMLEN) \
269 error = NFSERR_NAMETOL; \
270 if ((s) <= 0) \
271 error = EBADRPC; \
272 if (error) \
273 nfsm_reply(0); \
274 }
275
276#define nfsm_mtouio(p,s) \
277 if ((s) > 0 && \
278 (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
279 error = t1; \
280 m_freem(mrep); \
281 goto nfsmout; \
282 }
283
284#define nfsm_uiotom(p,s) \
285 if (t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
286 error = t1; \
287 m_freem(mreq); \
288 goto nfsmout; \
289 }
290
291#define nfsm_reqhead(v,a,s) \
292 mb = mreq = nfsm_reqh((v),(a),(s),&bpos)
293
294#define nfsm_reqdone m_freem(mrep); \
295 nfsmout:
296
297#define nfsm_rndup(a) (((a)+3)&(~0x3))
298
299#define nfsm_request(v, t, p, c) \
300 if (error = nfs_request((v), mreq, (t), (p), \
301 (c), &mrep, &md, &dpos)) { \
302 if (error & NFSERR_RETERR) \
303 error &= ~NFSERR_RETERR; \
304 else \
305 goto nfsmout; \
306 }
307
308#define nfsm_strtom(a,s,m) \
309 if ((s) > (m)) { \
310 m_freem(mreq); \
311 error = ENAMETOOLONG; \
312 goto nfsmout; \
313 } \
314 t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
315 if (t2 <= M_TRAILINGSPACE(mb)) { \
316 nfsm_build(tl,u_long *,t2); \
317 *tl++ = txdr_unsigned(s); \
318 *(tl+((t2>>2)-2)) = 0; \
319 bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
320 } else if (t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
321 error = t2; \
322 m_freem(mreq); \
323 goto nfsmout; \
324 }
325
326#define nfsm_srvdone \
327 nfsmout: \
328 return(error)
329
330#define nfsm_reply(s) \
331 { \
332 nfsd->nd_repstat = error; \
333 if (error && !(nfsd->nd_flag & ND_NFSV3)) \
334 (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
335 mrq, &mb, &bpos); \
336 else \
337 (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
338 mrq, &mb, &bpos); \
339 m_freem(mrep); \
340 mreq = *mrq; \
341 if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
342 error == EBADRPC)) \
343 return(0); \
344 }
345
346#define nfsm_writereply(s, v3) \
347 { \
348 nfsd->nd_repstat = error; \
349 if (error && !(v3)) \
350 (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
351 &mreq, &mb, &bpos); \
352 else \
353 (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
354 &mreq, &mb, &bpos); \
355 }
356
357#define nfsm_adv(s) \
358 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
359 if (t1 >= (s)) { \
360 dpos += (s); \
361 } else if (t1 = nfs_adv(&md, &dpos, (s), t1)) { \
362 error = t1; \
363 m_freem(mrep); \
364 goto nfsmout; \
365 } }
366
367#define nfsm_srvmtofh(f) \
368 { int fhlen = NFSX_V3FH; \
369 if (nfsd->nd_flag & ND_NFSV3) { \
370 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
371 fhlen = fxdr_unsigned(int, *tl); \
372 if (fhlen == 0) { \
373 bzero((caddr_t)(f), NFSX_V3FH); \
374 } else if (fhlen != NFSX_V3FH) { \
375 error = EBADRPC; \
376 nfsm_reply(0); \
377 } \
378 } \
379 if (fhlen != 0) { \
380 nfsm_dissect(tl, u_long *, NFSX_V3FH); \
381 bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
382 if ((nfsd->nd_flag & ND_NFSV3) == 0) \
383 nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
384 } \
385 }
386
387#define nfsm_clget \
388 if (bp >= be) { \
389 if (mp == mb) \
390 mp->m_len += bp-bpos; \
391 MGET(mp, M_WAIT, MT_DATA); \
392 MCLGET(mp, M_WAIT); \
393 mp->m_len = NFSMSIZ(mp); \
394 mp2->m_next = mp; \
395 mp2 = mp; \
396 bp = mtod(mp, caddr_t); \
397 be = bp+mp->m_len; \
398 } \
399 tl = (u_long *)bp
400
401#define nfsm_srvfillattr(a, f) \
402 nfsm_srvfattr(nfsd, (a), (f))
403
404#define nfsm_srvwcc_data(br, b, ar, a) \
405 nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos)
406
407#define nfsm_srvpostop_attr(r, a) \
408 nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos)
409
410#define nfsm_srvsattr(a) \
411 { nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
412 if (*tl == nfs_true) { \
413 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
414 (a)->va_mode = nfstov_mode(*tl); \
415 } \
416 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
417 if (*tl == nfs_true) { \
418 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
419 (a)->va_uid = fxdr_unsigned(uid_t, *tl); \
420 } \
421 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
422 if (*tl == nfs_true) { \
423 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
424 (a)->va_gid = fxdr_unsigned(gid_t, *tl); \
425 } \
426 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
427 if (*tl == nfs_true) { \
428 nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
429 fxdr_hyper(tl, &(a)->va_size); \
430 } \
431 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
432 switch (fxdr_unsigned(int, *tl)) { \
433 case NFSV3SATTRTIME_TOCLIENT: \
434 nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
435 fxdr_nfsv3time(tl, &(a)->va_atime); \
436 break; \
437 case NFSV3SATTRTIME_TOSERVER: \
438 (a)->va_atime.tv_sec = time.tv_sec; \
439 (a)->va_atime.tv_nsec = time.tv_usec * 1000; \
440 break; \
441 }; \
442 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
443 switch (fxdr_unsigned(int, *tl)) { \
444 case NFSV3SATTRTIME_TOCLIENT: \
445 nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
446 fxdr_nfsv3time(tl, &(a)->va_mtime); \
447 break; \
448 case NFSV3SATTRTIME_TOSERVER: \
449 (a)->va_mtime.tv_sec = time.tv_sec; \
450 (a)->va_mtime.tv_nsec = time.tv_usec * 1000; \
451 break; \
452 }; }
453
454#endif