diff options
author | mckusick <mckusick@FreeBSD.org> | 1998-09-29 23:15:25 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 1998-09-29 23:15:25 +0000 |
commit | 44e40659a639144e40f811fb2f1462a6fc70f152 (patch) | |
tree | 3bf69fd8442d2444b9001fd5b7b78b11b87f987f /sys/nfs | |
parent | a037faba698d8538a0e264aa9eaff8aa82406084 (diff) | |
download | FreeBSD-src-44e40659a639144e40f811fb2f1462a6fc70f152.zip FreeBSD-src-44e40659a639144e40f811fb2f1462a6fc70f152.tar.gz |
Do not need (or want) to take a reference on an NFS file that
is being deleted due to an forcible unmount. The problem is
that vgone calls vclean() which then calls calls nfs_inactive()
with VXLOCK set on the vnode. Nfs_inactive() was calling vget()
to get a reference on the vnode, which in turn hung on VXLOCK.
Nfs_inactive() now checks v_usecount to make sure that the vnode
is not coming from vclean() before it does a vget().
Diffstat (limited to 'sys/nfs')
-rw-r--r-- | sys/nfs/nfs_node.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/sys/nfs/nfs_node.c b/sys/nfs/nfs_node.c index dc67b36..4c01d6f 100644 --- a/sys/nfs/nfs_node.c +++ b/sys/nfs/nfs_node.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_node.c 8.6 (Berkeley) 5/22/95 - * $Id: nfs_node.c,v 1.26 1998/05/13 07:49:08 peter Exp $ + * $Id: nfs_node.c,v 1.27 1998/05/24 14:41:49 peter Exp $ */ @@ -203,21 +203,27 @@ nfs_inactive(ap) sp = (struct sillyrename *)0; if (sp) { /* - * XXX We need a reference to keep the vnode from being + * We need a reference to keep the vnode from being * recycled by getnewvnode while we do the I/O - * associated with discarding the buffers. + * associated with discarding the buffers unless we + * are being forcibly unmounted in which case we already + * have our own reference. */ - if (vget(ap->a_vp, 0, p)) + if (ap->a_vp->v_usecount > 0) + (void) nfs_vinvalbuf(ap->a_vp, 0, sp->s_cred, p, 1); + else if (vget(ap->a_vp, 0, p)) panic("nfs_inactive: lost vnode"); + else { + (void) nfs_vinvalbuf(ap->a_vp, 0, sp->s_cred, p, 1); + vrele(ap->a_vp); + } /* * Remove the silly file that was rename'd earlier */ - (void) nfs_vinvalbuf(ap->a_vp, 0, sp->s_cred, p, 1); nfs_removeit(sp); crfree(sp->s_cred); vrele(sp->s_dvp); FREE((caddr_t)sp, M_NFSREQ); - vrele(ap->a_vp); /* XXX Undo above reference */ } np->n_flag &= (NMODIFIED | NFLUSHINPROG | NFLUSHWANT | NQNFSEVICTED | NQNFSNONCACHE | NQNFSWRITE); |