summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormohans <mohans@FreeBSD.org>2006-08-29 22:00:12 +0000
committermohans <mohans@FreeBSD.org>2006-08-29 22:00:12 +0000
commit0b0d785f6a435dc88471b7af543291d29dc979e6 (patch)
tree5afe600ab3188731682a99d4a67baf8a5f7198df /sys
parent94a898c189056277d3ef70dc45bf61e092d120fb (diff)
downloadFreeBSD-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')
-rw-r--r--sys/nfsclient/nfs_socket.c16
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);
OpenPOWER on IntegriCloud