master
  1/*-
  2 * SPDX-License-Identifier: BSD-3-Clause
  3 *
  4 * Copyright (c) 1989, 1993
  5 *	The Regents of the University of California.  All rights reserved.
  6 *
  7 * This code is derived from software contributed to Berkeley by
  8 * Rick Macklem at The University of Guelph.
  9 *
 10 * Redistribution and use in source and binary forms, with or without
 11 * modification, are permitted provided that the following conditions
 12 * are met:
 13 * 1. Redistributions of source code must retain the above copyright
 14 *    notice, this list of conditions and the following disclaimer.
 15 * 2. Redistributions in binary form must reproduce the above copyright
 16 *    notice, this list of conditions and the following disclaimer in the
 17 *    documentation and/or other materials provided with the distribution.
 18 * 3. Neither the name of the University nor the names of its contributors
 19 *    may be used to endorse or promote products derived from this software
 20 *    without specific prior written permission.
 21 *
 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 32 * SUCH DAMAGE.
 33 */
 34
 35#ifndef _NFS_NFSM_SUBS_H_
 36#define	_NFS_NFSM_SUBS_H_
 37
 38/*
 39 * These macros do strange and peculiar things to mbuf chains for
 40 * the assistance of the nfs code. To attempt to use them for any
 41 * other purpose will be dangerous. (they make weird assumptions)
 42 */
 43
 44/*
 45 * First define what the actual subs. return
 46 */
 47#define	NFSM_DATAP(m, s)	(m)->m_data += (s)
 48
 49/*
 50 * Now for the macros that do the simple stuff and call the functions
 51 * for the hard stuff.
 52 * They use fields in struct nfsrv_descript to handle the mbuf queues.
 53 * Replace most of the macro with an inline function, to minimize
 54 * the machine code. The inline functions in lower case can be called
 55 * directly, bypassing the macro.
 56 */
 57static __inline void *
 58nfsm_build(struct nfsrv_descript *nd, int siz)
 59{
 60	void *retp;
 61	struct mbuf *mb2;
 62
 63	if ((nd->nd_flag & ND_EXTPG) == 0 &&
 64	    siz > M_TRAILINGSPACE(nd->nd_mb)) {
 65		NFSMCLGET(mb2, M_NOWAIT);
 66		if (siz > MLEN)
 67			panic("build > MLEN");
 68		mb2->m_len = 0;
 69		nd->nd_bpos = mtod(mb2, char *);
 70		nd->nd_mb->m_next = mb2;
 71		nd->nd_mb = mb2;
 72	} else if ((nd->nd_flag & ND_EXTPG) != 0) {
 73		if (siz > nd->nd_bextpgsiz) {
 74			mb2 = mb_alloc_ext_plus_pages(PAGE_SIZE, M_WAITOK);
 75			nd->nd_bpos = (char *)(void *)
 76			    PHYS_TO_DMAP(mb2->m_epg_pa[0]);
 77			nd->nd_bextpg = 0;
 78			nd->nd_bextpgsiz = PAGE_SIZE - siz;
 79			nd->nd_mb->m_next = mb2;
 80			nd->nd_mb = mb2;
 81		} else
 82			nd->nd_bextpgsiz -= siz;
 83		nd->nd_mb->m_epg_last_len += siz;
 84	}
 85	retp = (void *)(nd->nd_bpos);
 86	nd->nd_mb->m_len += siz;
 87	nd->nd_bpos += siz;
 88	return (retp);
 89}
 90
 91#define	NFSM_BUILD(a, c, s)	((a) = (c)nfsm_build(nd, (s)))
 92
 93static __inline void *
 94nfsm_dissect(struct nfsrv_descript *nd, int siz)
 95{
 96	int tt1; 
 97	void *retp;
 98
 99	tt1 = mtod(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos; 
100	if (tt1 >= siz) { 
101		retp = (void *)nd->nd_dpos; 
102		nd->nd_dpos += siz; 
103	} else { 
104		retp = nfsm_dissct(nd, siz, M_WAITOK); 
105	}
106	return (retp);
107}
108
109static __inline void *
110nfsm_dissect_nonblock(struct nfsrv_descript *nd, int siz)
111{
112	int tt1; 
113	void *retp;
114
115	tt1 = mtod(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos; 
116	if (tt1 >= siz) { 
117		retp = (void *)nd->nd_dpos; 
118		nd->nd_dpos += siz; 
119	} else { 
120		retp = nfsm_dissct(nd, siz, M_NOWAIT); 
121	}
122	return (retp);
123}
124
125#define	NFSM_DISSECT(a, c, s) 						\
126	do {								\
127		(a) = (c)nfsm_dissect(nd, (s));	 			\
128		if ((a) == NULL) { 					\
129			error = EBADRPC; 				\
130			goto nfsmout; 					\
131		}							\
132	} while (0)
133
134#define	NFSM_DISSECT_NONBLOCK(a, c, s) 					\
135	do {								\
136		(a) = (c)nfsm_dissect_nonblock(nd, (s));		\
137		if ((a) == NULL) { 					\
138			error = EBADRPC; 				\
139			goto nfsmout; 					\
140		}							\
141	} while (0)
142
143#define	NFSM_STRSIZ(s, m)  						\
144	do {								\
145		tl = (u_int32_t *)nfsm_dissect(nd, NFSX_UNSIGNED);	\
146		if (!tl || ((s) = fxdr_unsigned(int32_t, *tl)) > (m)) { \
147			error = EBADRPC; 				\
148			goto nfsmout; 					\
149		}							\
150	} while (0)
151
152#define	NFSM_RNDUP(a)	(((a)+3)&(~0x3))
153
154#endif	/* _NFS_NFSM_SUBS_H_ */