On Thu, Mar 06, 2008 at 09:49:48AM -0800, David O'Brien wrote: > On Tue, Aug 29, 2006 at 10:00:12PM +0000, Mohan Srinivasan wrote: > > mohans 2006-08-29 22:00:12 UTC > > FreeBSD src repository > > Modified files: > > sys/nfsclient nfs_socket.c > > Log: > > Fix for a deadlock triggered by a 'umount -f' causing a NFS request to > > never > > retransmit (or return). Thanks to John Baldwin for helping nail this one. > > Revision Changes Path > > 1.144 +14 -2 src/sys/nfsclient/nfs_socket.c > > http://cvsweb.freebsd.org/src/sys/nfsclient/nfs_socket.c.diff?r1=1.143&r2=1.144 > > How does this look for a RELENG_6 version of this fix? > > Index: nfsclient/nfs_socket.c > =================================================================== > RCS file: /home/ncvs/src/sys/nfsclient/nfs_socket.c,v > retrieving revision 1.125.2.18 > diff -u -p -r1.125.2.18 nfs_socket.c > --- nfsclient/nfs_socket.c 17 Jan 2008 21:04:51 -0000 1.125.2.18 > +++ nfsclient/nfs_socket.c 25 Feb 2008 10:26:59 -0000 > @@ -1323,6 +1323,18 @@ nfs_timer(void *arg) > continue; > if (nfs_sigintr(nmp, rep, rep->r_td)) > continue; > + else { > + /* > + * Terminate request if force-unmount in progress. > + * Note that NFS could have vfs_busy'ed the mount, > + * causing the unmount to wait for the mnt_lock, making > + * this bit of logic necessary. > + */ > + if (rep->r_nmp->nm_mountp->mnt_kern_flag & > MNTK_UNMOUNTF) { > + nfs_softterm(rep); > + continue; > + } > + } > if (nmp->nm_tprintf_initial_delay != 0 && > (rep->r_rexmit > 2 || (rep->r_flags & R_RESENDERR)) && > rep->r_lastmsg + nmp->nm_tprintf_delay < now.tv_sec) { > The reason for this change was the rev. 1.180 of the nfs_vfsops.c, that never makes into RELENG_6. NFS client in RELENG_7 is MPsafe and sufficiently reworked.
I think that scenario that leads to that deadlock is: The thread A doing fstatfs() vfs_busy()ed the mountpoint, and then: - unmount (thread B) waits for the mnt_lock; - the request sent by the thread A or response to that request is lost and never retransmitted due to forced umount being performed. This ends up in the deadlock.
pgp6cAUsZgrf5.pgp
Description: PGP signature