Ejemplo n.º 1
0
/*
 * Help break down an mbuf chain by setting the first siz bytes contiguous
 * pointed to by returned val.
 * This is used by the macro NFSM_DISSECT for tough
 * cases.
 */
APPLESTATIC void *
nfsm_dissct(struct nfsrv_descript *nd, int siz, int how)
{
	mbuf_t mp2;
	int siz2, xfer;
	caddr_t p;
	int left;
	caddr_t retp;

	retp = NULL;
	left = NFSMTOD(nd->nd_md, caddr_t) + mbuf_len(nd->nd_md) - nd->nd_dpos;
	while (left == 0) {
		nd->nd_md = mbuf_next(nd->nd_md);
		if (nd->nd_md == NULL)
			return (retp);
		left = mbuf_len(nd->nd_md);
		nd->nd_dpos = NFSMTOD(nd->nd_md, caddr_t);
	}
	if (left >= siz) {
		retp = nd->nd_dpos;
		nd->nd_dpos += siz;
	} else if (mbuf_next(nd->nd_md) == NULL) {
		return (retp);
	} else if (siz > ncl_mbuf_mhlen) {
		panic("nfs S too big");
	} else {
		MGET(mp2, MT_DATA, how);
		if (mp2 == NULL)
			return (NULL);
		mbuf_setnext(mp2, mbuf_next(nd->nd_md));
		mbuf_setnext(nd->nd_md, mp2);
		mbuf_setlen(nd->nd_md, mbuf_len(nd->nd_md) - left);
		nd->nd_md = mp2;
		retp = p = NFSMTOD(mp2, caddr_t);
		NFSBCOPY(nd->nd_dpos, p, left);	/* Copy what was left */
		siz2 = siz - left;
		p += left;
		mp2 = mbuf_next(mp2);
		/* Loop around copying up the siz2 bytes */
		while (siz2 > 0) {
			if (mp2 == NULL)
				return (NULL);
			xfer = (siz2 > mbuf_len(mp2)) ? mbuf_len(mp2) : siz2;
			if (xfer > 0) {
				NFSBCOPY(NFSMTOD(mp2, caddr_t), p, xfer);
				NFSM_DATAP(mp2, xfer);
				mbuf_setlen(mp2, mbuf_len(mp2) - xfer);
				p += xfer;
				siz2 -= xfer;
			}
			if (siz2 > 0)
				mp2 = mbuf_next(mp2);
		}
		mbuf_setlen(nd->nd_md, siz);
		nd->nd_md = mp2;
		nd->nd_dpos = NFSMTOD(mp2, caddr_t);
	}
	return (retp);
}
Ejemplo n.º 2
0
/*
 * Copy a string into mbuf(s).
 * Return the number of bytes output, including XDR overheads.
 */
APPLESTATIC int
nfsm_strtom(struct nfsrv_descript *nd, const char *cp, int siz)
{
	mbuf_t m2;
	int xfer, left;
	mbuf_t m1;
	int rem, bytesize;
	u_int32_t *tl;
	char *cp2;

	NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
	*tl = txdr_unsigned(siz);
	rem = NFSM_RNDUP(siz) - siz;
	bytesize = NFSX_UNSIGNED + siz + rem;
	m2 = nd->nd_mb;
	cp2 = nd->nd_bpos;
	left = M_TRAILINGSPACE(m2);

	/*
	 * Loop around copying the string to mbuf(s).
	 */
	while (siz > 0) {
		if (left == 0) {
			if (siz > ncl_mbuf_mlen)
				NFSMCLGET(m1, M_WAITOK);
			else
				NFSMGET(m1);
			mbuf_setlen(m1, 0);
			mbuf_setnext(m2, m1);
			m2 = m1;
			cp2 = NFSMTOD(m2, caddr_t);
			left = M_TRAILINGSPACE(m2);
		}
		if (left >= siz)
			xfer = siz;
		else
			xfer = left;
		NFSBCOPY(cp, cp2, xfer);
		cp += xfer;
		mbuf_setlen(m2, mbuf_len(m2) + xfer);
		siz -= xfer;
		left -= xfer;
		if (siz == 0 && rem) {
			if (left < rem)
				panic("nfsm_strtom");
			NFSBZERO(cp2 + xfer, rem);
			mbuf_setlen(m2, mbuf_len(m2) + rem);
		}
	}
	nd->nd_mb = m2;
	nd->nd_bpos = NFSMTOD(m2, caddr_t) + mbuf_len(m2);
	return (bytesize);
}
Ejemplo n.º 3
0
/*
 * Advance the position in the mbuf chain.
 * If offs == 0, this is a no-op, but it is simpler to just return from
 * here than check for offs > 0 for all calls to nfsm_advance.
 * If left == -1, it should be calculated here.
 */
APPLESTATIC int
nfsm_advance(struct nfsrv_descript *nd, int offs, int left)
{
	int error = 0;

	if (offs == 0)
		goto out;
	/*
	 * A negative offs should be considered a serious problem.
	 */
	if (offs < 0)
		panic("nfsrv_advance");

	/*
	 * If left == -1, calculate it here.
	 */
	if (left == -1)
		left = NFSMTOD(nd->nd_md, caddr_t) + mbuf_len(nd->nd_md) -
		    nd->nd_dpos;

	/*
	 * Loop around, advancing over the mbuf data.
	 */
	while (offs > left) {
		offs -= left;
		nd->nd_md = mbuf_next(nd->nd_md);
		if (nd->nd_md == NULL) {
			error = EBADRPC;
			goto out;
		}
		left = mbuf_len(nd->nd_md);
		nd->nd_dpos = NFSMTOD(nd->nd_md, caddr_t);
	}
	nd->nd_dpos += offs;

out:
	NFSEXITCODE(error);
	return (error);
}
Ejemplo n.º 4
0
/*
 * copies a uio scatter/gather list to an mbuf chain.
 * NOTE: can ony handle iovcnt == 1
 */
APPLESTATIC void
nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *uiop, int siz)
{
	char *uiocp;
	struct mbuf *mp, *mp2;
	int xfer, left, mlen;
	int uiosiz, clflg, rem;
	char *cp, *tcp;

	KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1"));

	if (siz > ncl_mbuf_mlen)	/* or should it >= MCLBYTES ?? */
		clflg = 1;
	else
		clflg = 0;
	rem = NFSM_RNDUP(siz) - siz;
	mp = mp2 = nd->nd_mb;
	while (siz > 0) {
		left = uiop->uio_iov->iov_len;
		uiocp = uiop->uio_iov->iov_base;
		if (left > siz)
			left = siz;
		uiosiz = left;
		while (left > 0) {
			mlen = M_TRAILINGSPACE(mp);
			if (mlen == 0) {
				if (clflg)
					NFSMCLGET(mp, M_WAITOK);
				else
					NFSMGET(mp);
				mbuf_setlen(mp, 0);
				mbuf_setnext(mp2, mp);
				mp2 = mp;
				mlen = M_TRAILINGSPACE(mp);
			}
			xfer = (left > mlen) ? mlen : left;
#ifdef notdef
			/* Not Yet.. */
			if (uiop->uio_iov->iov_op != NULL)
				(*(uiop->uio_iov->iov_op))
				(uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
				    xfer);
			else
#endif
			if (uiop->uio_segflg == UIO_SYSSPACE)
			    NFSBCOPY(uiocp, NFSMTOD(mp, caddr_t) + mbuf_len(mp),
				xfer);
			else
			    copyin(CAST_USER_ADDR_T(uiocp), NFSMTOD(mp, caddr_t)
				+ mbuf_len(mp), xfer);
			mbuf_setlen(mp, mbuf_len(mp) + xfer);
			left -= xfer;
			uiocp += xfer;
			uiop->uio_offset += xfer;
			uiop->uio_resid -= xfer;
		}
		tcp = (char *)uiop->uio_iov->iov_base;
		tcp += uiosiz;
		uiop->uio_iov->iov_base = (void *)tcp;
		uiop->uio_iov->iov_len -= uiosiz;
		siz -= uiosiz;
	}
	if (rem > 0) {
		if (rem > M_TRAILINGSPACE(mp)) {
			NFSMGET(mp);
			mbuf_setlen(mp, 0);
			mbuf_setnext(mp2, mp);
		}
		cp = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
		for (left = 0; left < rem; left++)
			*cp++ = '\0';
		mbuf_setlen(mp, mbuf_len(mp) + rem);
		nd->nd_bpos = cp;
	} else
		nd->nd_bpos = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
	nd->nd_mb = mp;
}
Ejemplo n.º 5
0
/*
 * copies a uio scatter/gather list to an mbuf chain.
 * This version returns the mbuf list and does not use "nd".
 * NOTE: can ony handle iovcnt == 1
 */
struct mbuf *
nfsm_uiombuflist(struct uio *uiop, int siz, struct mbuf **mbp, char **cpp)
{
	char *uiocp;
	struct mbuf *mp, *mp2, *firstmp;
	int xfer, left, mlen;
	int uiosiz, clflg;
	char *tcp;

	KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1"));

	if (siz > ncl_mbuf_mlen)	/* or should it >= MCLBYTES ?? */
		clflg = 1;
	else
		clflg = 0;
	if (clflg != 0)
		NFSMCLGET(mp, M_WAITOK);
	else
		NFSMGET(mp);
	mbuf_setlen(mp, 0);
	firstmp = mp2 = mp;
	while (siz > 0) {
		left = uiop->uio_iov->iov_len;
		uiocp = uiop->uio_iov->iov_base;
		if (left > siz)
			left = siz;
		uiosiz = left;
		while (left > 0) {
			mlen = M_TRAILINGSPACE(mp);
			if (mlen == 0) {
				if (clflg)
					NFSMCLGET(mp, M_WAITOK);
				else
					NFSMGET(mp);
				mbuf_setlen(mp, 0);
				mbuf_setnext(mp2, mp);
				mp2 = mp;
				mlen = M_TRAILINGSPACE(mp);
			}
			xfer = (left > mlen) ? mlen : left;
			if (uiop->uio_segflg == UIO_SYSSPACE)
				NFSBCOPY(uiocp, NFSMTOD(mp, caddr_t) +
				    mbuf_len(mp), xfer);
			else
				copyin(uiocp, NFSMTOD(mp, caddr_t) +
				    mbuf_len(mp), xfer);
			mbuf_setlen(mp, mbuf_len(mp) + xfer);
			left -= xfer;
			uiocp += xfer;
			uiop->uio_offset += xfer;
			uiop->uio_resid -= xfer;
		}
		tcp = (char *)uiop->uio_iov->iov_base;
		tcp += uiosiz;
		uiop->uio_iov->iov_base = (void *)tcp;
		uiop->uio_iov->iov_len -= uiosiz;
		siz -= uiosiz;
	}
	if (cpp != NULL)
		*cpp = NFSMTOD(mp, caddr_t) + mbuf_len(mp);
	if (mbp != NULL)
		*mbp = mp;
	return (firstmp);
}
Ejemplo n.º 6
0
/*
 * copies mbuf chain to the uio scatter/gather list
 */
int
nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *uiop, int siz)
{
	char *mbufcp, *uiocp;
	int xfer, left, len;
	mbuf_t mp;
	long uiosiz, rem;
	int error = 0;

	mp = nd->nd_md;
	mbufcp = nd->nd_dpos;
	len = NFSMTOD(mp, caddr_t) + mbuf_len(mp) - mbufcp;
	rem = NFSM_RNDUP(siz) - siz;
	while (siz > 0) {
		if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL) {
			error = EBADRPC;
			goto out;
		}
		left = uiop->uio_iov->iov_len;
		uiocp = uiop->uio_iov->iov_base;
		if (left > siz)
			left = siz;
		uiosiz = left;
		while (left > 0) {
			while (len == 0) {
				mp = mbuf_next(mp);
				if (mp == NULL) {
					error = EBADRPC;
					goto out;
				}
				mbufcp = NFSMTOD(mp, caddr_t);
				len = mbuf_len(mp);
				KASSERT(len >= 0,
				    ("len %d, corrupted mbuf?", len));
			}
			xfer = (left > len) ? len : left;
#ifdef notdef
			/* Not Yet.. */
			if (uiop->uio_iov->iov_op != NULL)
				(*(uiop->uio_iov->iov_op))
				(mbufcp, uiocp, xfer);
			else
#endif
			if (uiop->uio_segflg == UIO_SYSSPACE)
				NFSBCOPY(mbufcp, uiocp, xfer);
			else
				copyout(mbufcp, CAST_USER_ADDR_T(uiocp), xfer);
			left -= xfer;
			len -= xfer;
			mbufcp += xfer;
			uiocp += xfer;
			uiop->uio_offset += xfer;
			uiop->uio_resid -= xfer;
		}
		if (uiop->uio_iov->iov_len <= siz) {
			uiop->uio_iovcnt--;
			uiop->uio_iov++;
		} else {
			uiop->uio_iov->iov_base = (void *)
				((char *)uiop->uio_iov->iov_base + uiosiz);
			uiop->uio_iov->iov_len -= uiosiz;
		}
		siz -= uiosiz;
	}
	nd->nd_dpos = mbufcp;
	nd->nd_md = mp;
	if (rem > 0) {
		if (len < rem)
			error = nfsm_advance(nd, rem, len);
		else
			nd->nd_dpos += rem;
	}

out:
	NFSEXITCODE2(error, nd);
	return (error);
}