nfs_common.h revision 49405
1190214Srpaulo/* 2190214Srpaulo * Copyright (c) 1989, 1993 3190214Srpaulo * The Regents of the University of California. All rights reserved. 4190214Srpaulo * 5190214Srpaulo * This code is derived from software contributed to Berkeley by 6190214Srpaulo * Rick Macklem at The University of Guelph. 7190214Srpaulo * 8190214Srpaulo * Redistribution and use in source and binary forms, with or without 9190214Srpaulo * modification, are permitted provided that the following conditions 10190214Srpaulo * are met: 11190214Srpaulo * 1. Redistributions of source code must retain the above copyright 12190214Srpaulo * notice, this list of conditions and the following disclaimer. 13190214Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 14190214Srpaulo * notice, this list of conditions and the following disclaimer in the 15214518Srpaulo * documentation and/or other materials provided with the distribution. 16190214Srpaulo * 3. All advertising materials mentioning features or use of this software 17190214Srpaulo * must display the following acknowledgement: 18190214Srpaulo * This product includes software developed by the University of 19190214Srpaulo * California, Berkeley and its contributors. 20190214Srpaulo * 4. Neither the name of the University nor the names of its contributors 21190214Srpaulo * may be used to endorse or promote products derived from this software 22214518Srpaulo * without specific prior written permission. 23214518Srpaulo * 24214518Srpaulo * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25214518Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26190214Srpaulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27190214Srpaulo * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28190214Srpaulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29190214Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30190214Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31190214Srpaulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32190214Srpaulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33190214Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34190214Srpaulo * SUCH DAMAGE. 35190214Srpaulo * 36190214Srpaulo * @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95 37190214Srpaulo * $Id: nfsm_subs.h,v 1.24 1999/06/23 04:44:14 julian Exp $ 38190214Srpaulo */ 39190214Srpaulo 40190214Srpaulo 41190214Srpaulo#ifndef _NFS_NFSM_SUBS_H_ 42190214Srpaulo#define _NFS_NFSM_SUBS_H_ 43190214Srpaulo 44190214Srpaulostruct ucred; 45190214Srpaulostruct vnode; 46190214Srpaulo 47190214Srpaulo/* 48214518Srpaulo * These macros do strange and peculiar things to mbuf chains for 49190214Srpaulo * the assistance of the nfs code. To attempt to use them for any 50190214Srpaulo * other purpose will be dangerous. (they make weird assumptions) 51190214Srpaulo */ 52190214Srpaulo 53190214Srpaulo/* 54190214Srpaulo * First define what the actual subs. return 55190214Srpaulo */ 56190214Srpaulostruct mbuf *nfsm_reqh __P((struct vnode *vp, u_long procid, int hsiz, 57190214Srpaulo caddr_t *bposp)); 58190214Srpaulostruct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, 59190214Srpaulo int auth_type, int auth_len, char *auth_str, 60190214Srpaulo int verf_len, char *verf_str, 61190214Srpaulo struct mbuf *mrest, int mrest_len, 62190214Srpaulo struct mbuf **mbp, u_int32_t *xidp)); 63190214Srpaulo 64190214Srpaulo#define M_HASCL(m) ((m)->m_flags & M_EXT) 65190214Srpaulo#define NFSMINOFF(m) \ 66190214Srpaulo if (M_HASCL(m)) \ 67190214Srpaulo (m)->m_data = (m)->m_ext.ext_buf; \ 68190214Srpaulo else if ((m)->m_flags & M_PKTHDR) \ 69190214Srpaulo (m)->m_data = (m)->m_pktdat; \ 70190214Srpaulo else \ 71190214Srpaulo (m)->m_data = (m)->m_dat 72214518Srpaulo#define NFSMADV(m, s) (m)->m_data += (s) 73190214Srpaulo#define NFSMSIZ(m) ((M_HASCL(m))?MCLBYTES: \ 74214518Srpaulo (((m)->m_flags & M_PKTHDR)?MHLEN:MLEN)) 75190214Srpaulo 76190214Srpaulo/* 77190214Srpaulo * Now for the macros that do the simple stuff and call the functions 78190214Srpaulo * for the hard stuff. 79190214Srpaulo * These macros use several vars. declared in nfsm_reqhead and these 80190214Srpaulo * vars. must not be used elsewhere unless you are careful not to corrupt 81190214Srpaulo * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries 82190214Srpaulo * that may be used so long as the value is not expected to retained 83190214Srpaulo * after a macro. 84190214Srpaulo * I know, this is kind of dorkey, but it makes the actual op functions 85190214Srpaulo * fairly clean and deals with the mess caused by the xdr discriminating 86190214Srpaulo * unions. 87190214Srpaulo */ 88190214Srpaulo 89190214Srpaulo#define nfsm_build(a,c,s) \ 90190214Srpaulo { if ((s) > M_TRAILINGSPACE(mb)) { \ 91190214Srpaulo MGET(mb2, M_WAIT, MT_DATA); \ 92190214Srpaulo if ((s) > MLEN) \ 93190214Srpaulo panic("build > MLEN"); \ 94190214Srpaulo mb->m_next = mb2; \ 95190214Srpaulo mb = mb2; \ 96190214Srpaulo mb->m_len = 0; \ 97190214Srpaulo bpos = mtod(mb, caddr_t); \ 98190214Srpaulo } \ 99190214Srpaulo (a) = (c)(bpos); \ 100190214Srpaulo mb->m_len += (s); \ 101190214Srpaulo bpos += (s); } 102190214Srpaulo 103190214Srpaulo#define nfsm_dissect(a, c, s) \ 104190214Srpaulo { t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 105190214Srpaulo if (t1 >= (s)) { \ 106190214Srpaulo (a) = (c)(dpos); \ 107190214Srpaulo dpos += (s); \ 108190214Srpaulo } else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \ 109190214Srpaulo error = t1; \ 110190214Srpaulo m_freem(mrep); \ 111190214Srpaulo goto nfsmout; \ 112190214Srpaulo } else { \ 113190214Srpaulo (a) = (c)cp2; \ 114190214Srpaulo } } 115190214Srpaulo 116190214Srpaulo#define nfsm_fhtom(v, v3) \ 117190214Srpaulo { if (v3) { \ 118190214Srpaulo t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \ 119190214Srpaulo if (t2 <= M_TRAILINGSPACE(mb)) { \ 120190214Srpaulo nfsm_build(tl, u_int32_t *, t2); \ 121190214Srpaulo *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \ 122190214Srpaulo *(tl + ((t2>>2) - 2)) = 0; \ 123190214Srpaulo bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \ 124190214Srpaulo VTONFS(v)->n_fhsize); \ 125190214Srpaulo } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \ 126190214Srpaulo (caddr_t)VTONFS(v)->n_fhp, \ 127190214Srpaulo VTONFS(v)->n_fhsize)) != 0) { \ 128190214Srpaulo error = t2; \ 129190214Srpaulo m_freem(mreq); \ 130190214Srpaulo goto nfsmout; \ 131190214Srpaulo } \ 132190214Srpaulo } else { \ 133190214Srpaulo nfsm_build(cp, caddr_t, NFSX_V2FH); \ 134190214Srpaulo bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \ 135190214Srpaulo } } 136190214Srpaulo 137190214Srpaulo#define nfsm_srvfhtom(f, v3) \ 138190214Srpaulo { if (v3) { \ 139190214Srpaulo nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3FH); \ 140190214Srpaulo *tl++ = txdr_unsigned(NFSX_V3FH); \ 141190214Srpaulo bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \ 142190214Srpaulo } else { \ 143190214Srpaulo nfsm_build(cp, caddr_t, NFSX_V2FH); \ 144190214Srpaulo bcopy((caddr_t)(f), cp, NFSX_V2FH); \ 145190214Srpaulo } } 146190214Srpaulo 147190214Srpaulo#define nfsm_srvpostop_fh(f) \ 148190214Srpaulo { nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \ 149190214Srpaulo *tl++ = nfs_true; \ 150190214Srpaulo *tl++ = txdr_unsigned(NFSX_V3FH); \ 151190214Srpaulo bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \ 152190214Srpaulo } 153190214Srpaulo 154190214Srpaulo#define nfsm_mtofh(d, v, v3, f) \ 155190214Srpaulo { struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \ 156190214Srpaulo if (v3) { \ 157190214Srpaulo nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 158190214Srpaulo (f) = fxdr_unsigned(int, *tl); \ 159190214Srpaulo } else \ 160190214Srpaulo (f) = 1; \ 161190214Srpaulo if (f) { \ 162190214Srpaulo nfsm_getfh(ttfhp, ttfhsize, (v3)); \ 163190214Srpaulo if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \ 164190214Srpaulo &ttnp)) != 0) { \ 165190214Srpaulo error = t1; \ 166190214Srpaulo m_freem(mrep); \ 167190214Srpaulo goto nfsmout; \ 168190214Srpaulo } \ 169190214Srpaulo (v) = NFSTOV(ttnp); \ 170190214Srpaulo } \ 171190214Srpaulo if (v3) { \ 172190214Srpaulo nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 173190214Srpaulo if (f) \ 174190214Srpaulo (f) = fxdr_unsigned(int, *tl); \ 175190214Srpaulo else if (fxdr_unsigned(int, *tl)) \ 176190214Srpaulo nfsm_adv(NFSX_V3FATTR); \ 177190214Srpaulo } \ 178190214Srpaulo if (f) \ 179190214Srpaulo nfsm_loadattr((v), (struct vattr *)0); \ 180190214Srpaulo } 181190214Srpaulo 182190214Srpaulo#define nfsm_getfh(f, s, v3) \ 183190214Srpaulo { if (v3) { \ 184190214Srpaulo nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 185190214Srpaulo if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \ 186190214Srpaulo (s) > NFSX_V3FHMAX) { \ 187190214Srpaulo m_freem(mrep); \ 188190214Srpaulo error = EBADRPC; \ 189190214Srpaulo goto nfsmout; \ 190190214Srpaulo } \ 191190214Srpaulo } else \ 192190214Srpaulo (s) = NFSX_V2FH; \ 193190214Srpaulo nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); } 194190214Srpaulo 195190214Srpaulo#define nfsm_loadattr(v, a) \ 196190214Srpaulo { struct vnode *ttvp = (v); \ 197190214Srpaulo if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \ 198190214Srpaulo error = t1; \ 199190214Srpaulo m_freem(mrep); \ 200190214Srpaulo goto nfsmout; \ 201190214Srpaulo } \ 202190214Srpaulo (v) = ttvp; } 203190214Srpaulo 204190214Srpaulo#define nfsm_postop_attr(v, f) \ 205190214Srpaulo { struct vnode *ttvp = (v); \ 206190214Srpaulo nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 207190214Srpaulo if (((f) = fxdr_unsigned(int, *tl)) != 0) { \ 208190214Srpaulo if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \ 209190214Srpaulo (struct vattr *)0)) != 0) { \ 210190214Srpaulo error = t1; \ 211190214Srpaulo (f) = 0; \ 212190214Srpaulo m_freem(mrep); \ 213190214Srpaulo goto nfsmout; \ 214190214Srpaulo } \ 215190214Srpaulo (v) = ttvp; \ 216190214Srpaulo } } 217190214Srpaulo 218190214Srpaulo/* Used as (f) for nfsm_wcc_data() */ 219190214Srpaulo#define NFSV3_WCCRATTR 0 220190214Srpaulo#define NFSV3_WCCCHK 1 221190214Srpaulo 222190214Srpaulo#define nfsm_wcc_data(v, f) \ 223190214Srpaulo { int ttattrf, ttretf = 0; \ 224190214Srpaulo nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 225190214Srpaulo if (*tl == nfs_true) { \ 226190214Srpaulo nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); \ 227190214Srpaulo if (f) \ 228190214Srpaulo ttretf = (VTONFS(v)->n_mtime == \ 229190214Srpaulo fxdr_unsigned(u_int32_t, *(tl + 2))); \ 230190214Srpaulo } \ 231190214Srpaulo nfsm_postop_attr((v), ttattrf); \ 232190214Srpaulo if (f) { \ 233190214Srpaulo (f) = ttretf; \ 234190214Srpaulo } else { \ 235190214Srpaulo (f) = ttattrf; \ 236190214Srpaulo } } 237190214Srpaulo 238190214Srpaulo/* If full is true, set all fields, otherwise just set mode and time fields */ 239190214Srpaulo#define nfsm_v3attrbuild(a, full) \ 240190214Srpaulo { if ((a)->va_mode != (mode_t)VNOVAL) { \ 241190214Srpaulo nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ 242190214Srpaulo *tl++ = nfs_true; \ 243190214Srpaulo *tl = txdr_unsigned((a)->va_mode); \ 244190214Srpaulo } else { \ 245190214Srpaulo nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ 246190214Srpaulo *tl = nfs_false; \ 247190214Srpaulo } \ 248190214Srpaulo if ((full) && (a)->va_uid != (uid_t)VNOVAL) { \ 249190214Srpaulo nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ 250190214Srpaulo *tl++ = nfs_true; \ 251190214Srpaulo *tl = txdr_unsigned((a)->va_uid); \ 252190214Srpaulo } else { \ 253190214Srpaulo nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ 254190214Srpaulo *tl = nfs_false; \ 255190214Srpaulo } \ 256190214Srpaulo if ((full) && (a)->va_gid != (gid_t)VNOVAL) { \ 257190214Srpaulo nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ 258190214Srpaulo *tl++ = nfs_true; \ 259190214Srpaulo *tl = txdr_unsigned((a)->va_gid); \ 260190214Srpaulo } else { \ 261190214Srpaulo nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ 262190214Srpaulo *tl = nfs_false; \ 263190214Srpaulo } \ 264190214Srpaulo if ((full) && (a)->va_size != VNOVAL) { \ 265190214Srpaulo nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ 266190214Srpaulo *tl++ = nfs_true; \ 267190214Srpaulo txdr_hyper((a)->va_size, tl); \ 268190214Srpaulo } else { \ 269190214Srpaulo nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ 270190214Srpaulo *tl = nfs_false; \ 271190214Srpaulo } \ 272190214Srpaulo if ((a)->va_atime.tv_sec != VNOVAL) { \ 273190214Srpaulo if ((a)->va_atime.tv_sec != time_second) { \ 274190214Srpaulo nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ 275190214Srpaulo *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \ 276190214Srpaulo txdr_nfsv3time(&(a)->va_atime, tl); \ 277190214Srpaulo } else { \ 278190214Srpaulo nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ 279190214Srpaulo *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \ 280190214Srpaulo } \ 281190214Srpaulo } else { \ 282190214Srpaulo nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ 283190214Srpaulo *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \ 284190214Srpaulo } \ 285190214Srpaulo if ((a)->va_mtime.tv_sec != VNOVAL) { \ 286190214Srpaulo if ((a)->va_mtime.tv_sec != time_second) { \ 287190214Srpaulo nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ 288190214Srpaulo *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \ 289190214Srpaulo txdr_nfsv3time(&(a)->va_mtime, tl); \ 290190214Srpaulo } else { \ 291190214Srpaulo nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ 292190214Srpaulo *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \ 293190214Srpaulo } \ 294190214Srpaulo } else { \ 295190214Srpaulo nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ 296190214Srpaulo *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \ 297190214Srpaulo } \ 298190214Srpaulo } 299190214Srpaulo 300190214Srpaulo 301190214Srpaulo#define nfsm_strsiz(s,m) \ 302190214Srpaulo { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ 303190214Srpaulo if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \ 304190214Srpaulo m_freem(mrep); \ 305190214Srpaulo error = EBADRPC; \ 306190214Srpaulo goto nfsmout; \ 307190214Srpaulo } } 308190214Srpaulo 309190214Srpaulo#define nfsm_srvstrsiz(s,m) \ 310190214Srpaulo { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ 311190214Srpaulo if (((s) = fxdr_unsigned(int32_t,*tl)) > (m) || (s) <= 0) { \ 312190214Srpaulo error = EBADRPC; \ 313190214Srpaulo nfsm_reply(0); \ 314190214Srpaulo } } 315190214Srpaulo 316190214Srpaulo#define nfsm_srvnamesiz(s) \ 317190214Srpaulo { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ 318190214Srpaulo if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) \ 319190214Srpaulo error = NFSERR_NAMETOL; \ 320190214Srpaulo if ((s) <= 0) \ 321190214Srpaulo error = EBADRPC; \ 322190214Srpaulo if (error) \ 323190214Srpaulo nfsm_reply(0); \ 324190214Srpaulo } 325190214Srpaulo 326190214Srpaulo#define nfsm_mtouio(p,s) \ 327190214Srpaulo if ((s) > 0 && \ 328190214Srpaulo (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \ 329190214Srpaulo error = t1; \ 330190214Srpaulo m_freem(mrep); \ 331190214Srpaulo goto nfsmout; \ 332190214Srpaulo } 333190214Srpaulo 334190214Srpaulo#define nfsm_uiotom(p,s) \ 335190214Srpaulo if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \ 336190214Srpaulo error = t1; \ 337190214Srpaulo m_freem(mreq); \ 338190214Srpaulo goto nfsmout; \ 339190214Srpaulo } 340190214Srpaulo 341190214Srpaulo#define nfsm_reqhead(v,a,s) \ 342190214Srpaulo mb = mreq = nfsm_reqh((v),(a),(s),&bpos) 343190214Srpaulo 344190214Srpaulo#define nfsm_reqdone m_freem(mrep); \ 345190214Srpaulo nfsmout: 346190214Srpaulo 347190214Srpaulo#define nfsm_rndup(a) (((a)+3)&(~0x3)) 348190214Srpaulo 349214518Srpaulo#define nfsm_request(v, t, p, c) \ 350190214Srpaulo if ((error = nfs_request((v), mreq, (t), (p), \ 351190214Srpaulo (c), &mrep, &md, &dpos)) != 0) { \ 352190214Srpaulo if (error & NFSERR_RETERR) \ 353190214Srpaulo error &= ~NFSERR_RETERR; \ 354190214Srpaulo else \ 355190214Srpaulo goto nfsmout; \ 356190214Srpaulo } 357190214Srpaulo 358214518Srpaulo#define nfsm_strtom(a,s,m) \ 359 if ((s) > (m)) { \ 360 m_freem(mreq); \ 361 error = ENAMETOOLONG; \ 362 goto nfsmout; \ 363 } \ 364 t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \ 365 if (t2 <= M_TRAILINGSPACE(mb)) { \ 366 nfsm_build(tl,u_int32_t *,t2); \ 367 *tl++ = txdr_unsigned(s); \ 368 *(tl+((t2>>2)-2)) = 0; \ 369 bcopy((const char *)(a), (caddr_t)tl, (s)); \ 370 } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \ 371 error = t2; \ 372 m_freem(mreq); \ 373 goto nfsmout; \ 374 } 375 376#define nfsm_srvdone \ 377 nfsmout: \ 378 return(error) 379 380#define nfsm_reply(s) \ 381 { \ 382 nfsd->nd_repstat = error; \ 383 if (error && !(nfsd->nd_flag & ND_NFSV3)) \ 384 (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \ 385 mrq, &mb, &bpos); \ 386 else \ 387 (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \ 388 mrq, &mb, &bpos); \ 389 if (mrep != NULL) { \ 390 m_freem(mrep); \ 391 mrep = NULL; \ 392 } \ 393 mreq = *mrq; \ 394 if (error && (!(nfsd->nd_flag & ND_NFSV3) || \ 395 error == EBADRPC)) { \ 396 error = 0; \ 397 goto nfsmout; \ 398 } } 399 400#define nfsm_writereply(s, v3) \ 401 { \ 402 nfsd->nd_repstat = error; \ 403 if (error && !(v3)) \ 404 (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \ 405 &mreq, &mb, &bpos); \ 406 else \ 407 (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \ 408 &mreq, &mb, &bpos); \ 409 } 410 411#define nfsm_adv(s) \ 412 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 413 if (t1 >= (s)) { \ 414 dpos += (s); \ 415 } else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \ 416 error = t1; \ 417 m_freem(mrep); \ 418 goto nfsmout; \ 419 } } 420 421#define nfsm_srvmtofh(f) \ 422 do { \ 423 int fhlen; \ 424 if (nfsd->nd_flag & ND_NFSV3) { \ 425 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 426 fhlen = fxdr_unsigned(int, *tl); \ 427 if (fhlen != 0 && fhlen != NFSX_V3FH) { \ 428 error = EBADRPC; \ 429 nfsm_reply(0); \ 430 } \ 431 } else { \ 432 fhlen = NFSX_V2FH; \ 433 } \ 434 if (fhlen != 0) { \ 435 nfsm_dissect(tl, u_int32_t *, fhlen); \ 436 bcopy((caddr_t)tl, (caddr_t)(f), fhlen); \ 437 } else {\ 438 bzero((caddr_t)(f), NFSX_V3FH); \ 439 } \ 440 } while (0) 441 442#define nfsm_clget \ 443 if (bp >= be) { \ 444 if (mp == mb) \ 445 mp->m_len += bp-bpos; \ 446 MGET(mp, M_WAIT, MT_DATA); \ 447 MCLGET(mp, M_WAIT); \ 448 mp->m_len = NFSMSIZ(mp); \ 449 mp2->m_next = mp; \ 450 mp2 = mp; \ 451 bp = mtod(mp, caddr_t); \ 452 be = bp+mp->m_len; \ 453 } \ 454 tl = (u_int32_t *)bp 455 456#define nfsm_srvfillattr(a, f) \ 457 nfsm_srvfattr(nfsd, (a), (f)) 458 459#define nfsm_srvwcc_data(br, b, ar, a) \ 460 nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos) 461 462#define nfsm_srvpostop_attr(r, a) \ 463 nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos) 464 465#define nfsm_srvsattr(a) \ 466 { nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 467 if (*tl == nfs_true) { \ 468 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 469 (a)->va_mode = nfstov_mode(*tl); \ 470 } \ 471 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 472 if (*tl == nfs_true) { \ 473 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 474 (a)->va_uid = fxdr_unsigned(uid_t, *tl); \ 475 } \ 476 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 477 if (*tl == nfs_true) { \ 478 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 479 (a)->va_gid = fxdr_unsigned(gid_t, *tl); \ 480 } \ 481 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 482 if (*tl == nfs_true) { \ 483 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ 484 (a)->va_size = fxdr_hyper(tl); \ 485 } \ 486 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 487 switch (fxdr_unsigned(int, *tl)) { \ 488 case NFSV3SATTRTIME_TOCLIENT: \ 489 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ 490 fxdr_nfsv3time(tl, &(a)->va_atime); \ 491 break; \ 492 case NFSV3SATTRTIME_TOSERVER: \ 493 getnanotime(&(a)->va_atime); \ 494 break; \ 495 }; \ 496 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 497 switch (fxdr_unsigned(int, *tl)) { \ 498 case NFSV3SATTRTIME_TOCLIENT: \ 499 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ 500 fxdr_nfsv3time(tl, &(a)->va_mtime); \ 501 break; \ 502 case NFSV3SATTRTIME_TOSERVER: \ 503 getnanotime(&(a)->va_mtime); \ 504 break; \ 505 }; } 506 507#endif 508