DragonFly commits List (threaded) for 2004-03
cvs commit: src/sys/vfs/nfs nfs.h nfs_socket.c
dillon 2004/03/12 19:13:53 PST
DragonFly src repository
sys/vfs/nfs nfs.h nfs_socket.c
Fix a bunch of NFS races. These races existed in FreeBSD 4.x but are more
likely to occur now due to the additional thread switching that DragonFly
performs when doing things like sending UDP packets. Three bugs are
* nfs_request() adds the request to the nfs_timer queue before doing initial
processing (e.g. transmission) of the request. The initial transmission of
the request will race between nfs_request and nfs_timer, potentially causing
the congestion window calculation (nm_sent) to be bumped twice instead of
once. This eventually closes the congestion window permanently and
causes the NFS mount to freeze. (Additionally the request could be
transmitted twice unnecessarily, also fixed).
* Updates to rep->r_flags and nmp->nm_sent were not being properly protected
against nfs_timer due to splsoftclock() being released too early. All
such accesses are now protected.
* nfs_reply() depends on nfs_rcvlock to do an interlock check to see if the
request has already been replied, but nfs_rcvlock() only does this if it
cannot immediately get the receiver lock. The problem is that the NFS
code in between request transmission and nfs_reply() can block, potentially
allowing a reply to be returned to another nfsiod. The NFS receiver winds
up getting stuck waiting for a reply that has already been returned.
nfs_rcvlock() now unconditionally checks to see if the reply has already
occured before entering the loop.
Revision Changes Path
1.6 +9 -8 src/sys/vfs/nfs/nfs.h
1.14 +37 -14 src/sys/vfs/nfs/nfs_socket.c