summaryrefslogtreecommitdiffstats
path: root/sys/nfs/nfs_node.c
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>1998-09-29 23:15:25 +0000
committermckusick <mckusick@FreeBSD.org>1998-09-29 23:15:25 +0000
commit44e40659a639144e40f811fb2f1462a6fc70f152 (patch)
tree3bf69fd8442d2444b9001fd5b7b78b11b87f987f /sys/nfs/nfs_node.c
parenta037faba698d8538a0e264aa9eaff8aa82406084 (diff)
downloadFreeBSD-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/nfs_node.c')
-rw-r--r--sys/nfs/nfs_node.c18
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);
OpenPOWER on IntegriCloud