Annotation of sys/nfs/nfsm_subs.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: nfsm_subs.h,v 1.16 2006/04/02 18:35:11 otto 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 NFSMINOFF(m) \
55: if (M_HASCL(m)) \
56: (m)->m_data = (m)->m_ext.ext_buf; \
57: else if ((m)->m_flags & M_PKTHDR) \
58: (m)->m_data = (m)->m_pktdat; \
59: else \
60: (m)->m_data = (m)->m_dat
61: #define NFSMADV(m, s) (m)->m_data += (s)
62: #define NFSMSIZ(m) ((M_HASCL(m)) ? (m)->m_ext.ext_size : \
63: (((m)->m_flags & M_PKTHDR) ? MHLEN : MLEN))
64:
65: /*
66: * Now for the macros that do the simple stuff and call the functions
67: * for the hard stuff.
68: * These macros use several vars. declared in nfsm_reqhead and these
69: * vars. must not be used elsewhere unless you are careful not to corrupt
70: * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
71: * that may be used so long as the value is not expected to retained
72: * after a macro.
73: * I know, this is kind of dorkey, but it makes the actual op functions
74: * fairly clean and deals with the mess caused by the xdr discriminating
75: * unions.
76: */
77:
78: #define nfsm_build(a,c,s) \
79: { if ((s) > M_TRAILINGSPACE(mb)) { \
80: MGET(mb2, M_WAIT, MT_DATA); \
81: if ((s) > MLEN) \
82: panic("build > MLEN"); \
83: mb->m_next = mb2; \
84: mb = mb2; \
85: mb->m_len = 0; \
86: bpos = mtod(mb, caddr_t); \
87: } \
88: (a) = (c)(bpos); \
89: mb->m_len += (s); \
90: bpos += (s); }
91:
92: #define nfsm_dissect(a, c, s) \
93: { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
94: if (t1 >= (s)) { \
95: (a) = (c)(dpos); \
96: dpos += (s); \
97: } else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \
98: error = t1; \
99: m_freem(mrep); \
100: goto nfsmout; \
101: } else { \
102: (a) = (c)cp2; \
103: } }
104:
105: #define nfsm_fhtom(v, v3) \
106: { if (v3) { \
107: t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \
108: if (t2 <= M_TRAILINGSPACE(mb)) { \
109: nfsm_build(tl, u_int32_t *, t2); \
110: *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \
111: *(tl + ((t2>>2) - 2)) = 0; \
112: bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
113: VTONFS(v)->n_fhsize); \
114: } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \
115: (caddr_t)VTONFS(v)->n_fhp, \
116: VTONFS(v)->n_fhsize)) != 0) { \
117: error = t2; \
118: m_freem(mreq); \
119: goto nfsmout; \
120: } \
121: } else { \
122: nfsm_build(cp, caddr_t, NFSX_V2FH); \
123: bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \
124: } }
125:
126: #define nfsm_srvfhtom(f, v3) \
127: { if (v3) { \
128: nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3FH); \
129: *tl++ = txdr_unsigned(NFSX_V3FH); \
130: bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
131: } else { \
132: nfsm_build(cp, caddr_t, NFSX_V2FH); \
133: bcopy((caddr_t)(f), cp, NFSX_V2FH); \
134: } }
135:
136: #define nfsm_srvpostop_fh(f) \
137: { nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
138: *tl++ = nfs_true; \
139: *tl++ = txdr_unsigned(NFSX_V3FH); \
140: bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
141: }
142:
143: #define nfsm_mtofh(d, v, v3, f) \
144: { struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \
145: if (v3) { \
146: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
147: (f) = fxdr_unsigned(int, *tl); \
148: } else \
149: (f) = 1; \
150: if (f) { \
151: nfsm_getfh(ttfhp, ttfhsize, (v3)); \
152: if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
153: &ttnp)) != 0) { \
154: error = t1; \
155: m_freem(mrep); \
156: goto nfsmout; \
157: } \
158: (v) = NFSTOV(ttnp); \
159: } \
160: if (v3) { \
161: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
162: if (f) \
163: (f) = fxdr_unsigned(int, *tl); \
164: else if (fxdr_unsigned(int, *tl)) \
165: nfsm_adv(NFSX_V3FATTR); \
166: } \
167: if (f) \
168: nfsm_loadattr((v), (struct vattr *)0); \
169: }
170:
171: #define nfsm_getfh(f, s, v3) \
172: { if (v3) { \
173: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
174: if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \
175: (s) > NFSX_V3FHMAX) { \
176: m_freem(mrep); \
177: error = EBADRPC; \
178: goto nfsmout; \
179: } \
180: } else \
181: (s) = NFSX_V2FH; \
182: nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); }
183:
184: #define nfsm_loadattr(v, a) \
185: { struct vnode *ttvp = (v); \
186: if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \
187: error = t1; \
188: m_freem(mrep); \
189: goto nfsmout; \
190: } \
191: (v) = ttvp; }
192:
193: #define nfsm_postop_attr(v, f) \
194: { struct vnode *ttvp = (v); \
195: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
196: if (((f) = fxdr_unsigned(int, *tl)) != 0) { \
197: if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
198: (struct vattr *)0)) != 0) { \
199: error = t1; \
200: (f) = 0; \
201: m_freem(mrep); \
202: goto nfsmout; \
203: } \
204: (v) = ttvp; \
205: } }
206:
207: /* Used as (f) for nfsm_wcc_data() */
208: #define NFSV3_WCCRATTR 0
209: #define NFSV3_WCCCHK 1
210:
211: #define nfsm_wcc_data(v, f) \
212: { int ttattrf, ttretf = 0; \
213: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
214: if (*tl == nfs_true) { \
215: nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); \
216: if (f) \
217: ttretf = (VTONFS(v)->n_mtime == \
218: fxdr_unsigned(u_int32_t, *(tl + 2))); \
219: } \
220: nfsm_postop_attr((v), ttattrf); \
221: if (f) { \
222: (f) = ttretf; \
223: } else { \
224: (f) = ttattrf; \
225: } }
226:
227: /* If full is true, set all fields, otherwise just set mode and time fields */
228: #define nfsm_v3attrbuild(a, full) \
229: { if ((a)->va_mode != (mode_t)VNOVAL) { \
230: nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
231: *tl++ = nfs_true; \
232: *tl = txdr_unsigned((a)->va_mode); \
233: } else { \
234: nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
235: *tl = nfs_false; \
236: } \
237: if ((full) && (a)->va_uid != (uid_t)VNOVAL) { \
238: nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
239: *tl++ = nfs_true; \
240: *tl = txdr_unsigned((a)->va_uid); \
241: } else { \
242: nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
243: *tl = nfs_false; \
244: } \
245: if ((full) && (a)->va_gid != (gid_t)VNOVAL) { \
246: nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
247: *tl++ = nfs_true; \
248: *tl = txdr_unsigned((a)->va_gid); \
249: } else { \
250: nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
251: *tl = nfs_false; \
252: } \
253: if ((full) && (a)->va_size != VNOVAL) { \
254: nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \
255: *tl++ = nfs_true; \
256: txdr_hyper((a)->va_size, tl); \
257: } else { \
258: nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
259: *tl = nfs_false; \
260: } \
261: if ((a)->va_atime.tv_sec != VNOVAL) { \
262: if ((a)->va_atime.tv_sec != time_second) { \
263: nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \
264: *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
265: txdr_nfsv3time(&(a)->va_atime, tl); \
266: } else { \
267: nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
268: *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \
269: } \
270: } else { \
271: nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
272: *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \
273: } \
274: if ((a)->va_mtime.tv_sec != VNOVAL) { \
275: if ((a)->va_mtime.tv_sec != time_second) { \
276: nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \
277: *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
278: txdr_nfsv3time(&(a)->va_mtime, tl); \
279: } else { \
280: nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
281: *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \
282: } \
283: } else { \
284: nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \
285: *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \
286: } \
287: }
288:
289:
290: #define nfsm_strsiz(s,m) \
291: { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
292: if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \
293: m_freem(mrep); \
294: error = EBADRPC; \
295: goto nfsmout; \
296: } }
297:
298: #define nfsm_srvstrsiz(s,m) \
299: { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
300: if (((s) = fxdr_unsigned(int32_t,*tl)) > (m) || (s) <= 0) { \
301: error = EBADRPC; \
302: nfsm_reply(0); \
303: } }
304:
305: #define nfsm_srvnamesiz(s) \
306: { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \
307: if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) \
308: error = NFSERR_NAMETOL; \
309: if ((s) <= 0) \
310: error = EBADRPC; \
311: if (error) \
312: nfsm_reply(0); \
313: }
314:
315: #define nfsm_mtouio(p,s) \
316: if ((s) > 0 && \
317: (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \
318: error = t1; \
319: m_freem(mrep); \
320: goto nfsmout; \
321: }
322:
323: #define nfsm_uiotom(p,s) \
324: if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \
325: error = t1; \
326: m_freem(mreq); \
327: goto nfsmout; \
328: }
329:
330: #define nfsm_reqhead(v,a,s) \
331: mb = mreq = nfsm_reqh((v),(a),(s),&bpos)
332:
333: #define nfsm_reqdone m_freem(mrep); \
334: nfsmout:
335:
336: #define nfsm_rndup(a) (((a)+3)&(~0x3))
337:
338: #define nfsm_request(v, t, p, c) \
339: if ((error = nfs_request((v), mreq, (t), (p), \
340: (c), &mrep, &md, &dpos)) != 0) { \
341: if (error & NFSERR_RETERR) \
342: error &= ~NFSERR_RETERR; \
343: else \
344: goto nfsmout; \
345: }
346:
347: #define nfsm_strtom(a,s,m) \
348: if ((s) > (m)) { \
349: m_freem(mreq); \
350: error = ENAMETOOLONG; \
351: goto nfsmout; \
352: } \
353: t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
354: if (t2 <= M_TRAILINGSPACE(mb)) { \
355: nfsm_build(tl,u_int32_t *,t2); \
356: *tl++ = txdr_unsigned(s); \
357: *(tl+((t2>>2)-2)) = 0; \
358: bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
359: } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \
360: error = t2; \
361: m_freem(mreq); \
362: goto nfsmout; \
363: }
364:
365: #define nfsm_srvdone \
366: nfsmout: \
367: return(error)
368:
369: #define nfsm_reply(s) \
370: { \
371: nfsd->nd_repstat = error; \
372: if (error && !(nfsd->nd_flag & ND_NFSV3)) \
373: (void) nfs_rephead(0, nfsd, slp, error, &frev, \
374: mrq, &mb, &bpos); \
375: else \
376: (void) nfs_rephead((s), nfsd, slp, error, &frev, \
377: mrq, &mb, &bpos); \
378: if (mrep != NULL) { \
379: m_freem(mrep); \
380: mrep = NULL; \
381: } \
382: mreq = *mrq; \
383: if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
384: error == EBADRPC)) \
385: return(0); \
386: }
387:
388: #define nfsm_writereply(s, v3) \
389: { \
390: nfsd->nd_repstat = error; \
391: if (error && !(v3)) \
392: (void) nfs_rephead(0, nfsd, slp, error, &frev, \
393: &mreq, &mb, &bpos); \
394: else \
395: (void) nfs_rephead((s), nfsd, slp, error, &frev, \
396: &mreq, &mb, &bpos); \
397: }
398:
399: #define nfsm_adv(s) \
400: { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
401: if (t1 >= (s)) { \
402: dpos += (s); \
403: } else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \
404: error = t1; \
405: m_freem(mrep); \
406: goto nfsmout; \
407: } }
408:
409: #define nfsm_srvmtofh(f) \
410: { if (nfsd->nd_flag & ND_NFSV3) { \
411: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
412: if (fxdr_unsigned(int, *tl) != NFSX_V3FH) { \
413: error = EBADRPC; \
414: nfsm_reply(0); \
415: } \
416: } \
417: nfsm_dissect(tl, u_int32_t *, NFSX_V3FH); \
418: bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
419: if ((nfsd->nd_flag & ND_NFSV3) == 0) \
420: nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
421: }
422:
423: #define nfsm_clget \
424: if (bp >= be) { \
425: if (mp == mb) \
426: mp->m_len += bp-bpos; \
427: MGET(mp, M_WAIT, MT_DATA); \
428: MCLGET(mp, M_WAIT); \
429: mp->m_len = NFSMSIZ(mp); \
430: mp2->m_next = mp; \
431: mp2 = mp; \
432: bp = mtod(mp, caddr_t); \
433: be = bp+mp->m_len; \
434: } \
435: tl = (u_int32_t *)bp
436:
437: #define nfsm_srvfillattr(a, f) \
438: nfsm_srvfattr(nfsd, (a), (f))
439:
440: #define nfsm_srvwcc_data(br, b, ar, a) \
441: nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos)
442:
443: #define nfsm_srvpostop_attr(r, a) \
444: nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos)
445:
446: #define nfsm_srvsattr(a) \
447: { nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
448: if (*tl == nfs_true) { \
449: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
450: (a)->va_mode = nfstov_mode(*tl); \
451: } \
452: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
453: if (*tl == nfs_true) { \
454: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
455: (a)->va_uid = fxdr_unsigned(uid_t, *tl); \
456: } \
457: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
458: if (*tl == nfs_true) { \
459: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
460: (a)->va_gid = fxdr_unsigned(gid_t, *tl); \
461: } \
462: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
463: if (*tl == nfs_true) { \
464: nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
465: (a)->va_size = fxdr_hyper(tl); \
466: } \
467: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
468: switch (fxdr_unsigned(int, *tl)) { \
469: case NFSV3SATTRTIME_TOCLIENT: \
470: (a)->va_vaflags &= ~VA_UTIMES_NULL; \
471: nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
472: fxdr_nfsv3time(tl, &(a)->va_atime); \
473: break; \
474: case NFSV3SATTRTIME_TOSERVER: \
475: getnanotime(&(a)->va_atime); \
476: break; \
477: }; \
478: nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
479: switch (fxdr_unsigned(int, *tl)) { \
480: case NFSV3SATTRTIME_TOCLIENT: \
481: (a)->va_vaflags &= ~VA_UTIMES_NULL; \
482: nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \
483: fxdr_nfsv3time(tl, &(a)->va_mtime); \
484: break; \
485: case NFSV3SATTRTIME_TOSERVER: \
486: getnanotime(&(a)->va_mtime); \
487: break; \
488: }; }
489:
490: #endif
CVSweb