1191783Srmacklem/*-
2191783Srmacklem * Copyright (c) 1989, 1993
3191783Srmacklem *	The Regents of the University of California.  All rights reserved.
4191783Srmacklem *
5191783Srmacklem * This code is derived from software contributed to Berkeley by
6191783Srmacklem * Rick Macklem at The University of Guelph.
7191783Srmacklem *
8191783Srmacklem * Redistribution and use in source and binary forms, with or without
9191783Srmacklem * modification, are permitted provided that the following conditions
10191783Srmacklem * are met:
11191783Srmacklem * 1. Redistributions of source code must retain the above copyright
12191783Srmacklem *    notice, this list of conditions and the following disclaimer.
13191783Srmacklem * 2. Redistributions in binary form must reproduce the above copyright
14191783Srmacklem *    notice, this list of conditions and the following disclaimer in the
15191783Srmacklem *    documentation and/or other materials provided with the distribution.
16191783Srmacklem * 4. Neither the name of the University nor the names of its contributors
17191783Srmacklem *    may be used to endorse or promote products derived from this software
18191783Srmacklem *    without specific prior written permission.
19191783Srmacklem *
20191783Srmacklem * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21191783Srmacklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22191783Srmacklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23191783Srmacklem * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24191783Srmacklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25191783Srmacklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26191783Srmacklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27191783Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28191783Srmacklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29191783Srmacklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30191783Srmacklem * SUCH DAMAGE.
31191783Srmacklem *
32191783Srmacklem * $FreeBSD$
33191783Srmacklem */
34191783Srmacklem
35191783Srmacklem#ifndef _NFS_NFSM_SUBS_H_
36191783Srmacklem#define	_NFS_NFSM_SUBS_H_
37191783Srmacklem
38191783Srmacklem
39191783Srmacklem/*
40191783Srmacklem * These macros do strange and peculiar things to mbuf chains for
41191783Srmacklem * the assistance of the nfs code. To attempt to use them for any
42191783Srmacklem * other purpose will be dangerous. (they make weird assumptions)
43191783Srmacklem */
44191783Srmacklem
45191783Srmacklem#ifndef APPLE
46191783Srmacklem/*
47191783Srmacklem * First define what the actual subs. return
48191783Srmacklem */
49191783Srmacklem#define	M_HASCL(m)	((m)->m_flags & M_EXT)
50191783Srmacklem#define	NFSMINOFF(m) 							\
51191783Srmacklem		if (M_HASCL(m)) 					\
52191783Srmacklem			(m)->m_data = (m)->m_ext.ext_buf; 		\
53191783Srmacklem		else if ((m)->m_flags & M_PKTHDR) 			\
54191783Srmacklem			(m)->m_data = (m)->m_pktdat; 			\
55191783Srmacklem				else 					\
56191783Srmacklem			(m)->m_data = (m)->m_dat
57191783Srmacklem#define	NFSMSIZ(m)	((M_HASCL(m))?MCLBYTES: 			\
58191783Srmacklem				(((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
59191783Srmacklem#define	NFSM_DATAP(m, s)	(m)->m_data += (s)
60191783Srmacklem
61191783Srmacklem/*
62191783Srmacklem * Now for the macros that do the simple stuff and call the functions
63191783Srmacklem * for the hard stuff.
64191783Srmacklem * They use fields in struct nfsrv_descript to handle the mbuf queues.
65191783Srmacklem * Replace most of the macro with an inline function, to minimize
66191783Srmacklem * the machine code. The inline functions in lower case can be called
67191783Srmacklem * directly, bypassing the macro.
68191783Srmacklem */
69191783Srmacklemstatic __inline void *
70191783Srmacklemnfsm_build(struct nfsrv_descript *nd, int siz)
71191783Srmacklem{
72191783Srmacklem	void *retp;
73191783Srmacklem	struct mbuf *mb2;
74191783Srmacklem
75191783Srmacklem	if (siz > M_TRAILINGSPACE(nd->nd_mb)) {
76191783Srmacklem		NFSMCLGET(mb2, M_DONTWAIT);
77191783Srmacklem		if (siz > MLEN)
78191783Srmacklem			panic("build > MLEN");
79191783Srmacklem		mbuf_setlen(mb2, 0);
80191783Srmacklem		nd->nd_bpos = NFSMTOD(mb2, caddr_t);
81191783Srmacklem		nd->nd_mb->m_next = mb2;
82191783Srmacklem		nd->nd_mb = mb2;
83191783Srmacklem	}
84191783Srmacklem	retp = (void *)(nd->nd_bpos);
85191783Srmacklem	nd->nd_mb->m_len += siz;
86191783Srmacklem	nd->nd_bpos += siz;
87191783Srmacklem	return (retp);
88191783Srmacklem}
89191783Srmacklem
90191783Srmacklem#define	NFSM_BUILD(a, c, s)	((a) = (c)nfsm_build(nd, (s)))
91191783Srmacklem
92191783Srmacklemstatic __inline void *
93191783Srmacklemnfsm_dissect(struct nfsrv_descript *nd, int siz)
94191783Srmacklem{
95191783Srmacklem	int tt1;
96191783Srmacklem	void *retp;
97191783Srmacklem
98191783Srmacklem	tt1 = NFSMTOD(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos;
99191783Srmacklem	if (tt1 >= siz) {
100191783Srmacklem		retp = (void *)nd->nd_dpos;
101191783Srmacklem		nd->nd_dpos += siz;
102191783Srmacklem	} else {
103251641Sken		retp = nfsm_dissct(nd, siz, M_WAITOK);
104191783Srmacklem	}
105191783Srmacklem	return (retp);
106191783Srmacklem}
107191783Srmacklem
108251641Skenstatic __inline void *
109251641Skennfsm_dissect_nonblock(struct nfsrv_descript *nd, int siz)
110251641Sken{
111251641Sken	int tt1;
112251641Sken	void *retp;
113251641Sken
114251641Sken	tt1 = NFSMTOD(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos;
115251641Sken	if (tt1 >= siz) {
116251641Sken		retp = (void *)nd->nd_dpos;
117251641Sken		nd->nd_dpos += siz;
118251641Sken	} else {
119251641Sken		retp = nfsm_dissct(nd, siz, M_NOWAIT);
120251641Sken	}
121251641Sken	return (retp);
122251641Sken}
123251641Sken
124191783Srmacklem#define	NFSM_DISSECT(a, c, s) 						\
125191783Srmacklem	do {								\
126191783Srmacklem		(a) = (c)nfsm_dissect(nd, (s));	 			\
127191783Srmacklem		if ((a) == NULL) { 					\
128191783Srmacklem			error = EBADRPC; 				\
129191783Srmacklem			goto nfsmout; 					\
130191783Srmacklem		}							\
131191783Srmacklem	} while (0)
132251641Sken
133251641Sken#define	NFSM_DISSECT_NONBLOCK(a, c, s) 					\
134251641Sken	do {								\
135251641Sken		(a) = (c)nfsm_dissect_nonblock(nd, (s));		\
136251641Sken		if ((a) == NULL) { 					\
137251641Sken			error = EBADRPC; 				\
138251641Sken			goto nfsmout; 					\
139251641Sken		}							\
140251641Sken	} while (0)
141191783Srmacklem#endif	/* !APPLE */
142191783Srmacklem
143191783Srmacklem#define	NFSM_STRSIZ(s, m)  						\
144191783Srmacklem	do {								\
145191783Srmacklem		tl = (u_int32_t *)nfsm_dissect(nd, NFSX_UNSIGNED);	\
146191783Srmacklem		if (!tl || ((s) = fxdr_unsigned(int32_t, *tl)) > (m)) { \
147191783Srmacklem			error = EBADRPC; 				\
148191783Srmacklem			goto nfsmout; 					\
149191783Srmacklem		}							\
150191783Srmacklem	} while (0)
151191783Srmacklem
152191783Srmacklem#define	NFSM_RNDUP(a)	(((a)+3)&(~0x3))
153191783Srmacklem
154191783Srmacklem#endif	/* _NFS_NFSM_SUBS_H_ */
155