1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)nfsm_subs.h 7.13 (Berkeley) 06/19/92 11 */ 12 13 /* 14 * These macros do strange and peculiar things to mbuf chains for 15 * the assistance of the nfs code. To attempt to use them for any 16 * other purpose will be dangerous. (they make weird assumptions) 17 */ 18 19 /* 20 * First define what the actual subs. return 21 */ 22 extern struct mbuf *nfsm_reqh(); 23 24 #define M_HASCL(m) ((m)->m_flags & M_EXT) 25 #define NFSMINOFF(m) \ 26 if (M_HASCL(m)) \ 27 (m)->m_data = (m)->m_ext.ext_buf; \ 28 else if ((m)->m_flags & M_PKTHDR) \ 29 (m)->m_data = (m)->m_pktdat; \ 30 else \ 31 (m)->m_data = (m)->m_dat 32 #define NFSMADV(m, s) (m)->m_data += (s) 33 #define NFSMSIZ(m) ((M_HASCL(m))?MCLBYTES: \ 34 (((m)->m_flags & M_PKTHDR)?MHLEN:MLEN)) 35 36 /* 37 * Now for the macros that do the simple stuff and call the functions 38 * for the hard stuff. 39 * These macros use several vars. declared in nfsm_reqhead and these 40 * vars. must not be used elsewhere unless you are careful not to corrupt 41 * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries 42 * that may be used so long as the value is not expected to retained 43 * after a macro. 44 * I know, this is kind of dorkey, but it makes the actual op functions 45 * fairly clean and deals with the mess caused by the xdr discriminating 46 * unions. 47 */ 48 49 #define nfsm_build(a,c,s) \ 50 { if ((s) > M_TRAILINGSPACE(mb)) { \ 51 MGET(mb2, M_WAIT, MT_DATA); \ 52 if ((s) > MLEN) \ 53 panic("build > MLEN"); \ 54 mb->m_next = mb2; \ 55 mb = mb2; \ 56 mb->m_len = 0; \ 57 bpos = mtod(mb, caddr_t); \ 58 } \ 59 (a) = (c)(bpos); \ 60 mb->m_len += (s); \ 61 bpos += (s); } 62 63 #define nfsm_dissect(a,c,s) \ 64 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 65 if (t1 >= (s)) { \ 66 (a) = (c)(dpos); \ 67 dpos += (s); \ 68 } else if (error = nfsm_disct(&md, &dpos, (s), t1, TRUE, &cp2)) { \ 69 m_freem(mrep); \ 70 goto nfsmout; \ 71 } else { \ 72 (a) = (c)cp2; \ 73 } } 74 75 #define nfsm_dissecton(a,c,s) \ 76 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 77 if (t1 >= (s)) { \ 78 (a) = (c)(dpos); \ 79 dpos += (s); \ 80 } else if (error = nfsm_disct(&md, &dpos, (s), t1, FALSE, &cp2)) { \ 81 m_freem(mrep); \ 82 goto nfsmout; \ 83 } else { \ 84 (a) = (c)cp2; \ 85 } } 86 87 #define nfsm_fhtom(v) \ 88 nfsm_build(cp,caddr_t,NFSX_FH); \ 89 bcopy((caddr_t)&(VTONFS(v)->n_fh), cp, NFSX_FH) 90 91 #define nfsm_srvfhtom(f) \ 92 nfsm_build(cp,caddr_t,NFSX_FH); \ 93 bcopy((caddr_t)(f), cp, NFSX_FH) 94 95 #define nfsm_mtofh(d,v) \ 96 { struct nfsnode *np; nfsv2fh_t *fhp; \ 97 nfsm_dissect(fhp,nfsv2fh_t *,NFSX_FH); \ 98 if (error = nfs_nget((d)->v_mount, fhp, &np)) { \ 99 m_freem(mrep); \ 100 goto nfsmout; \ 101 } \ 102 (v) = NFSTOV(np); \ 103 nfsm_loadattr(v, (struct vattr *)0); \ 104 } 105 106 #define nfsm_loadattr(v,a) \ 107 { struct vnode *tvp = (v); \ 108 if (error = nfs_loadattrcache(&tvp, &md, &dpos, (a))) { \ 109 m_freem(mrep); \ 110 goto nfsmout; \ 111 } \ 112 (v) = tvp; } 113 114 #define nfsm_strsiz(s,m) \ 115 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \ 116 if (((s) = fxdr_unsigned(long,*tl)) > (m)) { \ 117 m_freem(mrep); \ 118 error = EBADRPC; \ 119 goto nfsmout; \ 120 } } 121 122 #define nfsm_srvstrsiz(s,m) \ 123 { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \ 124 if (((s) = fxdr_unsigned(long,*tl)) > (m) || (s) <= 0) { \ 125 error = EBADRPC; \ 126 nfsm_reply(0); \ 127 } } 128 129 #define nfsm_mtouio(p,s) \ 130 if ((s) > 0 && \ 131 (error = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \ 132 m_freem(mrep); \ 133 goto nfsmout; \ 134 } 135 136 #define nfsm_uiotom(p,s) \ 137 if (error = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \ 138 m_freem(mreq); \ 139 goto nfsmout; \ 140 } 141 142 #define nfsm_reqhead(v,a,s) \ 143 mb = mreq = nfsm_reqh((v),(a),(s),&bpos) 144 145 #define nfsm_reqdone m_freem(mrep); \ 146 nfsmout: 147 148 #define nfsm_rndup(a) (((a)+3)&(~0x3)) 149 150 #define nfsm_request(v, t, p, c) \ 151 if (error = nfs_request((v), mreq, (t), (p), \ 152 (c), &mrep, &md, &dpos)) \ 153 goto nfsmout 154 155 #define nfsm_strtom(a,s,m) \ 156 if ((s) > (m)) { \ 157 m_freem(mreq); \ 158 error = ENAMETOOLONG; \ 159 goto nfsmout; \ 160 } \ 161 t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \ 162 if (t2 <= M_TRAILINGSPACE(mb)) { \ 163 nfsm_build(tl,u_long *,t2); \ 164 *tl++ = txdr_unsigned(s); \ 165 *(tl+((t2>>2)-2)) = 0; \ 166 bcopy((caddr_t)(a), (caddr_t)tl, (s)); \ 167 } else if (error = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \ 168 m_freem(mreq); \ 169 goto nfsmout; \ 170 } 171 172 #define nfsm_srvdone \ 173 nfsmout: \ 174 return(error) 175 176 #define nfsm_reply(s) \ 177 { \ 178 nfsd->nd_repstat = error; \ 179 if (error) \ 180 (void) nfs_rephead(0, nfsd, error, cache, &frev, \ 181 mrq, &mb, &bpos); \ 182 else \ 183 (void) nfs_rephead((s), nfsd, error, cache, &frev, \ 184 mrq, &mb, &bpos); \ 185 m_freem(mrep); \ 186 mreq = *mrq; \ 187 if (error) \ 188 return(0); \ 189 } 190 191 #define nfsm_adv(s) \ 192 t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 193 if (t1 >= (s)) { \ 194 dpos += (s); \ 195 } else if (error = nfs_adv(&md, &dpos, (s), t1)) { \ 196 m_freem(mrep); \ 197 goto nfsmout; \ 198 } 199 200 #define nfsm_srvmtofh(f) \ 201 nfsm_dissecton(tl, u_long *, NFSX_FH); \ 202 bcopy((caddr_t)tl, (caddr_t)f, NFSX_FH) 203 204 #define nfsm_clget \ 205 if (bp >= be) { \ 206 if (mp == mb) \ 207 mp->m_len += bp-bpos; \ 208 MGET(mp, M_WAIT, MT_DATA); \ 209 MCLGET(mp, M_WAIT); \ 210 mp->m_len = NFSMSIZ(mp); \ 211 mp2->m_next = mp; \ 212 mp2 = mp; \ 213 bp = mtod(mp, caddr_t); \ 214 be = bp+mp->m_len; \ 215 } \ 216 tl = (u_long *)bp 217 218 #define nfsm_srvfillattr \ 219 fp->fa_type = vtonfs_type(vap->va_type); \ 220 fp->fa_mode = vtonfs_mode(vap->va_type, vap->va_mode); \ 221 fp->fa_nlink = txdr_unsigned(vap->va_nlink); \ 222 fp->fa_uid = txdr_unsigned(vap->va_uid); \ 223 fp->fa_gid = txdr_unsigned(vap->va_gid); \ 224 fp->fa_size = txdr_unsigned(vap->va_size); \ 225 fp->fa_blocksize = txdr_unsigned(vap->va_blocksize); \ 226 if (vap->va_type == VFIFO) \ 227 fp->fa_rdev = 0xffffffff; \ 228 else \ 229 fp->fa_rdev = txdr_unsigned(vap->va_rdev); \ 230 fp->fa_blocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); \ 231 fp->fa_fsid = txdr_unsigned(vap->va_fsid); \ 232 fp->fa_fileid = txdr_unsigned(vap->va_fileid); \ 233 fp->fa_atime.tv_sec = txdr_unsigned(vap->va_atime.ts_sec); \ 234 fp->fa_atime.tv_usec = txdr_unsigned(vap->va_flags); \ 235 txdr_time(&vap->va_mtime, &fp->fa_mtime); \ 236 fp->fa_ctime.tv_sec = txdr_unsigned(vap->va_ctime.ts_sec); \ 237 fp->fa_ctime.tv_usec = txdr_unsigned(vap->va_gen) 238 239