summaryrefslogtreecommitdiffstats
path: root/sys/nfsclient/nfs_vfsops.c
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2002-01-02 00:41:26 +0000
committeriedowse <iedowse@FreeBSD.org>2002-01-02 00:41:26 +0000
commite90d2d4ddf8dc608bc2ee606bbf071a7893023da (patch)
treef9069aa388cb51b8744fafaa7600b9fe830fc575 /sys/nfsclient/nfs_vfsops.c
parentcc0e9cda251fbf87336f271d48a33f8ac7f91f37 (diff)
downloadFreeBSD-src-e90d2d4ddf8dc608bc2ee606bbf071a7893023da.zip
FreeBSD-src-e90d2d4ddf8dc608bc2ee606bbf071a7893023da.tar.gz
Permit NFS filesystems to be forcibly unmounted when the server is
down, even if there are hung processes and the mount is non- interruptible. This works by having nfs_unmount call a new function nfs_nmcancelreqs() in the FORCECLOSE case. It scans the list of outstanding requests and marks as interrupted any requests belonging to the specified mount. Then it waits up to 30 seconds for all requests to terminate. A few other changes are necessary to support this: - Unconditionally set a socket timeout so that even hard mounts are guaranteed to occasionally check the R_SOFTTERM flag on requests. For hard mounts this flag can only be set by nfs_nmcancelreqs(). - Reject requests on a mount that is currently being unmounted. - Never grant the receive lock to a request that has been cancelled. This should also avoid an old problem where a forced NFS unmount could cause a crash; it occurred when a VOP on an unlocked vnode (usually VOP_GETATTR) was in progress at the time of the forced unmount.
Diffstat (limited to 'sys/nfsclient/nfs_vfsops.c')
-rw-r--r--sys/nfsclient/nfs_vfsops.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index 1cd6275..62d412e 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -918,6 +918,12 @@ nfs_unmount(struct mount *mp, int mntflags, struct thread *td)
* - Close the socket
* - Free up the data structures
*/
+ /* In the forced case, cancel any outstanding requests. */
+ if (flags & FORCECLOSE) {
+ error = nfs_nmcancelreqs(nmp);
+ if (error)
+ return (error);
+ }
/* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
error = vflush(mp, 1, flags);
if (error)
OpenPOWER on IntegriCloud