138414Smckusick /* 238414Smckusick * Copyright (c) 1989 The Regents of the University of California. 338414Smckusick * All rights reserved. 438414Smckusick * 538414Smckusick * This code is derived from software contributed to Berkeley by 638414Smckusick * Rick Macklem at The University of Guelph. 738414Smckusick * 844515Sbostic * %sccs.include.redist.c% 938414Smckusick * 10*58879Smckusick * @(#)nfsm_subs.h 7.15 (Berkeley) 03/30/93 1138414Smckusick */ 1238414Smckusick 1338414Smckusick /* 1438414Smckusick * These macros do strange and peculiar things to mbuf chains for 1538414Smckusick * the assistance of the nfs code. To attempt to use them for any 1638414Smckusick * other purpose will be dangerous. (they make weird assumptions) 1738414Smckusick */ 1838414Smckusick 1938414Smckusick /* 2038414Smckusick * First define what the actual subs. return 2138414Smckusick */ 2239494Smckusick extern struct mbuf *nfsm_reqh(); 2338414Smckusick 2438414Smckusick #define M_HASCL(m) ((m)->m_flags & M_EXT) 2538414Smckusick #define NFSMINOFF(m) \ 2638414Smckusick if (M_HASCL(m)) \ 2738414Smckusick (m)->m_data = (m)->m_ext.ext_buf; \ 2852196Smckusick else if ((m)->m_flags & M_PKTHDR) \ 2952196Smckusick (m)->m_data = (m)->m_pktdat; \ 3038414Smckusick else \ 3138414Smckusick (m)->m_data = (m)->m_dat 3238414Smckusick #define NFSMADV(m, s) (m)->m_data += (s) 3338425Smckusick #define NFSMSIZ(m) ((M_HASCL(m))?MCLBYTES: \ 3438414Smckusick (((m)->m_flags & M_PKTHDR)?MHLEN:MLEN)) 3538414Smckusick 3638414Smckusick /* 3738414Smckusick * Now for the macros that do the simple stuff and call the functions 3838414Smckusick * for the hard stuff. 3938414Smckusick * These macros use several vars. declared in nfsm_reqhead and these 4038414Smckusick * vars. must not be used elsewhere unless you are careful not to corrupt 4138414Smckusick * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries 4238414Smckusick * that may be used so long as the value is not expected to retained 4338414Smckusick * after a macro. 4438414Smckusick * I know, this is kind of dorkey, but it makes the actual op functions 4538414Smckusick * fairly clean and deals with the mess caused by the xdr discriminating 4638414Smckusick * unions. 4738414Smckusick */ 4838414Smckusick 4938414Smckusick #define nfsm_build(a,c,s) \ 5052196Smckusick { if ((s) > M_TRAILINGSPACE(mb)) { \ 5138414Smckusick MGET(mb2, M_WAIT, MT_DATA); \ 5238414Smckusick if ((s) > MLEN) \ 5338414Smckusick panic("build > MLEN"); \ 5438414Smckusick mb->m_next = mb2; \ 5538414Smckusick mb = mb2; \ 5638414Smckusick mb->m_len = 0; \ 5738414Smckusick bpos = mtod(mb, caddr_t); \ 5838414Smckusick } \ 5938414Smckusick (a) = (c)(bpos); \ 6038414Smckusick mb->m_len += (s); \ 6152196Smckusick bpos += (s); } 6238414Smckusick 6352196Smckusick #define nfsm_dissect(a,c,s) \ 6452196Smckusick { t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 6538414Smckusick if (t1 >= (s)) { \ 6638414Smckusick (a) = (c)(dpos); \ 6738414Smckusick dpos += (s); \ 6838414Smckusick } else if (error = nfsm_disct(&md, &dpos, (s), t1, TRUE, &cp2)) { \ 6938414Smckusick m_freem(mrep); \ 7038414Smckusick goto nfsmout; \ 7138414Smckusick } else { \ 7238414Smckusick (a) = (c)cp2; \ 7352196Smckusick } } 7438414Smckusick 7552196Smckusick #define nfsm_dissecton(a,c,s) \ 7652196Smckusick { t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 7738414Smckusick if (t1 >= (s)) { \ 7838414Smckusick (a) = (c)(dpos); \ 7938414Smckusick dpos += (s); \ 8038414Smckusick } else if (error = nfsm_disct(&md, &dpos, (s), t1, FALSE, &cp2)) { \ 8138414Smckusick m_freem(mrep); \ 8238414Smckusick goto nfsmout; \ 8338414Smckusick } else { \ 8438414Smckusick (a) = (c)cp2; \ 8552196Smckusick } } 8638414Smckusick 8738414Smckusick #define nfsm_fhtom(v) \ 8838414Smckusick nfsm_build(cp,caddr_t,NFSX_FH); \ 8938414Smckusick bcopy((caddr_t)&(VTONFS(v)->n_fh), cp, NFSX_FH) 9038414Smckusick 9138414Smckusick #define nfsm_srvfhtom(f) \ 9238414Smckusick nfsm_build(cp,caddr_t,NFSX_FH); \ 9338414Smckusick bcopy((caddr_t)(f), cp, NFSX_FH) 9438414Smckusick 9538414Smckusick #define nfsm_mtofh(d,v) \ 9638414Smckusick { struct nfsnode *np; nfsv2fh_t *fhp; \ 9752196Smckusick nfsm_dissect(fhp,nfsv2fh_t *,NFSX_FH); \ 9838414Smckusick if (error = nfs_nget((d)->v_mount, fhp, &np)) { \ 9938414Smckusick m_freem(mrep); \ 10038414Smckusick goto nfsmout; \ 10138414Smckusick } \ 10238414Smckusick (v) = NFSTOV(np); \ 10338414Smckusick nfsm_loadattr(v, (struct vattr *)0); \ 10438414Smckusick } 10538414Smckusick 10638414Smckusick #define nfsm_loadattr(v,a) \ 10739494Smckusick { struct vnode *tvp = (v); \ 10839494Smckusick if (error = nfs_loadattrcache(&tvp, &md, &dpos, (a))) { \ 10938414Smckusick m_freem(mrep); \ 11038414Smckusick goto nfsmout; \ 11139494Smckusick } \ 11239494Smckusick (v) = tvp; } 11338414Smckusick 11438414Smckusick #define nfsm_strsiz(s,m) \ 11552196Smckusick { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \ 11648046Smckusick if (((s) = fxdr_unsigned(long,*tl)) > (m)) { \ 11738414Smckusick m_freem(mrep); \ 11838414Smckusick error = EBADRPC; \ 11938414Smckusick goto nfsmout; \ 12052196Smckusick } } 12138414Smckusick 12238414Smckusick #define nfsm_srvstrsiz(s,m) \ 12352196Smckusick { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \ 12448046Smckusick if (((s) = fxdr_unsigned(long,*tl)) > (m) || (s) <= 0) { \ 12538414Smckusick error = EBADRPC; \ 12638414Smckusick nfsm_reply(0); \ 12752196Smckusick } } 12838414Smckusick 12938414Smckusick #define nfsm_mtouio(p,s) \ 13038414Smckusick if ((s) > 0 && \ 13138414Smckusick (error = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \ 13238414Smckusick m_freem(mrep); \ 13338414Smckusick goto nfsmout; \ 13438414Smckusick } 13538414Smckusick 13638414Smckusick #define nfsm_uiotom(p,s) \ 13738414Smckusick if (error = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \ 13838414Smckusick m_freem(mreq); \ 13938414Smckusick goto nfsmout; \ 14038414Smckusick } 14138414Smckusick 14252196Smckusick #define nfsm_reqhead(v,a,s) \ 14352196Smckusick mb = mreq = nfsm_reqh((v),(a),(s),&bpos) 14438414Smckusick 14538414Smckusick #define nfsm_reqdone m_freem(mrep); \ 14638414Smckusick nfsmout: 14738414Smckusick 14838414Smckusick #define nfsm_rndup(a) (((a)+3)&(~0x3)) 14938414Smckusick 15052196Smckusick #define nfsm_request(v, t, p, c) \ 15152196Smckusick if (error = nfs_request((v), mreq, (t), (p), \ 15252196Smckusick (c), &mrep, &md, &dpos)) \ 15338414Smckusick goto nfsmout 15438414Smckusick 15538414Smckusick #define nfsm_strtom(a,s,m) \ 15638414Smckusick if ((s) > (m)) { \ 15738414Smckusick m_freem(mreq); \ 15838414Smckusick error = ENAMETOOLONG; \ 15938414Smckusick goto nfsmout; \ 16038414Smckusick } \ 16138414Smckusick t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \ 16252196Smckusick if (t2 <= M_TRAILINGSPACE(mb)) { \ 16348046Smckusick nfsm_build(tl,u_long *,t2); \ 16448046Smckusick *tl++ = txdr_unsigned(s); \ 16548046Smckusick *(tl+((t2>>2)-2)) = 0; \ 16648046Smckusick bcopy((caddr_t)(a), (caddr_t)tl, (s)); \ 16738414Smckusick } else if (error = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \ 16838414Smckusick m_freem(mreq); \ 16938414Smckusick goto nfsmout; \ 17038414Smckusick } 17138414Smckusick 17238414Smckusick #define nfsm_srvdone \ 17338414Smckusick nfsmout: \ 17438414Smckusick return(error) 17538414Smckusick 17638414Smckusick #define nfsm_reply(s) \ 17738414Smckusick { \ 17852196Smckusick nfsd->nd_repstat = error; \ 17938414Smckusick if (error) \ 18052196Smckusick (void) nfs_rephead(0, nfsd, error, cache, &frev, \ 18152196Smckusick mrq, &mb, &bpos); \ 18238414Smckusick else \ 18352196Smckusick (void) nfs_rephead((s), nfsd, error, cache, &frev, \ 18452196Smckusick mrq, &mb, &bpos); \ 18538414Smckusick m_freem(mrep); \ 18639745Smckusick mreq = *mrq; \ 18738414Smckusick if (error) \ 18838414Smckusick return(0); \ 18938414Smckusick } 19038414Smckusick 19138414Smckusick #define nfsm_adv(s) \ 19238414Smckusick t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 19338414Smckusick if (t1 >= (s)) { \ 19438414Smckusick dpos += (s); \ 19538414Smckusick } else if (error = nfs_adv(&md, &dpos, (s), t1)) { \ 19638414Smckusick m_freem(mrep); \ 19738414Smckusick goto nfsmout; \ 19838414Smckusick } 19938414Smckusick 20038414Smckusick #define nfsm_srvmtofh(f) \ 20152196Smckusick nfsm_dissecton(tl, u_long *, NFSX_FH); \ 20248046Smckusick bcopy((caddr_t)tl, (caddr_t)f, NFSX_FH) 20338414Smckusick 20438414Smckusick #define nfsm_clget \ 20538414Smckusick if (bp >= be) { \ 20652196Smckusick if (mp == mb) \ 20752196Smckusick mp->m_len += bp-bpos; \ 20838414Smckusick MGET(mp, M_WAIT, MT_DATA); \ 20941894Smckusick MCLGET(mp, M_WAIT); \ 21038414Smckusick mp->m_len = NFSMSIZ(mp); \ 21152196Smckusick mp2->m_next = mp; \ 21252196Smckusick mp2 = mp; \ 21338414Smckusick bp = mtod(mp, caddr_t); \ 21438414Smckusick be = bp+mp->m_len; \ 21538414Smckusick } \ 21648046Smckusick tl = (u_long *)bp 21738414Smckusick 21839745Smckusick #define nfsm_srvfillattr \ 21939745Smckusick fp->fa_type = vtonfs_type(vap->va_type); \ 22039745Smckusick fp->fa_mode = vtonfs_mode(vap->va_type, vap->va_mode); \ 22139745Smckusick fp->fa_nlink = txdr_unsigned(vap->va_nlink); \ 22239745Smckusick fp->fa_uid = txdr_unsigned(vap->va_uid); \ 22339745Smckusick fp->fa_gid = txdr_unsigned(vap->va_gid); \ 22456277Smckusick if (nfsd->nd_nqlflag == NQL_NOVAL) { \ 22556277Smckusick fp->fa_nfsblocksize = txdr_unsigned(vap->va_blocksize); \ 22656277Smckusick if (vap->va_type == VFIFO) \ 22756277Smckusick fp->fa_nfsrdev = 0xffffffff; \ 22856277Smckusick else \ 22956277Smckusick fp->fa_nfsrdev = txdr_unsigned(vap->va_rdev); \ 23056277Smckusick fp->fa_nfsfsid = txdr_unsigned(vap->va_fsid); \ 23156277Smckusick fp->fa_nfsfileid = txdr_unsigned(vap->va_fileid); \ 23256277Smckusick fp->fa_nfssize = txdr_unsigned(vap->va_size); \ 23356277Smckusick fp->fa_nfsblocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); \ 234*58879Smckusick txdr_nfstime(&vap->va_atime, &fp->fa_nfsatime); \ 23556277Smckusick txdr_nfstime(&vap->va_mtime, &fp->fa_nfsmtime); \ 23656277Smckusick fp->fa_nfsctime.nfs_sec = txdr_unsigned(vap->va_ctime.ts_sec); \ 23756277Smckusick fp->fa_nfsctime.nfs_usec = txdr_unsigned(vap->va_gen); \ 23856277Smckusick } else { \ 23956277Smckusick fp->fa_nqblocksize = txdr_unsigned(vap->va_blocksize); \ 24056277Smckusick if (vap->va_type == VFIFO) \ 24156277Smckusick fp->fa_nqrdev = 0xffffffff; \ 24256277Smckusick else \ 24356277Smckusick fp->fa_nqrdev = txdr_unsigned(vap->va_rdev); \ 24456277Smckusick fp->fa_nqfsid = txdr_unsigned(vap->va_fsid); \ 24556277Smckusick fp->fa_nqfileid = txdr_unsigned(vap->va_fileid); \ 24656277Smckusick txdr_hyper(&vap->va_size, &fp->fa_nqsize); \ 24756277Smckusick txdr_hyper(&vap->va_bytes, &fp->fa_nqbytes); \ 24856277Smckusick txdr_nqtime(&vap->va_atime, &fp->fa_nqatime); \ 24956277Smckusick txdr_nqtime(&vap->va_mtime, &fp->fa_nqmtime); \ 25056277Smckusick txdr_nqtime(&vap->va_ctime, &fp->fa_nqctime); \ 25156277Smckusick fp->fa_nqflags = txdr_unsigned(vap->va_flags); \ 25256277Smckusick fp->fa_nqgen = txdr_unsigned(vap->va_gen); \ 25356277Smckusick txdr_hyper(&vap->va_filerev, &fp->fa_nqfilerev); \ 25456277Smckusick } 25539745Smckusick 256