1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #ifndef _NFS_NFSM_SUBS_H_
40 #define _NFS_NFSM_SUBS_H_
41
42
43
44
45
46
47
48
49
50
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
67
68
69
70
71
72
73
74
75
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
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
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