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
This commit is contained in:
Rick Macklem 2011-04-17 23:04:03 +00:00
parent ed52acf61d
commit be8b35eda7
3 changed files with 13 additions and 0 deletions

View File

@ -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

View File

@ -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);

View File

@ -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.
*/