rework zero padding of rpc reply.
- for READ procedure, don't send back more bytes than requested. - don't have doubtful assumptions on mbuf chain structure. - rename a function (nfsm_adj -> nfs_zeropad) to avoid confusion as the semantics of the function was changed.
This commit is contained in:
parent
789329a94f
commit
9c329a66d1
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs_serv.c,v 1.75 2003/05/29 15:18:14 yamt Exp $ */
|
||||
/* $NetBSD: nfs_serv.c,v 1.76 2003/06/09 13:10:31 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -59,7 +59,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.75 2003/05/29 15:18:14 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.76 2003/06/09 13:10:31 yamt Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -484,7 +484,8 @@ nfsrv_readlink(nfsd, slp, procp, mrq)
|
||||
u_int32_t *tl;
|
||||
int32_t t1;
|
||||
caddr_t bpos;
|
||||
int error = 0, rdonly, cache, i, tlen, len, getret;
|
||||
int error = 0, rdonly, cache, i, padlen, getret;
|
||||
uint32_t len;
|
||||
int v3 = (nfsd->nd_flag & ND_NFSV3);
|
||||
char *cp2;
|
||||
struct mbuf *mb, *mp2 = NULL, *mp3 = NULL, *mreq;
|
||||
@ -555,11 +556,10 @@ out:
|
||||
if (error)
|
||||
return (0);
|
||||
}
|
||||
if (uiop->uio_resid > 0) {
|
||||
len -= uiop->uio_resid;
|
||||
tlen = nfsm_rndup(len);
|
||||
nfsm_adj(mp3, NFS_MAXPATHLEN-tlen, tlen-len);
|
||||
}
|
||||
len -= uiop->uio_resid;
|
||||
padlen = nfsm_padlen(len);
|
||||
if (uiop->uio_resid || padlen)
|
||||
nfs_zeropad(mp3, uiop->uio_resid, padlen);
|
||||
nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
*tl = txdr_unsigned(len);
|
||||
mb->m_next = mp3;
|
||||
@ -595,7 +595,8 @@ nfsrv_read(nfsd, slp, procp, mrq)
|
||||
caddr_t bpos;
|
||||
int error = 0, rdonly, cache, getret;
|
||||
int v3 = (nfsd->nd_flag & ND_NFSV3);
|
||||
uint32_t reqlen, len, cnt, left, tlen;
|
||||
uint32_t reqlen, len, cnt, left;
|
||||
int padlen;
|
||||
char *cp2;
|
||||
struct mbuf *mb, *mreq;
|
||||
struct vnode *vp;
|
||||
@ -648,7 +649,7 @@ nfsrv_read(nfsd, slp, procp, mrq)
|
||||
if (off >= va.va_size)
|
||||
cnt = 0;
|
||||
else if ((off + reqlen) > va.va_size)
|
||||
cnt = nfsm_rndup(va.va_size - off);
|
||||
cnt = va.va_size - off;
|
||||
else
|
||||
cnt = reqlen;
|
||||
nfsm_reply(NFSX_POSTOPORFATTR(v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt));
|
||||
@ -817,9 +818,9 @@ read_error:
|
||||
vput(vp);
|
||||
nfsm_srvfillattr(&va, fp);
|
||||
len -= uiop->uio_resid;
|
||||
tlen = nfsm_rndup(len);
|
||||
if (cnt != tlen || tlen != len)
|
||||
nfsm_adj(mb, (int)cnt - tlen, tlen - len);
|
||||
padlen = nfsm_padlen(len);
|
||||
if (uiop->uio_resid || padlen)
|
||||
nfs_zeropad(mb, uiop->uio_resid, padlen);
|
||||
if (v3) {
|
||||
*tl++ = txdr_unsigned(len);
|
||||
if (len < reqlen)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs_subs.c,v 1.121 2003/05/22 14:16:23 yamt Exp $ */
|
||||
/* $NetBSD: nfs_subs.c,v 1.122 2003/06/09 13:10:31 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -74,7 +74,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.121 2003/05/22 14:16:23 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.122 2003/06/09 13:10:31 yamt Exp $");
|
||||
|
||||
#include "fs_nfs.h"
|
||||
#include "opt_nfs.h"
|
||||
@ -2137,9 +2137,12 @@ out:
|
||||
/*
|
||||
* A fiddled version of m_adj() that ensures null fill to a 32-bit
|
||||
* boundary and only trims off the back end
|
||||
*
|
||||
* 1. trim off 'len' bytes as m_adj(mp, -len).
|
||||
* 2. add zero-padding 'nul' bytes at the end of the mbuf chain.
|
||||
*/
|
||||
void
|
||||
nfsm_adj(mp, len, nul)
|
||||
nfs_zeropad(mp, len, nul)
|
||||
struct mbuf *mp;
|
||||
int len;
|
||||
int nul;
|
||||
@ -2159,65 +2162,56 @@ nfsm_adj(mp, len, nul)
|
||||
m = mp;
|
||||
for (;;) {
|
||||
count += m->m_len;
|
||||
if (m->m_next == (struct mbuf *)0)
|
||||
if (m->m_next == NULL)
|
||||
break;
|
||||
m = m->m_next;
|
||||
}
|
||||
if (m->m_len > len) {
|
||||
|
||||
KDASSERT(count >= len);
|
||||
|
||||
if (m->m_len >= len) {
|
||||
m->m_len -= len;
|
||||
if (nul > 0) {
|
||||
if (M_ROMAP(m)) {
|
||||
struct mbuf *n;
|
||||
|
||||
KDASSERT(MLEN >= nul);
|
||||
n = m_get(M_WAIT, MT_DATA);
|
||||
MCLAIM(n, &nfs_mowner);
|
||||
n->m_len = nul;
|
||||
n->m_next = m->m_next;
|
||||
m->m_len -= nul;
|
||||
m->m_next = n;
|
||||
m = n;
|
||||
} else {
|
||||
count -= len;
|
||||
/*
|
||||
* Correct length for chain is "count".
|
||||
* Find the mbuf with last data, adjust its length,
|
||||
* and toss data from remaining mbufs on chain.
|
||||
*/
|
||||
for (m = mp; m; m = m->m_next) {
|
||||
if (m->m_len >= count) {
|
||||
m->m_len = count;
|
||||
break;
|
||||
}
|
||||
cp = mtod(m, caddr_t)+m->m_len-nul;
|
||||
for (i = 0; i < nul; i++)
|
||||
*cp++ = '\0';
|
||||
count -= m->m_len;
|
||||
}
|
||||
return;
|
||||
m_freem(m->m_next);
|
||||
m->m_next = NULL;
|
||||
}
|
||||
count -= len;
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
|
||||
/*
|
||||
* Correct length for chain is "count".
|
||||
* Find the mbuf with last data, adjust its length,
|
||||
* and toss data from remaining mbufs on chain.
|
||||
* zero-padding.
|
||||
*/
|
||||
for (m = mp; m; m = m->m_next) {
|
||||
if (m->m_len >= count) {
|
||||
m->m_len = count;
|
||||
if (nul > 0) {
|
||||
if (M_ROMAP(m)) {
|
||||
struct mbuf *n;
|
||||
if (nul > 0) {
|
||||
if (M_ROMAP(m) || M_TRAILINGSPACE(m) < nul) {
|
||||
struct mbuf *n;
|
||||
|
||||
KDASSERT(MLEN >= nul);
|
||||
n = m_get(M_WAIT, MT_DATA);
|
||||
MCLAIM(n, &nfs_mowner);
|
||||
n->m_len = nul;
|
||||
n->m_next = m->m_next;
|
||||
m->m_len -= nul;
|
||||
m->m_next = n;
|
||||
m = n;
|
||||
}
|
||||
cp = mtod(m, caddr_t)+m->m_len-nul;
|
||||
for (i = 0; i < nul; i++)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
break;
|
||||
KDASSERT(MLEN >= nul);
|
||||
n = m_get(M_WAIT, MT_DATA);
|
||||
MCLAIM(n, &nfs_mowner);
|
||||
n->m_len = nul;
|
||||
n->m_next = m->m_next;
|
||||
m->m_next = n;
|
||||
m = n;
|
||||
cp = mtod(n, caddr_t);
|
||||
} else {
|
||||
cp = mtod(m, caddr_t) + m->m_len;
|
||||
m->m_len += nul;
|
||||
}
|
||||
count -= m->m_len;
|
||||
for (i = 0; i < nul; i++)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
for (m = m->m_next;m;m = m->m_next)
|
||||
m->m_len = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs_var.h,v 1.37 2003/05/22 14:16:24 yamt Exp $ */
|
||||
/* $NetBSD: nfs_var.h,v 1.38 2003/06/09 13:10:32 yamt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
@ -269,7 +269,7 @@ void nfs_delayedtruncate __P((struct vnode *));
|
||||
int nfs_namei __P((struct nameidata *, fhandle_t *, uint32_t,
|
||||
struct nfssvc_sock *, struct mbuf *, struct mbuf **,
|
||||
caddr_t *, struct vnode **, struct proc *, int, int));
|
||||
void nfsm_adj __P((struct mbuf *, int, int));
|
||||
void nfs_zeropad __P((struct mbuf *, int, int));
|
||||
void nfsm_srvwcc __P((struct nfsrv_descript *, int, struct vattr *, int,
|
||||
struct vattr *, struct mbuf **, char **));
|
||||
void nfsm_srvpostopattr __P((struct nfsrv_descript *, int, struct vattr *,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfsm_subs.h,v 1.27 2003/05/06 13:52:36 yamt Exp $ */
|
||||
/* $NetBSD: nfsm_subs.h,v 1.28 2003/06/09 13:10:32 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -333,6 +333,7 @@
|
||||
nfsmout:
|
||||
|
||||
#define nfsm_rndup(a) (((a)+3)&(~0x3))
|
||||
#define nfsm_padlen(a) (nfsm_rndup(a) - (a))
|
||||
|
||||
#define nfsm_request(v, t, p, c) \
|
||||
if ((error = nfs_request((v), mreq, (t), (p), \
|
||||
|
Loading…
Reference in New Issue
Block a user