xref: /original-bsd/sys/nfs/nfsm_subs.h (revision 3839ed90)
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.15 (Berkeley) 03/30/93
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 	if (nfsd->nd_nqlflag == NQL_NOVAL) { \
225 		fp->fa_nfsblocksize = txdr_unsigned(vap->va_blocksize); \
226 		if (vap->va_type == VFIFO) \
227 			fp->fa_nfsrdev = 0xffffffff; \
228 		else \
229 			fp->fa_nfsrdev = txdr_unsigned(vap->va_rdev); \
230 		fp->fa_nfsfsid = txdr_unsigned(vap->va_fsid); \
231 		fp->fa_nfsfileid = txdr_unsigned(vap->va_fileid); \
232 		fp->fa_nfssize = txdr_unsigned(vap->va_size); \
233 		fp->fa_nfsblocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); \
234 		txdr_nfstime(&vap->va_atime, &fp->fa_nfsatime); \
235 		txdr_nfstime(&vap->va_mtime, &fp->fa_nfsmtime); \
236 		fp->fa_nfsctime.nfs_sec = txdr_unsigned(vap->va_ctime.ts_sec); \
237 		fp->fa_nfsctime.nfs_usec = txdr_unsigned(vap->va_gen); \
238 	} else { \
239 		fp->fa_nqblocksize = txdr_unsigned(vap->va_blocksize); \
240 		if (vap->va_type == VFIFO) \
241 			fp->fa_nqrdev = 0xffffffff; \
242 		else \
243 			fp->fa_nqrdev = txdr_unsigned(vap->va_rdev); \
244 		fp->fa_nqfsid = txdr_unsigned(vap->va_fsid); \
245 		fp->fa_nqfileid = txdr_unsigned(vap->va_fileid); \
246 		txdr_hyper(&vap->va_size, &fp->fa_nqsize); \
247 		txdr_hyper(&vap->va_bytes, &fp->fa_nqbytes); \
248 		txdr_nqtime(&vap->va_atime, &fp->fa_nqatime); \
249 		txdr_nqtime(&vap->va_mtime, &fp->fa_nqmtime); \
250 		txdr_nqtime(&vap->va_ctime, &fp->fa_nqctime); \
251 		fp->fa_nqflags = txdr_unsigned(vap->va_flags); \
252 		fp->fa_nqgen = txdr_unsigned(vap->va_gen); \
253 		txdr_hyper(&vap->va_filerev, &fp->fa_nqfilerev); \
254 	}
255 
256