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	NFSM_DATAP(m, s)	(m)->m_data += (s)
50191783Srmacklem
51191783Srmacklem/*
52191783Srmacklem * Now for the macros that do the simple stuff and call the functions
53191783Srmacklem * for the hard stuff.
54191783Srmacklem * They use fields in struct nfsrv_descript to handle the mbuf queues.
55191783Srmacklem * Replace most of the macro with an inline function, to minimize
56191783Srmacklem * the machine code. The inline functions in lower case can be called
57191783Srmacklem * directly, bypassing the macro.
58191783Srmacklem */
59191783Srmacklemstatic __inline void *
60191783Srmacklemnfsm_build(struct nfsrv_descript *nd, int siz)
61191783Srmacklem{
62191783Srmacklem	void *retp;
63191783Srmacklem	struct mbuf *mb2;
64191783Srmacklem
65191783Srmacklem	if (siz > M_TRAILINGSPACE(nd->nd_mb)) {
66243882Sglebius		NFSMCLGET(mb2, M_NOWAIT);
67191783Srmacklem		if (siz > MLEN)
68191783Srmacklem			panic("build > MLEN");
69191783Srmacklem		mbuf_setlen(mb2, 0);
70191783Srmacklem		nd->nd_bpos = NFSMTOD(mb2, caddr_t);
71191783Srmacklem		nd->nd_mb->m_next = mb2;
72191783Srmacklem		nd->nd_mb = mb2;
73191783Srmacklem	}
74191783Srmacklem	retp = (void *)(nd->nd_bpos);
75191783Srmacklem	nd->nd_mb->m_len += siz;
76191783Srmacklem	nd->nd_bpos += siz;
77191783Srmacklem	return (retp);
78191783Srmacklem}
79191783Srmacklem
80191783Srmacklem#define	NFSM_BUILD(a, c, s)	((a) = (c)nfsm_build(nd, (s)))
81191783Srmacklem
82191783Srmacklemstatic __inline void *
83191783Srmacklemnfsm_dissect(struct nfsrv_descript *nd, int siz)
84191783Srmacklem{
85191783Srmacklem	int tt1;
86191783Srmacklem	void *retp;
87191783Srmacklem
88191783Srmacklem	tt1 = NFSMTOD(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos;
89191783Srmacklem	if (tt1 >= siz) {
90191783Srmacklem		retp = (void *)nd->nd_dpos;
91191783Srmacklem		nd->nd_dpos += siz;
92191783Srmacklem	} else {
93249592Sken		retp = nfsm_dissct(nd, siz, M_WAITOK);
94191783Srmacklem	}
95191783Srmacklem	return (retp);
96191783Srmacklem}
97191783Srmacklem
98249592Skenstatic __inline void *
99249592Skennfsm_dissect_nonblock(struct nfsrv_descript *nd, int siz)
100249592Sken{
101249592Sken	int tt1;
102249592Sken	void *retp;
103249592Sken
104249592Sken	tt1 = NFSMTOD(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos;
105249592Sken	if (tt1 >= siz) {
106249592Sken		retp = (void *)nd->nd_dpos;
107249592Sken		nd->nd_dpos += siz;
108249592Sken	} else {
109249592Sken		retp = nfsm_dissct(nd, siz, M_NOWAIT);
110249592Sken	}
111249592Sken	return (retp);
112249592Sken}
113249592Sken
114191783Srmacklem#define	NFSM_DISSECT(a, c, s) 						\
115191783Srmacklem	do {								\
116191783Srmacklem		(a) = (c)nfsm_dissect(nd, (s));	 			\
117191783Srmacklem		if ((a) == NULL) { 					\
118191783Srmacklem			error = EBADRPC; 				\
119191783Srmacklem			goto nfsmout; 					\
120191783Srmacklem		}							\
121191783Srmacklem	} while (0)
122249592Sken
123249592Sken#define	NFSM_DISSECT_NONBLOCK(a, c, s) 					\
124249592Sken	do {								\
125249592Sken		(a) = (c)nfsm_dissect_nonblock(nd, (s));		\
126249592Sken		if ((a) == NULL) { 					\
127249592Sken			error = EBADRPC; 				\
128249592Sken			goto nfsmout; 					\
129249592Sken		}							\
130249592Sken	} while (0)
131191783Srmacklem#endif	/* !APPLE */
132191783Srmacklem
133191783Srmacklem#define	NFSM_STRSIZ(s, m)  						\
134191783Srmacklem	do {								\
135191783Srmacklem		tl = (u_int32_t *)nfsm_dissect(nd, NFSX_UNSIGNED);	\
136191783Srmacklem		if (!tl || ((s) = fxdr_unsigned(int32_t, *tl)) > (m)) { \
137191783Srmacklem			error = EBADRPC; 				\
138191783Srmacklem			goto nfsmout; 					\
139191783Srmacklem		}							\
140191783Srmacklem	} while (0)
141191783Srmacklem
142191783Srmacklem#define	NFSM_RNDUP(a)	(((a)+3)&(~0x3))
143191783Srmacklem
144191783Srmacklem#endif	/* _NFS_NFSM_SUBS_H_ */
145