summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1996-07-16 10:19:45 +0000
committerdfr <dfr@FreeBSD.org>1996-07-16 10:19:45 +0000
commit90a643ddb4048ff6bfea37ed866b1d890d6e177f (patch)
treec09adb4e15413a694fad7e62a52249b526659ec7
parent96a4925288045b01e89e5fad53384551ec332380 (diff)
downloadFreeBSD-src-90a643ddb4048ff6bfea37ed866b1d890d6e177f.zip
FreeBSD-src-90a643ddb4048ff6bfea37ed866b1d890d6e177f.tar.gz
Various fixes from frank@fwi.uva.nl (Frank van der Linden) via
rick@snowhite.cis.uoguelph.ca: 1. Clear B_NEEDCOMMIT in nfs_write to make sure that dirty data is correctly send to the server. If a buffer was dirtied when it was in the B_DELWRI+B_NEEDCOMMIT state, the state of the buffer was left unchanged and when the buffer was later cleaned, just a commit rpc was made to the server to complete the previous write. Clearing B_NEEDCOMMIT ensures that another write is made to the server. 2. If a server returned a server (for whatever reason) returned an answer to a write RPC that implied that fewer bytes than requested were written, bad things would happen. 3. The setattr operation passed on the atime in stead of the mtime to the server. The fix is trivial. 4. XIDs always started at 0, but this caused some servers (older DEC OSF/1 3.0 so I've been told) who had very long-lasting XID caches to get confused if, after a reboot of a BSD client, RPCs came in with a XID that had in the past been used before from that client. Patch is to use the current time in seconds as a starting point for XIDs. The patch below is not perfect, because it requires the root fs to be mounted first. This is because of the check BSD systems do, comparing FS time to system time. Reviewed by: Bruce Evans, Terry Lambert. Obtained from: frank@fwi.uva.nl (Frank van der Linden) via rick@snowhite.cis.uoguelph.ca
-rw-r--r--sys/nfs/nfs_bio.c9
-rw-r--r--sys/nfs/nfs_common.c35
-rw-r--r--sys/nfs/nfs_subs.c35
-rw-r--r--sys/nfs/nfs_vnops.c4
-rw-r--r--sys/nfsclient/nfs_bio.c9
-rw-r--r--sys/nfsclient/nfs_subs.c35
-rw-r--r--sys/nfsclient/nfs_vnops.c4
-rw-r--r--sys/nfsserver/nfs_srvsubs.c35
8 files changed, 116 insertions, 50 deletions
diff --git a/sys/nfs/nfs_bio.c b/sys/nfs/nfs_bio.c
index b5b7668..d1bb47e 100644
--- a/sys/nfs/nfs_bio.c
+++ b/sys/nfs/nfs_bio.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_bio.c 8.5 (Berkeley) 1/4/94
- * $Id: nfs_bio.c,v 1.22 1996/01/24 18:52:18 mpp Exp $
+ * $Id: nfs_bio.c,v 1.23 1996/06/08 05:59:04 pst Exp $
*/
#include <sys/param.h>
@@ -584,6 +584,13 @@ again:
bp->b_validoff = min(bp->b_validoff, bp->b_dirtyoff);
bp->b_validend = max(bp->b_validend, bp->b_dirtyend);
}
+
+ /*
+ * Since this block is being modified, it must be written
+ * again and not just committed.
+ */
+ bp->b_flags &= ~B_NEEDCOMMIT;
+
/*
* If the lease is non-cachable or IO_SYNC do bwrite().
*/
diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c
index 3cf21ad..5288153 100644
--- a/sys/nfs/nfs_common.c
+++ b/sys/nfs/nfs_common.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_subs.c,v 1.29 1996/06/14 11:13:21 phk Exp $
+ * $Id: nfs_subs.c,v 1.30 1996/06/23 17:19:25 bde Exp $
*/
/*
@@ -635,6 +635,8 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
register int i;
struct mbuf *mreq, *mb2;
int siz, grpsiz, authsiz;
+ struct timeval tv;
+ static u_long base;
authsiz = nfsm_rndup(auth_len);
MGETHDR(mb, M_WAIT, MT_DATA);
@@ -653,8 +655,22 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
* First the RPC header.
*/
nfsm_build(tl, u_long *, 8 * NFSX_UNSIGNED);
+
+ /*
+ * derive initial xid from system time
+ * XXX time is invalid if root not yet mounted
+ */
+ if (!base && (rootvp)) {
+ microtime(&tv);
+ base = tv.tv_sec << 12;
+ nfs_xid = base;
+ }
+ /*
+ * Skip zero xid if it should ever happen.
+ */
if (++nfs_xid == 0)
nfs_xid++;
+
*tl++ = *xidp = txdr_unsigned(nfs_xid);
*tl++ = rpc_call;
*tl++ = rpc_vers;
@@ -834,7 +850,8 @@ nfsm_mbuftouio(mrep, uiop, siz, dpos)
}
/*
- * copies a uio scatter/gather list to an mbuf chain...
+ * copies a uio scatter/gather list to an mbuf chain.
+ * NOTE: can ony handle iovcnt == 1
*/
int
nfsm_uiotombuf(uiop, mq, siz, bpos)
@@ -849,6 +866,9 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
int uiosiz, clflg, rem;
char *cp;
+ if (uiop->uio_iovcnt != 1)
+ panic("nfsm_uiotombuf: iovcnt != 1");
+
if (siz > MLEN) /* or should it >= MCLBYTES ?? */
clflg = 1;
else
@@ -856,8 +876,6 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
rem = nfsm_rndup(siz)-siz;
mp = mp2 = *mq;
while (siz > 0) {
- if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL)
- return (EINVAL);
left = uiop->uio_iov->iov_len;
uiocp = uiop->uio_iov->iov_base;
if (left > siz)
@@ -892,13 +910,8 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
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 += uiosiz;
- uiop->uio_iov->iov_len -= uiosiz;
- }
+ uiop->uio_iov->iov_base += uiosiz;
+ uiop->uio_iov->iov_len -= uiosiz;
siz -= uiosiz;
}
if (rem > 0) {
diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c
index 3cf21ad..5288153 100644
--- a/sys/nfs/nfs_subs.c
+++ b/sys/nfs/nfs_subs.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_subs.c,v 1.29 1996/06/14 11:13:21 phk Exp $
+ * $Id: nfs_subs.c,v 1.30 1996/06/23 17:19:25 bde Exp $
*/
/*
@@ -635,6 +635,8 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
register int i;
struct mbuf *mreq, *mb2;
int siz, grpsiz, authsiz;
+ struct timeval tv;
+ static u_long base;
authsiz = nfsm_rndup(auth_len);
MGETHDR(mb, M_WAIT, MT_DATA);
@@ -653,8 +655,22 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
* First the RPC header.
*/
nfsm_build(tl, u_long *, 8 * NFSX_UNSIGNED);
+
+ /*
+ * derive initial xid from system time
+ * XXX time is invalid if root not yet mounted
+ */
+ if (!base && (rootvp)) {
+ microtime(&tv);
+ base = tv.tv_sec << 12;
+ nfs_xid = base;
+ }
+ /*
+ * Skip zero xid if it should ever happen.
+ */
if (++nfs_xid == 0)
nfs_xid++;
+
*tl++ = *xidp = txdr_unsigned(nfs_xid);
*tl++ = rpc_call;
*tl++ = rpc_vers;
@@ -834,7 +850,8 @@ nfsm_mbuftouio(mrep, uiop, siz, dpos)
}
/*
- * copies a uio scatter/gather list to an mbuf chain...
+ * copies a uio scatter/gather list to an mbuf chain.
+ * NOTE: can ony handle iovcnt == 1
*/
int
nfsm_uiotombuf(uiop, mq, siz, bpos)
@@ -849,6 +866,9 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
int uiosiz, clflg, rem;
char *cp;
+ if (uiop->uio_iovcnt != 1)
+ panic("nfsm_uiotombuf: iovcnt != 1");
+
if (siz > MLEN) /* or should it >= MCLBYTES ?? */
clflg = 1;
else
@@ -856,8 +876,6 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
rem = nfsm_rndup(siz)-siz;
mp = mp2 = *mq;
while (siz > 0) {
- if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL)
- return (EINVAL);
left = uiop->uio_iov->iov_len;
uiocp = uiop->uio_iov->iov_base;
if (left > siz)
@@ -892,13 +910,8 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
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 += uiosiz;
- uiop->uio_iov->iov_len -= uiosiz;
- }
+ uiop->uio_iov->iov_base += uiosiz;
+ uiop->uio_iov->iov_len -= uiosiz;
siz -= uiosiz;
}
if (rem > 0) {
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index 8dec9a2..6a56128 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94
- * $Id: nfs_vnops.c,v 1.32 1996/01/24 21:11:26 phk Exp $
+ * $Id: nfs_vnops.c,v 1.33 1996/01/25 00:45:37 bde Exp $
*/
/*
@@ -757,7 +757,7 @@ nfs_setattrrpc(vp, vap, cred, procp)
if (vap->va_mtime.ts_sec != time.tv_sec) {
nfsm_build(tl, u_long *, 3 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);
- txdr_nfsv3time(&vap->va_atime, tl);
+ txdr_nfsv3time(&vap->va_mtime, tl);
} else {
nfsm_build(tl, u_long *, NFSX_UNSIGNED);
*tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER);
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c
index b5b7668..d1bb47e 100644
--- a/sys/nfsclient/nfs_bio.c
+++ b/sys/nfsclient/nfs_bio.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_bio.c 8.5 (Berkeley) 1/4/94
- * $Id: nfs_bio.c,v 1.22 1996/01/24 18:52:18 mpp Exp $
+ * $Id: nfs_bio.c,v 1.23 1996/06/08 05:59:04 pst Exp $
*/
#include <sys/param.h>
@@ -584,6 +584,13 @@ again:
bp->b_validoff = min(bp->b_validoff, bp->b_dirtyoff);
bp->b_validend = max(bp->b_validend, bp->b_dirtyend);
}
+
+ /*
+ * Since this block is being modified, it must be written
+ * again and not just committed.
+ */
+ bp->b_flags &= ~B_NEEDCOMMIT;
+
/*
* If the lease is non-cachable or IO_SYNC do bwrite().
*/
diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c
index 3cf21ad..5288153 100644
--- a/sys/nfsclient/nfs_subs.c
+++ b/sys/nfsclient/nfs_subs.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_subs.c,v 1.29 1996/06/14 11:13:21 phk Exp $
+ * $Id: nfs_subs.c,v 1.30 1996/06/23 17:19:25 bde Exp $
*/
/*
@@ -635,6 +635,8 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
register int i;
struct mbuf *mreq, *mb2;
int siz, grpsiz, authsiz;
+ struct timeval tv;
+ static u_long base;
authsiz = nfsm_rndup(auth_len);
MGETHDR(mb, M_WAIT, MT_DATA);
@@ -653,8 +655,22 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
* First the RPC header.
*/
nfsm_build(tl, u_long *, 8 * NFSX_UNSIGNED);
+
+ /*
+ * derive initial xid from system time
+ * XXX time is invalid if root not yet mounted
+ */
+ if (!base && (rootvp)) {
+ microtime(&tv);
+ base = tv.tv_sec << 12;
+ nfs_xid = base;
+ }
+ /*
+ * Skip zero xid if it should ever happen.
+ */
if (++nfs_xid == 0)
nfs_xid++;
+
*tl++ = *xidp = txdr_unsigned(nfs_xid);
*tl++ = rpc_call;
*tl++ = rpc_vers;
@@ -834,7 +850,8 @@ nfsm_mbuftouio(mrep, uiop, siz, dpos)
}
/*
- * copies a uio scatter/gather list to an mbuf chain...
+ * copies a uio scatter/gather list to an mbuf chain.
+ * NOTE: can ony handle iovcnt == 1
*/
int
nfsm_uiotombuf(uiop, mq, siz, bpos)
@@ -849,6 +866,9 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
int uiosiz, clflg, rem;
char *cp;
+ if (uiop->uio_iovcnt != 1)
+ panic("nfsm_uiotombuf: iovcnt != 1");
+
if (siz > MLEN) /* or should it >= MCLBYTES ?? */
clflg = 1;
else
@@ -856,8 +876,6 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
rem = nfsm_rndup(siz)-siz;
mp = mp2 = *mq;
while (siz > 0) {
- if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL)
- return (EINVAL);
left = uiop->uio_iov->iov_len;
uiocp = uiop->uio_iov->iov_base;
if (left > siz)
@@ -892,13 +910,8 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
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 += uiosiz;
- uiop->uio_iov->iov_len -= uiosiz;
- }
+ uiop->uio_iov->iov_base += uiosiz;
+ uiop->uio_iov->iov_len -= uiosiz;
siz -= uiosiz;
}
if (rem > 0) {
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 8dec9a2..6a56128 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94
- * $Id: nfs_vnops.c,v 1.32 1996/01/24 21:11:26 phk Exp $
+ * $Id: nfs_vnops.c,v 1.33 1996/01/25 00:45:37 bde Exp $
*/
/*
@@ -757,7 +757,7 @@ nfs_setattrrpc(vp, vap, cred, procp)
if (vap->va_mtime.ts_sec != time.tv_sec) {
nfsm_build(tl, u_long *, 3 * NFSX_UNSIGNED);
*tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);
- txdr_nfsv3time(&vap->va_atime, tl);
+ txdr_nfsv3time(&vap->va_mtime, tl);
} else {
nfsm_build(tl, u_long *, NFSX_UNSIGNED);
*tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER);
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
index 3cf21ad..5288153 100644
--- a/sys/nfsserver/nfs_srvsubs.c
+++ b/sys/nfsserver/nfs_srvsubs.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_subs.c,v 1.29 1996/06/14 11:13:21 phk Exp $
+ * $Id: nfs_subs.c,v 1.30 1996/06/23 17:19:25 bde Exp $
*/
/*
@@ -635,6 +635,8 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
register int i;
struct mbuf *mreq, *mb2;
int siz, grpsiz, authsiz;
+ struct timeval tv;
+ static u_long base;
authsiz = nfsm_rndup(auth_len);
MGETHDR(mb, M_WAIT, MT_DATA);
@@ -653,8 +655,22 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
* First the RPC header.
*/
nfsm_build(tl, u_long *, 8 * NFSX_UNSIGNED);
+
+ /*
+ * derive initial xid from system time
+ * XXX time is invalid if root not yet mounted
+ */
+ if (!base && (rootvp)) {
+ microtime(&tv);
+ base = tv.tv_sec << 12;
+ nfs_xid = base;
+ }
+ /*
+ * Skip zero xid if it should ever happen.
+ */
if (++nfs_xid == 0)
nfs_xid++;
+
*tl++ = *xidp = txdr_unsigned(nfs_xid);
*tl++ = rpc_call;
*tl++ = rpc_vers;
@@ -834,7 +850,8 @@ nfsm_mbuftouio(mrep, uiop, siz, dpos)
}
/*
- * copies a uio scatter/gather list to an mbuf chain...
+ * copies a uio scatter/gather list to an mbuf chain.
+ * NOTE: can ony handle iovcnt == 1
*/
int
nfsm_uiotombuf(uiop, mq, siz, bpos)
@@ -849,6 +866,9 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
int uiosiz, clflg, rem;
char *cp;
+ if (uiop->uio_iovcnt != 1)
+ panic("nfsm_uiotombuf: iovcnt != 1");
+
if (siz > MLEN) /* or should it >= MCLBYTES ?? */
clflg = 1;
else
@@ -856,8 +876,6 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
rem = nfsm_rndup(siz)-siz;
mp = mp2 = *mq;
while (siz > 0) {
- if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL)
- return (EINVAL);
left = uiop->uio_iov->iov_len;
uiocp = uiop->uio_iov->iov_base;
if (left > siz)
@@ -892,13 +910,8 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
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 += uiosiz;
- uiop->uio_iov->iov_len -= uiosiz;
- }
+ uiop->uio_iov->iov_base += uiosiz;
+ uiop->uio_iov->iov_len -= uiosiz;
siz -= uiosiz;
}
if (rem > 0) {
OpenPOWER on IntegriCloud