nfsm_subs.h revision 1.27
1/* $OpenBSD: nfsm_subs.h,v 1.27 2008/06/12 20:24:06 blambert Exp $ */ 2/* $NetBSD: nfsm_subs.h,v 1.10 1996/03/20 21:59:56 fvdl Exp $ */ 3 4/* 5 * Copyright (c) 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Rick Macklem at The University of Guelph. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95 36 */ 37 38 39#ifndef _NFS_NFSM_SUBS_H_ 40#define _NFS_NFSM_SUBS_H_ 41 42 43/* 44 * These macros do strange and peculiar things to mbuf chains for 45 * the assistance of the nfs code. To attempt to use them for any 46 * other purpose will be dangerous. (they make weird assumptions) 47 */ 48 49/* 50 * First define what the actual subs. return 51 */ 52 53#define M_HASCL(m) ((m)->m_flags & M_EXT) 54#define NFSMADV(m, s) (m)->m_data += (s) 55#define NFSMSIZ(m) ((M_HASCL(m)) ? (m)->m_ext.ext_size : \ 56 (((m)->m_flags & M_PKTHDR) ? MHLEN : MLEN)) 57 58/* 59 * Now for the macros that do the simple stuff and call the functions 60 * for the hard stuff. 61 * These macros use several vars. declared in nfsm_reqhead and these 62 * vars. must not be used elsewhere unless you are careful not to corrupt 63 * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries 64 * that may be used so long as the value is not expected to retained 65 * after a macro. 66 * I know, this is kind of dorkey, but it makes the actual op functions 67 * fairly clean and deals with the mess caused by the xdr discriminating 68 * unions. 69 */ 70 71#define nfsm_dissect(a, c, s) \ 72 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 73 if (t1 >= (s)) { \ 74 (a) = (c)(dpos); \ 75 dpos += (s); \ 76 } else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \ 77 error = t1; \ 78 m_freem(mrep); \ 79 goto nfsmout; \ 80 } else { \ 81 (a) = (c)cp2; \ 82 } } 83 84#define nfsm_fhtom(v, v3) \ 85 { if (v3) { \ 86 nfsm_strtombuf(&mb, VTONFS(v)->n_fhp, \ 87 VTONFS(v)->n_fhsize); \ 88 } else { \ 89 cp = nfsm_build(&mb, NFSX_V2FH); \ 90 bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \ 91 } } 92 93#define nfsm_srvfhtom(f, v3) \ 94 { if (v3) { \ 95 tl = nfsm_build(&mb, NFSX_UNSIGNED + NFSX_V3FH); \ 96 *tl++ = txdr_unsigned(NFSX_V3FH); \ 97 bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \ 98 } else { \ 99 cp = nfsm_build(&mb, NFSX_V2FH); \ 100 bcopy((caddr_t)(f), cp, NFSX_V2FH); \ 101 } } 102 103#define nfsm_srvpostop_fh(f) \ 104 { tl = nfsm_build(&mb, 2 * NFSX_UNSIGNED + NFSX_V3FH); \ 105 *tl++ = nfs_true; \ 106 *tl++ = txdr_unsigned(NFSX_V3FH); \ 107 bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \ 108 } 109 110#define nfsm_mtofh(d, v, v3, f) \ 111 { struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \ 112 if (v3) { \ 113 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 114 (f) = fxdr_unsigned(int, *tl); \ 115 } else \ 116 (f) = 1; \ 117 if (f) { \ 118 nfsm_getfh(ttfhp, ttfhsize, (v3)); \ 119 if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \ 120 &ttnp)) != 0) { \ 121 error = t1; \ 122 m_freem(mrep); \ 123 goto nfsmout; \ 124 } \ 125 (v) = NFSTOV(ttnp); \ 126 } \ 127 if (v3) { \ 128 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 129 if (f) \ 130 (f) = fxdr_unsigned(int, *tl); \ 131 else if (fxdr_unsigned(int, *tl)) \ 132 nfsm_adv(NFSX_V3FATTR); \ 133 } \ 134 if (f) \ 135 nfsm_loadattr((v), (struct vattr *)0); \ 136 } 137 138#define nfsm_getfh(f, s, v3) \ 139 { if (v3) { \ 140 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 141 if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \ 142 (s) > NFSX_V3FHMAX) { \ 143 m_freem(mrep); \ 144 error = EBADRPC; \ 145 goto nfsmout; \ 146 } \ 147 } else \ 148 (s) = NFSX_V2FH; \ 149 nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); } 150 151#define nfsm_loadattr(v, a) \ 152 { struct vnode *ttvp = (v); \ 153 if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \ 154 error = t1; \ 155 m_freem(mrep); \ 156 goto nfsmout; \ 157 } \ 158 (v) = ttvp; } 159 160#define nfsm_postop_attr(v, f) \ 161 { struct vnode *ttvp = (v); \ 162 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 163 if (((f) = fxdr_unsigned(int, *tl)) != 0) { \ 164 if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \ 165 (struct vattr *)0)) != 0) { \ 166 error = t1; \ 167 (f) = 0; \ 168 m_freem(mrep); \ 169 goto nfsmout; \ 170 } \ 171 (v) = ttvp; \ 172 } } 173 174/* Used as (f) for nfsm_wcc_data() */ 175#define NFSV3_WCCRATTR 0 176#define NFSV3_WCCCHK 1 177 178#define nfsm_wcc_data(v, f) \ 179 { int ttattrf, ttretf = 0; \ 180 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 181 if (*tl == nfs_true) { \ 182 nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); \ 183 if (f) \ 184 ttretf = (VTONFS(v)->n_mtime == \ 185 fxdr_unsigned(u_int32_t, *(tl + 2))); \ 186 } \ 187 nfsm_postop_attr((v), ttattrf); \ 188 if (f) { \ 189 (f) = ttretf; \ 190 } else { \ 191 (f) = ttattrf; \ 192 } } 193 194#define nfsm_strsiz(s,m) \ 195 { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ 196 if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \ 197 m_freem(mrep); \ 198 error = EBADRPC; \ 199 goto nfsmout; \ 200 } } 201 202#define nfsm_srvstrsiz(s,m) \ 203 { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ 204 if (((s) = fxdr_unsigned(int32_t,*tl)) > (m) || (s) <= 0) { \ 205 error = EBADRPC; \ 206 nfsm_reply(0); \ 207 } } 208 209#define nfsm_srvnamesiz(s) \ 210 { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ 211 if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) \ 212 error = NFSERR_NAMETOL; \ 213 if ((s) <= 0) \ 214 error = EBADRPC; \ 215 if (error) \ 216 nfsm_reply(0); \ 217 } 218 219#define nfsm_mtouio(p,s) \ 220 if ((s) > 0 && \ 221 (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \ 222 error = t1; \ 223 m_freem(mrep); \ 224 goto nfsmout; \ 225 } 226 227#define nfsm_reqhead(v,a,s) \ 228 mb = mreq = nfsm_reqh((v),(a),(s)) 229 230#define nfsm_rndup(a) (((a)+3)&(~0x3)) 231 232#define nfsm_request(v, t, p, c) \ 233 if ((error = nfs_request((v), mreq, (t), (p), \ 234 (c), &mrep, &md, &dpos)) != 0) { \ 235 if (error & NFSERR_RETERR) \ 236 error &= ~NFSERR_RETERR; \ 237 else \ 238 goto nfsmout; \ 239 } 240 241#define nfsm_strtom(a,s,m) \ 242 if ((s) > (m)) { \ 243 m_freem(mreq); \ 244 error = ENAMETOOLONG; \ 245 goto nfsmout; \ 246 } \ 247 nfsm_strtombuf(&mb, (a), (s)) 248 249#define nfsm_reply(s) \ 250 { \ 251 nfsd->nd_repstat = error; \ 252 if (error && !(nfsd->nd_flag & ND_NFSV3)) \ 253 (void) nfs_rephead(0, nfsd, slp, error, \ 254 mrq, &mb); \ 255 else \ 256 (void) nfs_rephead((s), nfsd, slp, error, \ 257 mrq, &mb); \ 258 if (mrep != NULL) { \ 259 m_freem(mrep); \ 260 mrep = NULL; \ 261 } \ 262 mreq = *mrq; \ 263 if (error && (!(nfsd->nd_flag & ND_NFSV3) || \ 264 error == EBADRPC)) \ 265 return(0); \ 266 } 267 268#define nfsm_writereply(s, v3) \ 269 { \ 270 nfsd->nd_repstat = error; \ 271 if (error && !(v3)) \ 272 (void) nfs_rephead(0, nfsd, slp, error, \ 273 &mreq, &mb); \ 274 else \ 275 (void) nfs_rephead((s), nfsd, slp, error, \ 276 &mreq, &mb); \ 277 } 278 279#define nfsm_adv(s) \ 280 { t1 = mtod(md, caddr_t)+md->m_len-dpos; \ 281 if (t1 >= (s)) { \ 282 dpos += (s); \ 283 } else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \ 284 error = t1; \ 285 m_freem(mrep); \ 286 goto nfsmout; \ 287 } } 288 289#define nfsm_srvmtofh(f) \ 290 { if (nfsd->nd_flag & ND_NFSV3) { \ 291 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 292 if (fxdr_unsigned(int, *tl) != NFSX_V3FH) { \ 293 error = EBADRPC; \ 294 nfsm_reply(0); \ 295 } \ 296 } \ 297 nfsm_dissect(tl, u_int32_t *, NFSX_V3FH); \ 298 bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \ 299 if ((nfsd->nd_flag & ND_NFSV3) == 0) \ 300 nfsm_adv(NFSX_V2FH - NFSX_V3FH); \ 301 } 302 303#define nfsm_srvpostop_attr(r, a) \ 304 nfsm_srvpostopattr(nfsd, (r), (a), &mb) 305 306#define nfsm_srvsattr(a) \ 307 { nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 308 if (*tl == nfs_true) { \ 309 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 310 (a)->va_mode = nfstov_mode(*tl); \ 311 } \ 312 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 313 if (*tl == nfs_true) { \ 314 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 315 (a)->va_uid = fxdr_unsigned(uid_t, *tl); \ 316 } \ 317 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 318 if (*tl == nfs_true) { \ 319 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 320 (a)->va_gid = fxdr_unsigned(gid_t, *tl); \ 321 } \ 322 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 323 if (*tl == nfs_true) { \ 324 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ 325 (a)->va_size = fxdr_hyper(tl); \ 326 } \ 327 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 328 switch (fxdr_unsigned(int, *tl)) { \ 329 case NFSV3SATTRTIME_TOCLIENT: \ 330 (a)->va_vaflags &= ~VA_UTIMES_NULL; \ 331 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ 332 fxdr_nfsv3time(tl, &(a)->va_atime); \ 333 break; \ 334 case NFSV3SATTRTIME_TOSERVER: \ 335 getnanotime(&(a)->va_atime); \ 336 break; \ 337 }; \ 338 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 339 switch (fxdr_unsigned(int, *tl)) { \ 340 case NFSV3SATTRTIME_TOCLIENT: \ 341 (a)->va_vaflags &= ~VA_UTIMES_NULL; \ 342 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ 343 fxdr_nfsv3time(tl, &(a)->va_mtime); \ 344 break; \ 345 case NFSV3SATTRTIME_TOSERVER: \ 346 getnanotime(&(a)->va_mtime); \ 347 break; \ 348 }; } 349 350#endif 351