From owner-freebsd-current@FreeBSD.ORG Tue Apr 20 13:14:05 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B339B16A4CE for ; Tue, 20 Apr 2004 13:14:05 -0700 (PDT) Received: from root.org (root.org [67.118.192.226]) by mx1.FreeBSD.org (Postfix) with SMTP id 8058743D53 for ; Tue, 20 Apr 2004 13:14:05 -0700 (PDT) (envelope-from nate@root.org) Received: (qmail 30938 invoked by uid 1000); 20 Apr 2004 20:14:06 -0000 Date: Tue, 20 Apr 2004 13:14:06 -0700 (PDT) From: Nate Lawson To: current@freebsd.org Message-ID: <20040420131312.T30850@root.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Subject: NFS fix from DragonFly X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Apr 2004 20:14:05 -0000 Curious if we should address this? dillon 2004/03/12 19:13:53 PST DragonFly src repository Modified files: sys/vfs/nfs nfs.h nfs_socket.c Log: 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 being fixed: * 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 http://www.dragonflybsd.org/cvsweb/src/sys/vfs/nfs/nfs.h.diff?r1=1.5&r2=1.6&f=h http://www.dragonflybsd.org/cvsweb/src/sys/vfs/nfs/nfs_socket.c.diff?r1=1.13&r2=1.14&f=h