1 /* $OpenBSD: nfsm_subs.h,v 1.43 2009/08/10 09:18:31 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 struct nfsm_info { 43 struct mbuf *nmi_mreq; 44 struct mbuf *nmi_mrep; 45 46 struct proc *nmi_procp; /* XXX XXX XXX */ 47 struct ucred *nmi_cred; /* XXX XXX XXX */ 48 49 /* Setting up / Tearing down. */ 50 struct mbuf *nmi_md; 51 struct mbuf *nmi_mb; 52 caddr_t nmi_dpos; 53 54 int nmi_v3; 55 }; 56 57 #define nfsm_dissect(a, c, s) { \ 58 t1 = mtod(info.nmi_md, caddr_t) + info.nmi_md->m_len - \ 59 info.nmi_dpos; \ 60 if (t1 >= (s)) { \ 61 (a) = (c)(info.nmi_dpos); \ 62 info.nmi_dpos += (s); \ 63 } else if ((t1 = \ 64 nfsm_disct(&info.nmi_md, &info.nmi_dpos, (s), t1, \ 65 &cp2)) != 0) { \ 66 error = t1; \ 67 m_freem(info.nmi_mrep); \ 68 goto nfsmout; \ 69 } else { \ 70 (a) = (c)cp2; \ 71 } \ 72 } 73 74 #define nfsm_srvpostop_fh(f) { \ 75 tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED + NFSX_V3FH); \ 76 *tl++ = nfs_true; \ 77 *tl++ = txdr_unsigned(NFSX_V3FH); \ 78 bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \ 79 } 80 81 #define nfsm_mtofh(d, v, v3, f) { \ 82 struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \ 83 if (v3) { \ 84 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 85 (f) = fxdr_unsigned(int, *tl); \ 86 } else \ 87 (f) = 1; \ 88 if (f) { \ 89 nfsm_getfh(ttfhp, ttfhsize, (v3)); \ 90 if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \ 91 &ttnp)) != 0) { \ 92 error = t1; \ 93 m_freem(info.nmi_mrep); \ 94 goto nfsmout; \ 95 } \ 96 (v) = NFSTOV(ttnp); \ 97 } \ 98 if (v3) { \ 99 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 100 if (f) \ 101 (f) = fxdr_unsigned(int, *tl); \ 102 else if (fxdr_unsigned(int, *tl)) \ 103 nfsm_adv(NFSX_V3FATTR); \ 104 } \ 105 if (f) \ 106 nfsm_loadattr((v), NULL); \ 107 } 108 109 #define nfsm_getfh(f, s, v3) { \ 110 if (v3) { \ 111 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 112 if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \ 113 (s) > NFSX_V3FHMAX) { \ 114 m_freem(info.nmi_mrep); \ 115 error = EBADRPC; \ 116 goto nfsmout; \ 117 } \ 118 } else \ 119 (s) = NFSX_V2FH; \ 120 nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); \ 121 } 122 123 #define nfsm_loadattr(v, a) { \ 124 struct vnode *ttvp = (v); \ 125 if ((t1 = nfs_loadattrcache(&ttvp, &info.nmi_md, \ 126 &info.nmi_dpos, (a))) != 0) { \ 127 error = t1; \ 128 m_freem(info.nmi_mrep); \ 129 goto nfsmout; \ 130 } \ 131 (v) = ttvp; \ 132 } 133 134 #define nfsm_postop_attr(v, f) { if (info.nmi_mrep != NULL) { \ 135 struct vnode *ttvp = (v); \ 136 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 137 if (((f) = fxdr_unsigned(int, *tl)) != 0) { \ 138 if ((t1 = nfs_loadattrcache(&ttvp, &info.nmi_md, \ 139 &info.nmi_dpos, NULL)) != 0) { \ 140 error = t1; \ 141 (f) = 0; \ 142 m_freem(info.nmi_mrep); \ 143 goto nfsmout; \ 144 } \ 145 (v) = ttvp; \ 146 } \ 147 } } 148 149 /* Used as (f) for nfsm_wcc_data() */ 150 #define NFSV3_WCCRATTR 0 151 #define NFSV3_WCCCHK 1 152 153 #define nfsm_wcc_data(v, f) do { if (info.nmi_mrep != NULL) { \ 154 struct timespec _mtime; \ 155 int ttattrf, ttretf = 0; \ 156 \ 157 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 158 if (*tl == nfs_true) { \ 159 nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); \ 160 fxdr_nfsv3time(tl + 2, &_mtime); \ 161 if (f) { \ 162 ttretf = timespeccmp(&VTONFS(v)->n_mtime, \ 163 &_mtime, !=); \ 164 } \ 165 } \ 166 nfsm_postop_attr((v), ttattrf); \ 167 if (f) { \ 168 (f) = ttretf; \ 169 } else { \ 170 (f) = ttattrf; \ 171 } \ 172 } } while (0) 173 174 #define nfsm_strsiz(s,m) { \ 175 nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ 176 if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \ 177 m_freem(info.nmi_mrep); \ 178 error = EBADRPC; \ 179 goto nfsmout; \ 180 } \ 181 } 182 183 #define nfsm_srvnamesiz(s) { \ 184 nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ 185 if (((s) = fxdr_unsigned(int32_t,*tl)) > NFS_MAXNAMLEN) \ 186 error = NFSERR_NAMETOL; \ 187 if ((s) <= 0) \ 188 error = EBADRPC; \ 189 if (error) \ 190 nfsm_reply(0); \ 191 } 192 193 #define nfsm_mtouio(p,s) \ 194 if ((s) > 0 && \ 195 (t1 = nfsm_mbuftouio(&info.nmi_md,(p),(s), \ 196 &info.nmi_dpos)) != 0) { \ 197 error = t1; \ 198 m_freem(info.nmi_mrep); \ 199 goto nfsmout; \ 200 } 201 202 #define nfsm_rndup(a) (((a)+3)&(~0x3)) 203 204 #define nfsm_strtom(a,s,m) \ 205 if ((s) > (m)) { \ 206 m_freem(info.nmi_mreq); \ 207 error = ENAMETOOLONG; \ 208 goto nfsmout; \ 209 } \ 210 nfsm_strtombuf(&info.nmi_mb, (a), (s)) 211 212 #define nfsm_reply(s) { \ 213 nfsd->nd_repstat = error; \ 214 if (error && !(nfsd->nd_flag & ND_NFSV3)) \ 215 (void) nfs_rephead(0, nfsd, slp, error, \ 216 &info.nmi_mreq, &info.nmi_mb); \ 217 else \ 218 (void) nfs_rephead((s), nfsd, slp, error, \ 219 &info.nmi_mreq, &info.nmi_mb); \ 220 if (info.nmi_mrep != NULL) { \ 221 m_freem(info.nmi_mrep); \ 222 info.nmi_mrep = NULL; \ 223 } \ 224 *mrq = info.nmi_mreq; \ 225 if (error && (!(nfsd->nd_flag & ND_NFSV3) || error == EBADRPC)) \ 226 return(0); \ 227 } 228 229 #define nfsm_writereply(s, v3) { \ 230 nfsd->nd_repstat = error; \ 231 if (error && !(v3)) \ 232 (void) nfs_rephead(0, nfsd, slp, error, &info.nmi_mreq, \ 233 &info.nmi_mb); \ 234 else \ 235 (void) nfs_rephead((s), nfsd, slp, error, &info.nmi_mreq, \ 236 &info.nmi_mb); \ 237 } 238 239 #define nfsm_adv(s) { \ 240 t1 = mtod(info.nmi_md, caddr_t) + info.nmi_md->m_len - \ 241 info.nmi_dpos; \ 242 if (t1 >= (s)) { \ 243 info.nmi_dpos += (s); \ 244 } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos, \ 245 (s), t1)) != 0) { \ 246 error = t1; \ 247 m_freem(info.nmi_mrep); \ 248 goto nfsmout; \ 249 } \ 250 } 251 252 #define nfsm_srvmtofh(f) { \ 253 if (nfsd->nd_flag & ND_NFSV3) { \ 254 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ 255 if (fxdr_unsigned(int, *tl) != NFSX_V3FH) { \ 256 error = EBADRPC; \ 257 nfsm_reply(0); \ 258 } \ 259 } \ 260 nfsm_dissect(tl, u_int32_t *, NFSX_V3FH); \ 261 bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \ 262 if ((nfsd->nd_flag & ND_NFSV3) == 0) \ 263 nfsm_adv(NFSX_V2FH - NFSX_V3FH); \ 264 } 265 266 #endif 267