diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2011-04-17 23:04:03 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2011-04-17 23:04:03 +0000 |
commit | 0ee1980af426bbfd0aab1067520e1fbb6a684bb5 (patch) | |
tree | 637c5bc4c2228307f7ec70c8828756accbd78417 /sys/fs/nfsclient | |
parent | 91c215d2a6a56a18db8c626d8f4180a499162ce2 (diff) | |
download | FreeBSD-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.c | 5 | ||||
-rw-r--r-- | sys/fs/nfsclient/nfs_clstate.c | 4 | ||||
-rw-r--r-- | sys/fs/nfsclient/nfs_clvfsops.c | 4 |
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. */ |