upgraded to the latest NetBSD version
[unix-history] / usr / src / sys / nfs / nfsm_subs.h
CommitLineData
a2907882 1/*
f013d4c5
KB
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
a2907882
KM
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
7 *
dbf0c423 8 * %sccs.include.redist.c%
a2907882 9 *
4acac3d6 10 * @(#)nfsm_subs.h 8.2 (Berkeley) %G%
a2907882
KM
11 */
12
4acac3d6
KM
13
14#ifndef _NFS_NFSM_SUBS_H_
15#define _NFS_NFSM_SUBS_H_
16
17
a2907882
KM
18/*
19 * These macros do strange and peculiar things to mbuf chains for
20 * the assistance of the nfs code. To attempt to use them for any
21 * other purpose will be dangerous. (they make weird assumptions)
22 */
23
24/*
25 * First define what the actual subs. return
26 */
0bd503ad 27extern struct mbuf *nfsm_reqh();
a2907882 28
a2907882 29#define M_HASCL(m) ((m)->m_flags & M_EXT)
a2907882
KM
30#define NFSMINOFF(m) \
31 if (M_HASCL(m)) \
32 (m)->m_data = (m)->m_ext.ext_buf; \
2c5b44a2
KM
33 else if ((m)->m_flags & M_PKTHDR) \
34 (m)->m_data = (m)->m_pktdat; \
a2907882
KM
35 else \
36 (m)->m_data = (m)->m_dat
37#define NFSMADV(m, s) (m)->m_data += (s)
36c3043b 38#define NFSMSIZ(m) ((M_HASCL(m))?MCLBYTES: \
a2907882 39 (((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
a2907882
KM
40
41/*
42 * Now for the macros that do the simple stuff and call the functions
43 * for the hard stuff.
44 * These macros use several vars. declared in nfsm_reqhead and these
45 * vars. must not be used elsewhere unless you are careful not to corrupt
46 * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
47 * that may be used so long as the value is not expected to retained
48 * after a macro.
49 * I know, this is kind of dorkey, but it makes the actual op functions
50 * fairly clean and deals with the mess caused by the xdr discriminating
51 * unions.
52 */
53
54#define nfsm_build(a,c,s) \
2c5b44a2 55 { if ((s) > M_TRAILINGSPACE(mb)) { \
a2907882
KM
56 MGET(mb2, M_WAIT, MT_DATA); \
57 if ((s) > MLEN) \
58 panic("build > MLEN"); \
59 mb->m_next = mb2; \
60 mb = mb2; \
61 mb->m_len = 0; \
62 bpos = mtod(mb, caddr_t); \
63 } \
64 (a) = (c)(bpos); \
65 mb->m_len += (s); \
2c5b44a2 66 bpos += (s); }
a2907882 67
4acac3d6 68#define nfsm_dissect(a, c, s) \
2c5b44a2 69 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
a2907882
KM
70 if (t1 >= (s)) { \
71 (a) = (c)(dpos); \
72 dpos += (s); \
4acac3d6
KM
73 } else if (t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) { \
74 error = t1; \
a2907882
KM
75 m_freem(mrep); \
76 goto nfsmout; \
77 } else { \
78 (a) = (c)cp2; \
2c5b44a2 79 } }
a2907882 80
4acac3d6
KM
81#define nfsm_fhtom(v, v3) \
82 { if (v3) { \
83 t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \
84 if (t2 <= M_TRAILINGSPACE(mb)) { \
85 nfsm_build(tl, u_long *, t2); \
86 *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \
87 *(tl + ((t2>>2) - 2)) = 0; \
88 bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
89 VTONFS(v)->n_fhsize); \
90 } else if (t2 = nfsm_strtmbuf(&mb, &bpos, \
91 (caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize)) { \
92 error = t2; \
93 m_freem(mreq); \
94 goto nfsmout; \
95 } \
96 } else { \
97 nfsm_build(cp, caddr_t, NFSX_V2FH); \
98 bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \
99 } }
a2907882 100
4acac3d6
KM
101#define nfsm_srvfhtom(f, v3) \
102 { if (v3) { \
103 nfsm_build(tl, u_long *, NFSX_UNSIGNED + NFSX_V3FH); \
104 *tl++ = txdr_unsigned(NFSX_V3FH); \
105 bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
106 } else { \
107 nfsm_build(cp, caddr_t, NFSX_V2FH); \
108 bcopy((caddr_t)(f), cp, NFSX_V2FH); \
109 } }
a2907882 110
4acac3d6
KM
111#define nfsm_srvpostop_fh(f) \
112 { nfsm_build(tl, u_long *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
113 *tl++ = nfs_true; \
114 *tl++ = txdr_unsigned(NFSX_V3FH); \
115 bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
116 }
117
118#define nfsm_mtofh(d, v, v3, f) \
119 { struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \
120 if (v3) { \
121 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
122 (f) = fxdr_unsigned(int, *tl); \
123 } else \
124 (f) = 1; \
125 if (f) { \
126 nfsm_getfh(ttfhp, ttfhsize, (v3)); \
127 if (t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
128 &ttnp)) { \
129 error = t1; \
130 m_freem(mrep); \
131 goto nfsmout; \
132 } \
133 (v) = NFSTOV(ttnp); \
134 } \
135 if (v3) { \
136 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
137 if (f) \
138 (f) = fxdr_unsigned(int, *tl); \
139 else if (fxdr_unsigned(int, *tl)) \
140 nfsm_adv(NFSX_V3FATTR); \
a2907882 141 } \
4acac3d6
KM
142 if (f) \
143 nfsm_loadattr((v), (struct vattr *)0); \
a2907882
KM
144 }
145
4acac3d6
KM
146#define nfsm_getfh(f, s, v3) \
147 { if (v3) { \
148 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
149 if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \
150 (s) > NFSX_V3FHMAX) { \
151 m_freem(mrep); \
152 error = EBADRPC; \
153 goto nfsmout; \
154 } \
155 } else \
156 (s) = NFSX_V2FH; \
157 nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); }
158
159#define nfsm_loadattr(v, a) \
160 { struct vnode *ttvp = (v); \
161 if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) { \
162 error = t1; \
a2907882
KM
163 m_freem(mrep); \
164 goto nfsmout; \
0bd503ad 165 } \
4acac3d6
KM
166 (v) = ttvp; }
167
168#define nfsm_postop_attr(v, f) \
169 { struct vnode *ttvp = (v); \
170 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
171 if ((f) = fxdr_unsigned(int, *tl)) { \
172 if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
173 (struct vattr *)0)) { \
174 error = t1; \
175 (f) = 0; \
176 m_freem(mrep); \
177 goto nfsmout; \
178 } \
179 (v) = ttvp; \
180 } }
181
182/* Used as (f) for nfsm_wcc_data() */
183#define NFSV3_WCCRATTR 0
184#define NFSV3_WCCCHK 1
185
186#define nfsm_wcc_data(v, f) \
187 { int ttattrf, ttretf = 0; \
188 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
189 if (*tl == nfs_true) { \
190 nfsm_dissect(tl, u_long *, 6 * NFSX_UNSIGNED); \
191 if (f) \
192 ttretf = (VTONFS(v)->n_mtime == \
193 fxdr_unsigned(u_long, *(tl + 2))); \
194 } \
195 nfsm_postop_attr((v), ttattrf); \
196 if (f) { \
197 (f) = ttretf; \
198 } else { \
199 (f) = ttattrf; \
200 } }
201
202#define nfsm_v3sattr(s, a, u, g) \
203 { (s)->sa_modetrue = nfs_true; \
204 (s)->sa_mode = vtonfsv3_mode((a)->va_mode); \
205 (s)->sa_uidtrue = nfs_true; \
206 (s)->sa_uid = txdr_unsigned(u); \
207 (s)->sa_gidtrue = nfs_true; \
208 (s)->sa_gid = txdr_unsigned(g); \
209 (s)->sa_sizefalse = nfs_false; \
210 (s)->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
211 txdr_nfsv3time(&(a)->va_atime, &(s)->sa_atime); \
212 (s)->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \
213 txdr_nfsv3time(&(a)->va_mtime, &(s)->sa_mtime); \
214 }
a2907882
KM
215
216#define nfsm_strsiz(s,m) \
2c5b44a2 217 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
9fb16cce 218 if (((s) = fxdr_unsigned(long,*tl)) > (m)) { \
a2907882
KM
219 m_freem(mrep); \
220 error = EBADRPC; \
221 goto nfsmout; \
2c5b44a2 222 } }
a2907882
KM
223
224#define nfsm_srvstrsiz(s,m) \
2c5b44a2 225 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
9fb16cce 226 if (((s) = fxdr_unsigned(long,*tl)) > (m) || (s) <= 0) { \
a2907882
KM
227 error = EBADRPC; \
228 nfsm_reply(0); \
2c5b44a2 229 } }
a2907882 230
4acac3d6
KM
231#define nfsm_srvnamesiz(s) \
232 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
233 if (((s) = fxdr_unsigned(long,*tl)) > NFS_MAXNAMLEN) \
234 error = NFSERR_NAMETOL; \
235 if ((s) <= 0) \
236 error = EBADRPC; \
237 if (error) \
238 nfsm_reply(0); \
239 }
240
a2907882
KM
241#define nfsm_mtouio(p,s) \
242 if ((s) > 0 && \
4acac3d6
KM
243 (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
244 error = t1; \
a2907882
KM
245 m_freem(mrep); \
246 goto nfsmout; \
247 }
248
249#define nfsm_uiotom(p,s) \
4acac3d6
KM
250 if (t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \
251 error = t1; \
a2907882
KM
252 m_freem(mreq); \
253 goto nfsmout; \
254 }
255
2c5b44a2
KM
256#define nfsm_reqhead(v,a,s) \
257 mb = mreq = nfsm_reqh((v),(a),(s),&bpos)
a2907882 258
a2907882
KM
259#define nfsm_reqdone m_freem(mrep); \
260 nfsmout:
261
262#define nfsm_rndup(a) (((a)+3)&(~0x3))
263
2c5b44a2
KM
264#define nfsm_request(v, t, p, c) \
265 if (error = nfs_request((v), mreq, (t), (p), \
4acac3d6
KM
266 (c), &mrep, &md, &dpos)) { \
267 if (error & NFSERR_RETERR) \
268 error &= ~NFSERR_RETERR; \
269 else \
270 goto nfsmout; \
271 }
a2907882
KM
272
273#define nfsm_strtom(a,s,m) \
274 if ((s) > (m)) { \
275 m_freem(mreq); \
276 error = ENAMETOOLONG; \
277 goto nfsmout; \
278 } \
279 t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
2c5b44a2 280 if (t2 <= M_TRAILINGSPACE(mb)) { \
9fb16cce
KM
281 nfsm_build(tl,u_long *,t2); \
282 *tl++ = txdr_unsigned(s); \
283 *(tl+((t2>>2)-2)) = 0; \
284 bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
4acac3d6
KM
285 } else if (t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \
286 error = t2; \
a2907882
KM
287 m_freem(mreq); \
288 goto nfsmout; \
289 }
290
a2907882
KM
291#define nfsm_srvdone \
292 nfsmout: \
293 return(error)
294
295#define nfsm_reply(s) \
296 { \
2c5b44a2 297 nfsd->nd_repstat = error; \
4acac3d6
KM
298 if (error && !(nfsd->nd_flag & ND_NFSV3)) \
299 (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
2c5b44a2 300 mrq, &mb, &bpos); \
a2907882 301 else \
4acac3d6 302 (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
2c5b44a2 303 mrq, &mb, &bpos); \
a2907882 304 m_freem(mrep); \
66435314 305 mreq = *mrq; \
4acac3d6
KM
306 if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
307 error == EBADRPC)) \
a2907882
KM
308 return(0); \
309 }
310
4acac3d6
KM
311#define nfsm_writereply(s, v3) \
312 { \
313 nfsd->nd_repstat = error; \
314 if (error && !(v3)) \
315 (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
316 &mreq, &mb, &bpos); \
317 else \
318 (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
319 &mreq, &mb, &bpos); \
320 }
321
a2907882 322#define nfsm_adv(s) \
4acac3d6 323 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
a2907882
KM
324 if (t1 >= (s)) { \
325 dpos += (s); \
4acac3d6
KM
326 } else if (t1 = nfs_adv(&md, &dpos, (s), t1)) { \
327 error = t1; \
a2907882
KM
328 m_freem(mrep); \
329 goto nfsmout; \
4acac3d6 330 } }
a2907882
KM
331
332#define nfsm_srvmtofh(f) \
4acac3d6
KM
333 { if (nfsd->nd_flag & ND_NFSV3) { \
334 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
335 if (fxdr_unsigned(int, *tl) != NFSX_V3FH) { \
336 error = EBADRPC; \
337 nfsm_reply(0); \
338 } \
339 } \
340 nfsm_dissect(tl, u_long *, NFSX_V3FH); \
341 bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
342 if ((nfsd->nd_flag & ND_NFSV3) == 0) \
343 nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
344 }
a2907882
KM
345
346#define nfsm_clget \
347 if (bp >= be) { \
2c5b44a2
KM
348 if (mp == mb) \
349 mp->m_len += bp-bpos; \
a2907882 350 MGET(mp, M_WAIT, MT_DATA); \
f0f1cbaa 351 MCLGET(mp, M_WAIT); \
a2907882 352 mp->m_len = NFSMSIZ(mp); \
2c5b44a2
KM
353 mp2->m_next = mp; \
354 mp2 = mp; \
a2907882
KM
355 bp = mtod(mp, caddr_t); \
356 be = bp+mp->m_len; \
357 } \
9fb16cce 358 tl = (u_long *)bp
a2907882 359
4acac3d6
KM
360#define nfsm_srvfillattr(a, f) \
361 nfsm_srvfattr(nfsd, (a), (f))
362
363#define nfsm_srvwcc_data(br, b, ar, a) \
364 nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos)
365
366#define nfsm_srvpostop_attr(r, a) \
367 nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos)
368
369#define nfsm_srvsattr(a) \
370 { nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
371 if (*tl == nfs_true) { \
372 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
373 (a)->va_mode = nfstov_mode(*tl); \
374 } \
375 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
376 if (*tl == nfs_true) { \
377 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
378 (a)->va_uid = fxdr_unsigned(uid_t, *tl); \
379 } \
380 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
381 if (*tl == nfs_true) { \
382 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
383 (a)->va_gid = fxdr_unsigned(gid_t, *tl); \
384 } \
385 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
386 if (*tl == nfs_true) { \
387 nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
388 fxdr_hyper(tl, &(a)->va_size); \
389 } \
390 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
391 switch (fxdr_unsigned(int, *tl)) { \
392 case NFSV3SATTRTIME_TOCLIENT: \
393 nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
394 fxdr_nfsv3time(tl, &(a)->va_atime); \
395 break; \
396 case NFSV3SATTRTIME_TOSERVER: \
397 (a)->va_atime.ts_sec = time.tv_sec; \
398 (a)->va_atime.ts_nsec = time.tv_usec * 1000; \
399 break; \
400 }; \
401 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
402 switch (fxdr_unsigned(int, *tl)) { \
403 case NFSV3SATTRTIME_TOCLIENT: \
404 nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
405 fxdr_nfsv3time(tl, &(a)->va_mtime); \
406 break; \
407 case NFSV3SATTRTIME_TOSERVER: \
408 (a)->va_mtime.ts_sec = time.tv_sec; \
409 (a)->va_mtime.ts_nsec = time.tv_usec * 1000; \
410 break; \
411 }; }
66435314 412
4acac3d6 413#endif