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:
yamt 2003-06-09 13:10:31 +00:00
parent 789329a94f
commit 9c329a66d1
4 changed files with 62 additions and 66 deletions

View File

@ -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)

View File

@ -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;
}
/*

View File

@ -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 *,

View File

@ -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), \