summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfsclient
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2011-04-17 23:04:03 +0000
committerrmacklem <rmacklem@FreeBSD.org>2011-04-17 23:04:03 +0000
commit0ee1980af426bbfd0aab1067520e1fbb6a684bb5 (patch)
tree637c5bc4c2228307f7ec70c8828756accbd78417 /sys/fs/nfsclient
parent91c215d2a6a56a18db8c626d8f4180a499162ce2 (diff)
downloadFreeBSD-src-0ee1980af426bbfd0aab1067520e1fbb6a684bb5.zip
FreeBSD-src-0ee1980af426bbfd0aab1067520e1fbb6a684bb5.tar.gz
Add checks for MNTK_UNMOUNTF at the beginning of three
functions, so that threads don't get stuck in them during a forced dismount. nfs_sync/VFS_SYNC() needs this, since it is called by dounmount() before VFS_UNMOUNT(). The nfscl_nget() case makes sure that a thread doing an VOP_OPEN() or VOP_ADVLOCK() call doesn't get blocked before attempting the RPC. Attempting RPCs don't block, since they all fail once a forced dismount is in progress. The third one at the beginning of nfsrpc_close() is done so threads don't get blocked while doing VOP_INACTIVE() as the vnodes are cleared out. With these three changes plus a change to the umount(1) command so that it doesn't do "sync()" for the forced case seem to make forced dismounts work for the experimental NFS client. MFC after: 2 weeks
Diffstat (limited to 'sys/fs/nfsclient')
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c5
-rw-r--r--sys/fs/nfsclient/nfs_clstate.c4
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c4
3 files changed, 13 insertions, 0 deletions
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 6e4c046..0970064 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -567,6 +567,11 @@ nfsrpc_close(vnode_t vp, int doclose, NFSPROC_T *p)
if (vnode_vtype(vp) != VREG)
return (0);
+
+ /* For forced unmounts, just return. */
+ if ((vp->v_mount->mnt_kern_flag & MNTK_UNMOUNTF) != 0)
+ return (0);
+
if (doclose)
error = nfscl_doclose(vp, &clp, p);
else
diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 8e9aa6a..65427a7 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -692,6 +692,10 @@ nfscl_getcl(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
int igotlock = 0, error, trystalecnt, clidinusedelay, i;
u_int16_t idlen = 0;
+ /* For forced unmounts, just return an error. */
+ if ((vnode_mount(vp)->mnt_kern_flag & MNTK_UNMOUNTF) != 0)
+ return (EPERM);
+
if (cred != NULL) {
getcredhostuuid(cred, uuid, sizeof uuid);
idlen = strlen(uuid);
diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
index a37dd51..8586776 100644
--- a/sys/fs/nfsclient/nfs_clvfsops.c
+++ b/sys/fs/nfsclient/nfs_clvfsops.c
@@ -1386,6 +1386,10 @@ nfs_sync(struct mount *mp, int waitfor)
td = curthread;
+ /* For a forced unmount, just return EPERM. */
+ if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0)
+ return (EPERM);
+
/*
* Force stale buffer cache information to be flushed.
*/
OpenPOWER on IntegriCloud