Subject: a couple of bug-fixes for nfs
To: None <freebsd-bugs@FreeBSD.org>
From: None <rick@snowhite.cis.uoguelph.ca>
List: netbsd-bugs
Date: 01/09/1995 21:56:09
Hi,
Here are a couple of nfs related bugs/fixes for FreeBSD2.0R. I don't know if
they also apply to -current or NetBSD or any of the other 4.4BSD-Lite based
systems. The first is a missing brelse() call for an uncommon case during
read-ahead and the second fixes two problems with respect to conversion
to/from the nfs v2 time structure handling microseconds.
The diff -c's are for FreeBSD2.0R, so your line numbers may vary. (I have
not tested these fixes that extensively, but they both seem pretty obvious, so..)
Have fun with it, rick
---- diff -c's -----
*** nfs_bio.c.bak Mon Jan 9 15:43:57 1995
--- nfs_bio.c Mon Jan 9 15:45:55 1995
***************
*** 212,232 ****
if (!incore(vp, rabn)) {
rabp = nfs_getcacheblk(vp, rabn, biosize, p);
if (!rabp)
return (EINTR);
if ((rabp->b_flags & (B_DELWRI | B_DONE)) == 0) {
rabp->b_flags |= (B_READ | B_ASYNC);
if (nfs_asyncio(rabp, cred)) {
rabp->b_flags |= B_INVAL;
brelse(rabp);
}
! }
}
}
}
/*
* If the block is in the cache and has the required data
* in a valid region, just copy it out.
* Otherwise, get the block and write back/read in,
* as required.
*/
--- 212,233 ----
if (!incore(vp, rabn)) {
rabp = nfs_getcacheblk(vp, rabn, biosize, p);
if (!rabp)
return (EINTR);
if ((rabp->b_flags & (B_DELWRI | B_DONE)) == 0) {
rabp->b_flags |= (B_READ | B_ASYNC);
if (nfs_asyncio(rabp, cred)) {
rabp->b_flags |= B_INVAL;
brelse(rabp);
}
! } else
! brelse(rabp);
}
}
}
/*
* If the block is in the cache and has the required data
* in a valid region, just copy it out.
* Otherwise, get the block and write back/read in,
* as required.
*/
***************
*** 320,340 ****
rabn != 0 && rabn != np->n_direofoffset &&
!incore(vp, rabn)) {
rabp = nfs_getcacheblk(vp, rabn, NFS_DIRBLKSIZ, p);
if (rabp) {
if ((rabp->b_flags & (B_DONE | B_DELWRI)) == 0) {
rabp->b_flags |= (B_READ | B_ASYNC);
if (nfs_asyncio(rabp, cred)) {
rabp->b_flags |= B_INVAL;
brelse(rabp);
}
! }
}
}
on = 0;
n = min(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid);
got_buf = 1;
break;
default:
printf(" nfsbioread: type %x unexpected\n",vp->v_type);
break;
};
--- 321,342 ----
rabn != 0 && rabn != np->n_direofoffset &&
!incore(vp, rabn)) {
rabp = nfs_getcacheblk(vp, rabn, NFS_DIRBLKSIZ, p);
if (rabp) {
if ((rabp->b_flags & (B_DONE | B_DELWRI)) == 0) {
rabp->b_flags |= (B_READ | B_ASYNC);
if (nfs_asyncio(rabp, cred)) {
rabp->b_flags |= B_INVAL;
brelse(rabp);
}
! } else
! brelse(rabp);
}
}
on = 0;
n = min(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid);
got_buf = 1;
break;
default:
printf(" nfsbioread: type %x unexpected\n",vp->v_type);
break;
};
*** xdr_subs.h.bak Mon Jan 9 16:37:36 1995
--- xdr_subs.h Mon Jan 9 16:39:51 1995
***************
*** 49,73 ****
* machines, and count on them being `#define'd away. Some of these
* might be slightly more efficient as quad_t copies on a big-endian,
* but we cannot count on their alignment anyway.
*/
#define fxdr_unsigned(t, v) ((t)ntohl((long)(v)))
#define txdr_unsigned(v) (htonl((long)(v)))
#define fxdr_nfstime(f, t) { \
(t)->ts_sec = ntohl(((struct nfsv2_time *)(f))->nfs_sec); \
! (t)->ts_nsec = 1000 * ntohl(((struct nfsv2_time *)(f))->nfs_usec); \
}
#define txdr_nfstime(f, t) { \
((struct nfsv2_time *)(t))->nfs_sec = htonl((f)->ts_sec); \
! ((struct nfsv2_time *)(t))->nfs_usec = htonl((f)->ts_nsec) / 1000; \
}
#define fxdr_nqtime(f, t) { \
(t)->ts_sec = ntohl(((struct nqnfs_time *)(f))->nq_sec); \
(t)->ts_nsec = ntohl(((struct nqnfs_time *)(f))->nq_nsec); \
}
#define txdr_nqtime(f, t) { \
((struct nqnfs_time *)(t))->nq_sec = htonl((f)->ts_sec); \
((struct nqnfs_time *)(t))->nq_nsec = htonl((f)->ts_nsec); \
}
--- 49,79 ----
* machines, and count on them being `#define'd away. Some of these
* might be slightly more efficient as quad_t copies on a big-endian,
* but we cannot count on their alignment anyway.
*/
#define fxdr_unsigned(t, v) ((t)ntohl((long)(v)))
#define txdr_unsigned(v) (htonl((long)(v)))
#define fxdr_nfstime(f, t) { \
(t)->ts_sec = ntohl(((struct nfsv2_time *)(f))->nfs_sec); \
! if (((struct nfsv2_time *)(f))->nfs_usec != 0xffffffff) \
! (t)->ts_nsec = 1000 * ntohl(((struct nfsv2_time *)(f))->nfs_usec); \
! else \
! (t)->ts_nsec = -1; \
}
#define txdr_nfstime(f, t) { \
((struct nfsv2_time *)(t))->nfs_sec = htonl((f)->ts_sec); \
! if ((f)->ts_nsec != -1) \
! ((struct nfsv2_time *)(t))->nfs_usec = htonl((f)->ts_nsec / 1000); \
! else \
! ((struct nfsv2_time *)(t))->nfs_usec = 0xffffffff; \
}
#define fxdr_nqtime(f, t) { \
(t)->ts_sec = ntohl(((struct nqnfs_time *)(f))->nq_sec); \
(t)->ts_nsec = ntohl(((struct nqnfs_time *)(f))->nq_nsec); \
}
#define txdr_nqtime(f, t) { \
((struct nqnfs_time *)(t))->nq_sec = htonl((f)->ts_sec); \
((struct nqnfs_time *)(t))->nq_nsec = htonl((f)->ts_nsec); \
}