summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/nfs/nfs_subs.c226
-rw-r--r--sys/nfs/nfs_var.h9
-rw-r--r--sys/nfs/nfs_vfsops.c6
-rw-r--r--sys/nfs/nfs_vnops.c47
-rw-r--r--sys/nfs/nfsm_subs.h30
5 files changed, 120 insertions, 198 deletions
diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c
index 7f220727e79..91f6b819d41 100644
--- a/sys/nfs/nfs_subs.c
+++ b/sys/nfs/nfs_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_subs.c,v 1.69 2008/01/06 17:38:23 blambert Exp $ */
+/* $OpenBSD: nfs_subs.c,v 1.70 2008/04/14 13:46:13 blambert Exp $ */
/* $NetBSD: nfs_subs.c,v 1.27.4.3 1996/07/08 20:34:24 jtc Exp $ */
/*
@@ -724,87 +724,97 @@ nfsm_mbuftouio(mrep, uiop, siz, dpos)
}
/*
- * copies a uio scatter/gather list to an mbuf chain.
- * NOTE: can ony handle iovcnt == 1
+ * Copy a uio scatter/gather list to an mbuf chain.
*/
-int
-nfsm_uiotombuf(uiop, mq, siz, bpos)
- struct uio *uiop;
- struct mbuf **mq;
- int siz;
- caddr_t *bpos;
+void
+nfsm_uiotombuf(struct mbuf **mp, struct uio *uiop, size_t len, caddr_t *bposp)
{
- char *uiocp;
- struct mbuf *mp, *mp2;
- int xfer, left, mlen;
- int uiosiz, clflg, rem;
- char *cp;
+ struct mbuf *mb, *mb2;
+ size_t xfer, pad;
-#ifdef DIAGNOSTIC
- if (uiop->uio_iovcnt != 1)
- panic("nfsm_uiotombuf: iovcnt != 1");
-#endif
+ mb = *mp;
- if (siz > MLEN) /* or should it >= MCLBYTES ?? */
- clflg = 1;
- else
- clflg = 0;
- rem = nfsm_rndup(siz)-siz;
- mp = mp2 = *mq;
- 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) {
- MGET(mp, M_WAIT, MT_DATA);
- if (clflg)
- MCLGET(mp, M_WAIT);
- mp->m_len = 0;
- mp2->m_next = 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, mtod(mp, caddr_t)+mp->m_len, xfer);
- else
-#endif
- if (uiop->uio_segflg == UIO_SYSSPACE)
- bcopy(uiocp, mtod(mp, caddr_t)+mp->m_len, xfer);
- else
- copyin(uiocp, mtod(mp, caddr_t)+mp->m_len, xfer);
- mp->m_len += xfer;
- left -= xfer;
- uiocp += xfer;
- uiop->uio_offset += xfer;
- uiop->uio_resid -= xfer;
+ pad = nfsm_padlen(len);
+
+ /* XXX -- the following should be done by the caller */
+ uiop->uio_resid = len;
+ uiop->uio_rw = UIO_WRITE;
+
+ while (len) {
+ xfer = min(len, M_TRAILINGSPACE(mb));
+ uiomove(mb_offset(mb), xfer, uiop);
+ mb->m_len += xfer;
+ len -= xfer;
+ if (len > 0) {
+ MGET(mb2, M_WAIT, MT_DATA);
+ if (len > MINCLSIZE)
+ MCLGET(mb2, M_WAIT);
+ mb2->m_len = 0;
+ mb->m_next = mb2;
+ mb = mb2;
}
- (char *)uiop->uio_iov->iov_base += uiosiz;
- uiop->uio_iov->iov_len -= uiosiz;
- siz -= uiosiz;
}
- if (rem > 0) {
- if (rem > M_TRAILINGSPACE(mp)) {
- MGET(mp, M_WAIT, MT_DATA);
- mp->m_len = 0;
- mp2->m_next = mp;
+
+ if (pad > 0) {
+ if (pad > M_TRAILINGSPACE(mb)) {
+ MGET(mb2, M_WAIT, MT_DATA);
+ mb2->m_len = 0;
+ mb->m_next = mb2;
+ mb = mb2;
}
- cp = mtod(mp, caddr_t)+mp->m_len;
- for (left = 0; left < rem; left++)
- *cp++ = '\0';
- mp->m_len += rem;
- *bpos = cp;
- } else
- *bpos = mtod(mp, caddr_t)+mp->m_len;
- *mq = mp;
- return (0);
+ bzero(mb_offset(mb), pad);
+ mb->m_len += pad;
+ }
+
+ *bposp = mb_offset(mb);
+ *mp = mb;
+}
+
+/*
+ * Copy a buffer to an mbuf chain
+ */
+void
+nfsm_buftombuf(struct mbuf **mp, void *buf, size_t len, caddr_t *bposp)
+{
+ struct iovec iov;
+ struct uio io;
+
+ iov.iov_base = buf;
+ iov.iov_len = len;
+
+ io.uio_iov = &iov;
+ io.uio_iovcnt = 1;
+ io.uio_resid = len;
+ io.uio_segflg = UIO_SYSSPACE;
+ io.uio_rw = UIO_WRITE;
+
+ nfsm_uiotombuf(mp, &io, len, bposp);
+}
+
+/*
+ * Copy a string to an mbuf chain
+ */
+void
+nfsm_strtombuf(struct mbuf **mp, void *str, size_t len, caddr_t *bposp)
+{
+ struct iovec iov[2];
+ struct uio io;
+ uint32_t strlen;
+
+ strlen = txdr_unsigned(len);
+
+ iov[0].iov_base = &strlen;
+ iov[0].iov_len = sizeof(uint32_t);
+ iov[1].iov_base = str;
+ iov[1].iov_len = len;
+
+ io.uio_iov = iov;
+ io.uio_iovcnt = 2;
+ io.uio_resid = sizeof(uint32_t) + len;
+ io.uio_segflg = UIO_SYSSPACE;
+ io.uio_rw = UIO_WRITE;
+
+ nfsm_uiotombuf(mp, &io, io.uio_resid, bposp);
}
/*
@@ -901,72 +911,6 @@ nfs_adv(mdp, dposp, offs, left)
}
/*
- * Copy a string into mbufs for the hard cases...
- */
-int
-nfsm_strtmbuf(mb, bpos, cp, siz)
- struct mbuf **mb;
- char **bpos;
- char *cp;
- long siz;
-{
- struct mbuf *m1 = NULL, *m2;
- long left, xfer, len, tlen;
- u_int32_t *tl;
- int putsize;
-
- putsize = 1;
- m2 = *mb;
- left = M_TRAILINGSPACE(m2);
- if (left > 0) {
- tl = ((u_int32_t *)(*bpos));
- *tl++ = txdr_unsigned(siz);
- putsize = 0;
- left -= NFSX_UNSIGNED;
- m2->m_len += NFSX_UNSIGNED;
- if (left > 0) {
- bcopy(cp, (caddr_t) tl, left);
- siz -= left;
- cp += left;
- m2->m_len += left;
- left = 0;
- }
- }
- /* Loop around adding mbufs */
- while (siz > 0) {
- MGET(m1, M_WAIT, MT_DATA);
- if (siz > MLEN)
- MCLGET(m1, M_WAIT);
- m1->m_len = NFSMSIZ(m1);
- m2->m_next = m1;
- m2 = m1;
- tl = mtod(m1, u_int32_t *);
- tlen = 0;
- if (putsize) {
- *tl++ = txdr_unsigned(siz);
- m1->m_len -= NFSX_UNSIGNED;
- tlen = NFSX_UNSIGNED;
- putsize = 0;
- }
- if (siz < m1->m_len) {
- len = nfsm_rndup(siz);
- xfer = siz;
- if (xfer < len)
- *(tl+(xfer>>2)) = 0;
- } else {
- xfer = len = m1->m_len;
- }
- bcopy(cp, (caddr_t) tl, xfer);
- m1->m_len = len+tlen;
- siz -= xfer;
- cp += xfer;
- }
- *mb = m1;
- *bpos = mtod(m1, caddr_t)+m1->m_len;
- return (0);
-}
-
-/*
* Called once to initialize data structures...
*/
void
diff --git a/sys/nfs/nfs_var.h b/sys/nfs/nfs_var.h
index 54bf6ecc2bd..49c51d80fb6 100644
--- a/sys/nfs/nfs_var.h
+++ b/sys/nfs/nfs_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_var.h,v 1.33 2008/01/06 17:38:23 blambert Exp $ */
+/* $OpenBSD: nfs_var.h,v 1.34 2008/04/14 13:46:13 blambert Exp $ */
/* $NetBSD: nfs_var.h,v 1.3 1996/02/18 11:53:54 fvdl Exp $ */
/*
@@ -241,7 +241,9 @@ struct mbuf *nfsm_reqh(struct vnode *, u_long, int, caddr_t *);
void nfsm_rpchead(struct nfsreq *, struct ucred *, int, struct mbuf *, int);
void *nfsm_build(struct mbuf **, u_int, caddr_t *);
int nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *);
-int nfsm_uiotombuf(struct uio *, struct mbuf **, int, caddr_t *);
+void nfsm_uiotombuf(struct mbuf **, struct uio *, size_t, caddr_t *);
+void nfsm_strtombuf(struct mbuf **, void *, size_t, caddr_t *);
+void nfsm_buftombuf(struct mbuf **, void *, size_t, caddr_t *);
int nfsm_disct(struct mbuf **, caddr_t *, int, int, caddr_t *);
int nfs_adv(struct mbuf **, caddr_t *, int, int);
int nfsm_strtmbuf(struct mbuf **, char **, char *, long);
@@ -289,3 +291,6 @@ void nfs_getset_niothreads(int);
/* nfs_kq.c */
int nfs_kqfilter(void *);
+/* Internal NFS utility macros */
+#define mb_offset(m) (mtod((m), caddr_t) + (m)->m_len)
+#define nfsm_padlen(s) (nfsm_rndup(s) - (s))
diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c
index a04ca7f69fe..04071d5e9b6 100644
--- a/sys/nfs/nfs_vfsops.c
+++ b/sys/nfs/nfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vfsops.c,v 1.70 2008/03/16 19:42:57 otto Exp $ */
+/* $OpenBSD: nfs_vfsops.c,v 1.71 2008/04/14 13:46:13 blambert Exp $ */
/* $NetBSD: nfs_vfsops.c,v 1.46.4.1 1996/05/25 22:40:35 fvdl Exp $ */
/*
@@ -112,7 +112,7 @@ nfs_statfs(mp, sbp, p)
struct nfs_statfs *sfp = NULL;
caddr_t cp;
u_int32_t *tl;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
struct nfsmount *nmp = VFSTONFS(mp);
int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr;
@@ -186,7 +186,7 @@ nfs_fsinfo(nmp, vp, cred, p)
{
struct nfsv3_fsinfo *fsp;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
u_int32_t *tl, pref, max;
caddr_t bpos, dpos, cp2;
int error = 0, retattr;
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index 393230a1afc..ba5ab6612f7 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vnops.c,v 1.80 2008/01/06 17:38:23 blambert Exp $ */
+/* $OpenBSD: nfs_vnops.c,v 1.81 2008/04/14 13:46:13 blambert Exp $ */
/* $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $ */
/*
@@ -220,7 +220,7 @@ nfs_access(v)
struct vnode *vp = ap->a_vp;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
int error = 0, attrflag;
struct mbuf *mreq, *mrep, *md, *mb;
@@ -432,8 +432,7 @@ nfs_getattr(v)
struct vnode *vp = ap->a_vp;
struct nfsnode *np = VTONFS(vp);
caddr_t cp;
- u_int32_t *tl;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos;
int error = 0;
struct mbuf *mreq, *mrep, *md, *mb;
@@ -552,7 +551,7 @@ nfs_setattrrpc(vp, vap, cred, procp)
{
struct nfsv2_sattr *sp;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
u_int32_t *tl;
int error = 0, wccflag = NFSV3_WCCRATTR;
@@ -612,7 +611,7 @@ nfs_lookup(v)
struct vnode *newvp;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
struct nfsmount *nmp;
caddr_t bpos, dpos, cp2;
struct mbuf *mreq, *mrep, *md, *mb;
@@ -896,7 +895,7 @@ nfs_readlinkrpc(vp, uiop, cred)
{
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
int error = 0, len, attrflag;
struct mbuf *mreq, *mrep, *md, *mb;
@@ -928,7 +927,7 @@ nfs_readrpc(vp, uiop)
{
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
struct mbuf *mreq, *mrep, *md, *mb;
struct nfsmount *nmp;
@@ -993,7 +992,7 @@ nfs_writerpc(vp, uiop, iomode, must_commit)
{
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2, backup;
+ int32_t t1, backup;
caddr_t bpos, dpos, cp2;
struct mbuf *mreq, *mrep, *md, *mb;
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
@@ -1034,11 +1033,7 @@ nfs_writerpc(vp, uiop, iomode, must_commit)
*tl = x; /* size of this write */
}
- if ((t1 = nfsm_uiotombuf(uiop, &mb, len, &bpos)) != 0) {
- error = t1;
- m_freem(mreq);
- goto nfsmout;
- }
+ nfsm_uiotombuf(&mb, uiop, len, &bpos);
nfsm_request(vp, NFSPROC_WRITE, uiop->uio_procp,
VTONFS(vp)->n_wcred);
if (v3) {
@@ -1110,7 +1105,7 @@ nfs_mknodrpc(dvp, vpp, cnp, vap)
struct nfsv2_sattr *sp;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
struct vnode *newvp = (struct vnode *)0;
struct nfsnode *np;
char *cp2;
@@ -1223,7 +1218,7 @@ nfs_create(v)
struct nfsv2_sattr *sp;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
struct nfsnode *np = (struct nfsnode *)0;
struct vnode *newvp = (struct vnode *)0;
caddr_t bpos, dpos, cp2;
@@ -1408,7 +1403,7 @@ nfs_removerpc(dvp, name, namelen, cred, proc)
{
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
int error = 0, wccflag = NFSV3_WCCRATTR;
struct mbuf *mreq, *mrep, *md, *mb;
@@ -1527,7 +1522,7 @@ nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, proc)
{
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR;
struct mbuf *mreq, *mrep, *md, *mb;
@@ -1570,7 +1565,7 @@ nfs_link(v)
struct componentname *cnp = ap->a_cnp;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0;
struct mbuf *mreq, *mrep, *md, *mb;
@@ -1638,7 +1633,7 @@ nfs_symlink(v)
struct nfsv2_sattr *sp;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp;
struct mbuf *mreq, *mrep, *md, *mb;
@@ -1701,7 +1696,7 @@ nfs_mkdir(v)
struct nfsv2_sattr *sp;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
int len;
struct nfsnode *np = (struct nfsnode *)0;
struct vnode *newvp = (struct vnode *)0;
@@ -1780,7 +1775,7 @@ nfs_rmdir(v)
struct componentname *cnp = ap->a_cnp;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
int error = 0, wccflag = NFSV3_WCCRATTR;
struct mbuf *mreq, *mrep, *md, *mb;
@@ -2005,7 +2000,7 @@ nfs_readdirrpc(struct vnode *vp,
struct dirent *dp = NULL;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
caddr_t bpos, dpos, cp2;
struct mbuf *mreq, *mrep, *md, *mb;
nfsuint64 cookie;
@@ -2189,7 +2184,7 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
struct dirent *dp = NULL;
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
struct vnode *newvp;
caddr_t bpos, dpos, cp2, dpossav1, dpossav2;
struct mbuf *mreq, *mrep, *md, *mb, *mdsav1, *mdsav2;
@@ -2478,7 +2473,7 @@ nfs_lookitup(dvp, name, len, cred, procp, npp)
{
u_int32_t *tl;
caddr_t cp;
- int32_t t1, t2;
+ int32_t t1;
struct vnode *newvp = (struct vnode *)0;
struct nfsnode *np, *dnp = VTONFS(dvp);
caddr_t bpos, dpos, cp2;
@@ -2550,7 +2545,7 @@ nfs_commit(vp, offset, cnt, procp)
{
caddr_t cp;
u_int32_t *tl;
- int32_t t1, t2;
+ int32_t t1;
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
caddr_t bpos, dpos, cp2;
int error = 0, wccflag = NFSV3_WCCRATTR;
diff --git a/sys/nfs/nfsm_subs.h b/sys/nfs/nfsm_subs.h
index 14adbdb552e..cf5b20223f7 100644
--- a/sys/nfs/nfsm_subs.h
+++ b/sys/nfs/nfsm_subs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfsm_subs.h,v 1.24 2008/01/06 17:38:23 blambert Exp $ */
+/* $OpenBSD: nfsm_subs.h,v 1.25 2008/04/14 13:46:13 blambert Exp $ */
/* $NetBSD: nfsm_subs.h,v 1.10 1996/03/20 21:59:56 fvdl Exp $ */
/*
@@ -83,20 +83,8 @@
#define nfsm_fhtom(v, v3) \
{ if (v3) { \
- t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \
- if (t2 <= M_TRAILINGSPACE(mb)) { \
- tl = nfsm_build(&mb, t2, &bpos); \
- *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \
- *(tl + ((t2>>2) - 2)) = 0; \
- bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
- VTONFS(v)->n_fhsize); \
- } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \
- (caddr_t)VTONFS(v)->n_fhp, \
- VTONFS(v)->n_fhsize)) != 0) { \
- error = t2; \
- m_freem(mreq); \
- goto nfsmout; \
- } \
+ nfsm_strtombuf(&mb, VTONFS(v)->n_fhp, \
+ VTONFS(v)->n_fhsize, &bpos); \
} else { \
cp = nfsm_build(&mb, NFSX_V2FH, &bpos); \
bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \
@@ -256,17 +244,7 @@
error = ENAMETOOLONG; \
goto nfsmout; \
} \
- t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
- if (t2 <= M_TRAILINGSPACE(mb)) { \
- tl = nfsm_build(&mb, t2, &bpos); \
- *tl++ = txdr_unsigned(s); \
- *(tl+((t2>>2)-2)) = 0; \
- bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
- } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \
- error = t2; \
- m_freem(mreq); \
- goto nfsmout; \
- }
+ nfsm_strtombuf(&mb, (a), (s), &bpos)
#define nfsm_reply(s) \
{ \