aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_mount.c
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2013-09-01 23:02:59 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2013-09-01 23:02:59 +0000
commit8fe6bddff703fa63fca6ddb08f5fb8dc6fa31496 (patch)
treed7581118dafcc5b29d5d01d4bb41cb2114a97168 /sys/kern/vfs_mount.c
parent17df25c41c5eb4c3933bc8bc66afc7d28c4cbf78 (diff)
downloadsrc-8fe6bddff703fa63fca6ddb08f5fb8dc6fa31496.tar.gz
src-8fe6bddff703fa63fca6ddb08f5fb8dc6fa31496.zip
Forced dismounts of NFS mounts can fail when thread(s) are stuck
waiting for an RPC reply from the server while holding the mount point busy (mnt_lockref incremented). This happens because dounmount() msleep()s waiting for mnt_lockref to become 0, before calling VFS_UNMOUNT(). This patch adds a new VFS operation called VFS_PURGE(), which the NFS client implements as purging RPCs in progress. Making this call before checking mnt_lockref fixes the problem, by ensuring that the VOP_xxx() calls will fail and unbusy the mount point. Reported by: sbruno Reviewed by: kib MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=255136
Diffstat (limited to 'sys/kern/vfs_mount.c')
-rw-r--r--sys/kern/vfs_mount.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 493bb9888836..8f92e10b69b9 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -1269,8 +1269,16 @@ dounmount(mp, flags, td)
}
mp->mnt_kern_flag |= MNTK_UNMOUNT | MNTK_NOINSMNTQ;
/* Allow filesystems to detect that a forced unmount is in progress. */
- if (flags & MNT_FORCE)
+ if (flags & MNT_FORCE) {
mp->mnt_kern_flag |= MNTK_UNMOUNTF;
+ MNT_IUNLOCK(mp);
+ /*
+ * Must be done after setting MNTK_UNMOUNTF and before
+ * waiting for mnt_lockref to become 0.
+ */
+ VFS_PURGE(mp);
+ MNT_ILOCK(mp);
+ }
error = 0;
if (mp->mnt_lockref) {
mp->mnt_kern_flag |= MNTK_DRAINING;