diff options
author | Rick Macklem <rmacklem@FreeBSD.org> | 2013-09-01 23:02:59 +0000 |
---|---|---|
committer | Rick Macklem <rmacklem@FreeBSD.org> | 2013-09-01 23:02:59 +0000 |
commit | 8fe6bddff703fa63fca6ddb08f5fb8dc6fa31496 (patch) | |
tree | d7581118dafcc5b29d5d01d4bb41cb2114a97168 /sys/kern/vfs_mount.c | |
parent | 17df25c41c5eb4c3933bc8bc66afc7d28c4cbf78 (diff) | |
download | src-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.c | 10 |
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; |