diff options
author | mohans <mohans@FreeBSD.org> | 2006-08-29 22:00:12 +0000 |
---|---|---|
committer | mohans <mohans@FreeBSD.org> | 2006-08-29 22:00:12 +0000 |
commit | 0b0d785f6a435dc88471b7af543291d29dc979e6 (patch) | |
tree | 5afe600ab3188731682a99d4a67baf8a5f7198df /sys/nfsclient | |
parent | 94a898c189056277d3ef70dc45bf61e092d120fb (diff) | |
download | FreeBSD-src-0b0d785f6a435dc88471b7af543291d29dc979e6.zip FreeBSD-src-0b0d785f6a435dc88471b7af543291d29dc979e6.tar.gz |
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.
Found by : Kris Kennaway
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/nfs_socket.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index 3df174e..9634dd6 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -1372,8 +1372,20 @@ nfs_timer(void *arg) if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) { mtx_unlock(&rep->r_mtx); continue; - } else - mtx_unlock(&rep->r_mtx); + } 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); + mtx_unlock(&rep->r_mtx); + continue; + } + mtx_unlock(&rep->r_mtx); + } if (nfs_sigintr(nmp, rep, rep->r_td)) continue; mtx_lock(&nmp->nm_mtx); |