diff options
author | dillon <dillon@FreeBSD.org> | 1999-12-14 19:07:54 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 1999-12-14 19:07:54 +0000 |
commit | 3968ced3f8a2f899bd9f39b2b067f2236d485ce5 (patch) | |
tree | 6751051d6eb810f743e91024499cb430268b96e2 /sys/nfsclient/nfs_node.c | |
parent | 4c83e2cd181003d28cb3352704faaa4cd1acdeff (diff) | |
download | FreeBSD-src-3968ced3f8a2f899bd9f39b2b067f2236d485ce5.zip FreeBSD-src-3968ced3f8a2f899bd9f39b2b067f2236d485ce5.tar.gz |
Fix two problems: First, fix the append seek position race that can
occur due to np->n_size potentially changing if nfs_getcacheblk()
blocks in nfs_write().
Second, under -current we must supply the proper bufsize when obtaining
buffers that straddle the EOF, but due to the fact that np->n_size can
change out from under us it is possible that we may specify the wrong
buffer size and wind up truncating dirty data written by another
process.
Both problems are solved by implementing nfs_rslock(), which allows us
to lock around sensitive buffer cache operations such as those that
occur when appending to a file.
It is believed that this race is responsible for causing dirtyoff/dirtyend
and (in stable) validoff/validend to exceed the buffer size. Therefore
we have now added a warning printf for the dirtyoff/end case in current.
However, we have introduced a new problem which we need to fix at some
point, and that is that soft or intr NFS mounts may become
uninterruptable from the point of view of process A which is stuck waiting
on rslock while process B is stuck doing the rpc. To unstick process A,
process B would have to be interrupted first.
Reviewed by: Alfred Perlstein <bright@wintelcom.net>
Diffstat (limited to 'sys/nfsclient/nfs_node.c')
-rw-r--r-- | sys/nfsclient/nfs_node.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c index 53c73a1..4db6fc2 100644 --- a/sys/nfsclient/nfs_node.c +++ b/sys/nfsclient/nfs_node.c @@ -180,6 +180,7 @@ loop: np->n_fhp = &np->n_fh; bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize); np->n_fhsize = fhsize; + lockinit(&np->n_rslock, PVFS, "nfrslk", 0, LK_NOPAUSE); *npp = np; if (nfs_node_hash_lock < 0) |