From delphij@tarsier.delphij.net  Mon Mar 24 08:07:40 2008
Return-Path: <delphij@tarsier.delphij.net>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 0CEFE1065673;
	Mon, 24 Mar 2008 08:07:40 +0000 (UTC)
	(envelope-from delphij@tarsier.delphij.net)
Received: from tarsier.delphij.net (delphij-pt.tunnel.tserv2.fmt.ipv6.he.net [IPv6:2001:470:1f03:2c9::2])
	by mx1.freebsd.org (Postfix) with ESMTP id 45C308FC12;
	Mon, 24 Mar 2008 08:07:38 +0000 (UTC)
	(envelope-from delphij@tarsier.delphij.net)
Received: from tarsier.geekcn.org (tarsier.geekcn.org [202.108.54.204])
	(using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits))
	(No client certificate requested)
	by tarsier.delphij.net (Postfix) with ESMTPS id 1F2FE284A2;
	Mon, 24 Mar 2008 16:07:37 +0800 (CST)
Received: from localhost (tarsier.geekcn.org [202.108.54.204])
	by tarsier.geekcn.org (Postfix) with ESMTP id E44B1EB71A9;
	Mon, 24 Mar 2008 16:07:36 +0800 (CST)
Received: from tarsier.geekcn.org ([202.108.54.204])
	by localhost (mail.geekcn.org [202.108.54.204]) (amavisd-new, port 10024)
	with ESMTP id RQYbkOpYVEvF; Mon, 24 Mar 2008 16:07:30 +0800 (CST)
Received: from tarsier.delphij.net (tarsier.cn.freebsd.org [202.108.54.205])
	by tarsier.geekcn.org (Postfix) with ESMTP id 6FA20EB3004;
	Mon, 24 Mar 2008 16:07:28 +0800 (CST)
Received: by tarsier.delphij.net (Postfix, from userid 1001)
	id 606CB284A1; Mon, 24 Mar 2008 16:07:28 +0800 (CST)
Message-Id: <20080324080728.606CB284A1@tarsier.delphij.net>
Date: Mon, 24 Mar 2008 16:07:28 +0800 (CST)
From: Xin LI <delphij@FreeBSD.org>
Reply-To: Xin LI <delphij@FreeBSD.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc: kris@FreeBSD.org
Subject: tmpfs: panic: tmpfs_alloc_vp: type 0xc7d2fab0 0
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         122038
>Category:       kern
>Synopsis:       [tmpfs] [panic] tmpfs: panic: tmpfs_alloc_vp: type 0xc7d2fab0 0
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    gleb
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Mar 24 08:10:02 UTC 2008
>Closed-Date:    Fri Mar 15 23:34:49 UTC 2013
>Last-Modified:  Fri Mar 15 23:34:49 UTC 2013
>Originator:     Xin LI
>Release:        FreeBSD 7.0-RELEASE i386
>Organization:
The FreeBSD Project
>Environment:
System: FreeBSD tarsier.delphij.net 7.0-RELEASE FreeBSD 7.0-RELEASE #28: Mon Feb 25 12:28:45 CST 2008 delphij@tarsier.delphij.net:/usr/obj/usr/src/sys/TARSIER i386


>Description:

Note the problem here so we will be able to reference it when it is resolved.

Kris has reported the following backtrace, which seems to be come from
FreeBSD/i386.

Running stress2 in a tmpfs on 8.0.  Unfortunately I can't dump this
machine but will leave it in DDB.

panic: tmpfs_alloc_vp: type 0xc7d2fab0 0
cpuid = 0
KDB: enter: panic
[thread pid 73297 tid 100794 ]
Stopped at      kdb_enter+0x3a: movl    $0,kdb_why
db> wh
Tracing pid 73297 tid 100794 td 0xcd5f9000
kdb_enter(c0a644ff,c0a644ff,c0a5a314,e912e8a0,0,...) at kdb_enter+0x3a
panic(c0a5a314,c7d2fab0,0,16b,118,...) at panic+0x12c
tmpfs_alloc_vp(c6caa520,c7d2fab0,40000,e912eb94,cd5f9000,...) at tmpfs_alloc_vp+0x215
tmpfs_lookup(e912e950,c8303000,e912eba8,c8303000,e912e970,...) at tmpfs_lookup+0x2ae
VOP_CACHEDLOOKUP_APV(c0b125a0,e912e950,e912eba8,e912eb94,c6e8b400,...) at VOP_CACHEDLOOKUP_APV+0xa5
vfs_cache_lookup(e912e9d4,e912e9d4,5200044,c8303000,40000,...) at vfs_cache_lookup+0xd0
VOP_LOOKUP_APV(c0b125a0,e912e9d4,c0a6e8c1,19c,e912eb94,...) at VOP_LOOKUP_APV+0xa5
lookup(e912eb80,c0a6e8c1,c6,bf,c9124d2c,...) at lookup+0x56e
namei(e912eb80,c0c710e0,c0a62d95,e912eaa0,c07623ae,...) at namei+0x34b
vn_open_cred(e912eb80,e912ec78,0,c6e8b400,d8795e38,...) at vn_open_cred+0x2c9
vn_open(e912eb80,e912ec78,0,d8795e38,341f8,...) at vn_open+0x33
kern_open(cd5f9000,2815ff4b,0,1,0,...) at kern_open+0xf2
open(cd5f9000,e912ecfc,c,c161e510,c0b154d8,...) at open+0x30
syscall(e912ed38) at syscall+0x2a3
Xint0x80_syscall() at Xint0x80_syscall+0x20
--- syscall (5, FreeBSD ELF32, open), eip = 0x2814843f, esp = 0xbfbfe80c, ebp = 0xbfbfe898 ---


>How-To-Repeat:
>Fix:

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-fs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Mon May 18 03:05:39 UTC 2009 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=122038 

From: gprspb@mail.ru
To: bug-followup@FreeBSD.org, delphij@FreeBSD.org
Cc:  
Subject: Re: kern/122038: [tmpfs] [panic] tmpfs: panic: tmpfs_alloc_vp:
 type 0xc7d2fab0 0
Date: Wed, 12 Aug 2009 21:47:01 +0400

 This is 100% reproducible on my system with the following commands:
 
 # mkdir -p /tmp/1/2
 # cd /tmp/1/2
 # rm -rf /tmp/1 ; cd ..
 
 Panic String: tmpfs_alloc_vp: type 0xffffff00268b80e0 0
 
 tmpfs on /tmp (tmpfs, local)
 
 FreeBSD gpr.nnz-home.ru 8.0-BETA2 FreeBSD 8.0-BETA2 #0 r196086M: Sat Aug  8 23:53:43 MSD 2009     gpr@gpr.nnz-home.ru:/usr/obj/usr/src/freebsd-head/sys/GPR  amd64
 
 I can make dump or submit additional info if it is necessary.
 

From: Gleb Kurtsou <gleb.kurtsou@gmail.com>
To: bug-followup@FreeBSD.org, delphij@FreeBSD.org, gprspb@mail.ru
Cc: freebsd-fs@FreeBSD.org
Subject: Re: kern/122038: [tmpfs] [panic] tmpfs: panic: tmpfs_alloc_vp:
 type 0xc7d2fab0 0
Date: Sat, 3 Oct 2009 01:23:06 +0300

 --5vNYLRcllDrimb99
 Content-Type: text/plain; charset=utf-8
 Content-Disposition: inline
 
 Could you test following patch. I think it should fix the issue, but it
 seems locking for tn_parent field is missing in some places. It needs a
 closer look and more thorough testing.
 
 
 --5vNYLRcllDrimb99
 Content-Type: text/plain; charset=utf-8
 Content-Disposition: attachment; filename="tmpfs-rmparent.patch.txt"
 
 diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
 index dad634e..2d28058 100644
 --- a/sys/fs/tmpfs/tmpfs_subr.c
 +++ b/sys/fs/tmpfs/tmpfs_subr.c
 @@ -375,6 +375,7 @@ loop:
  		vp->v_op = &tmpfs_fifoop_entries;
  		break;
  	case VDIR:
 +		MPASS(node->tn_dir.tn_parent != NULL);
  		if (node->tn_dir.tn_parent == node)
  			vp->v_vflag |= VV_ROOT;
  		break;
 @@ -653,6 +654,9 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio)
  	TMPFS_VALIDATE_DIR(node);
  	MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT);
  
 +	if (node->tn_dir.tn_parent == NULL)
 +		return ENOENT;
 +
  	dent.d_fileno = node->tn_dir.tn_parent->tn_id;
  	dent.d_type = DT_DIR;
  	dent.d_namlen = 2;
 diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
 index db8ceea..7caac14 100644
 --- a/sys/fs/tmpfs/tmpfs_vnops.c
 +++ b/sys/fs/tmpfs/tmpfs_vnops.c
 @@ -88,6 +88,10 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
  	if (cnp->cn_flags & ISDOTDOT) {
  		int ltype = 0;
  
 +		if (dnode->tn_dir.tn_parent == NULL) {
 +			error = ENOENT;
 +			goto out;
 +		}
  		ltype = VOP_ISLOCKED(dvp);
  		vhold(dvp);
  		VOP_UNLOCK(dvp, 0);
 @@ -98,6 +102,10 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
  		vn_lock(dvp, ltype | LK_RETRY);
  		vdrop(dvp);
  	} else if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
 +		if (dnode->tn_dir.tn_parent == NULL) {
 +			error = ENOENT;
 +			goto out;
 +		}
  		VREF(dvp);
  		*vpp = dvp;
  		error = 0;
 @@ -959,7 +967,8 @@ tmpfs_rename(struct vop_rename_args *v)
  			 * with stale nodes. */
  			n = tdnode;
  			while (n != n->tn_dir.tn_parent) {
 -				if (n == fnode) {
 +				MPASS(n->tn_dir.tn_parent != NULL);
 +				if (n == fnode || n->tn_dir.tn_parent == NULL) {
  					error = EINVAL;
  					if (newname != NULL)
  						    free(newname, M_TMPFSNAME);
 @@ -1112,6 +1121,7 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
  	node->tn_dir.tn_parent->tn_links--;
  	node->tn_dir.tn_parent->tn_status |= TMPFS_NODE_ACCESSED | \
  	    TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED;
 +	node->tn_dir.tn_parent = NULL;
  
  	cache_purge(dvp);
  	cache_purge(vp);
 
 --5vNYLRcllDrimb99--
Responsible-Changed-From-To: freebsd-fs->delphij 
Responsible-Changed-By: delphij 
Responsible-Changed-When: Sun Oct 11 07:04:00 UTC 2009 
Responsible-Changed-Why:  
Take since I have committed a patch from gk@ 

http://www.freebsd.org/cgi/query-pr.cgi?pr=122038 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/122038: commit references a PR
Date: Sun, 11 Oct 2009 07:04:07 +0000 (UTC)

 Author: delphij
 Date: Sun Oct 11 07:03:56 2009
 New Revision: 197953
 URL: http://svn.freebsd.org/changeset/base/197953
 
 Log:
   Add locking around access to parent node, and bail out when the parent
   node is already freed rather than panicking the system.
   
   PR:		kern/122038
   Submitted by:	gk
   Tested by:	pho
   MFC after:	1 week
 
 Modified:
   head/sys/fs/tmpfs/tmpfs.h
   head/sys/fs/tmpfs/tmpfs_subr.c
   head/sys/fs/tmpfs/tmpfs_vnops.c
 
 Modified: head/sys/fs/tmpfs/tmpfs.h
 ==============================================================================
 --- head/sys/fs/tmpfs/tmpfs.h	Sun Oct 11 05:59:43 2009	(r197952)
 +++ head/sys/fs/tmpfs/tmpfs.h	Sun Oct 11 07:03:56 2009	(r197953)
 @@ -303,10 +303,30 @@ LIST_HEAD(tmpfs_node_list, tmpfs_node);
  
  #define TMPFS_NODE_LOCK(node) mtx_lock(&(node)->tn_interlock)
  #define TMPFS_NODE_UNLOCK(node) mtx_unlock(&(node)->tn_interlock)
 -#define        TMPFS_NODE_MTX(node) (&(node)->tn_interlock)
 +#define TMPFS_NODE_MTX(node) (&(node)->tn_interlock)
 +
 +#ifdef INVARIANTS
 +#define TMPFS_ASSERT_LOCKED(node) do {					\
 +		MPASS(node != NULL);					\
 +		MPASS(node->tn_vnode != NULL);				\
 +		if (!VOP_ISLOCKED(node->tn_vnode) &&			\
 +		    !mtx_owned(TMPFS_NODE_MTX(node)))			\
 +			panic("tmpfs: node is not locked: %p", node);	\
 +	} while (0)
 +#define TMPFS_ASSERT_ELOCKED(node) do {					\
 +		MPASS((node) != NULL);					\
 +		MPASS((node)->tn_vnode != NULL);			\
 +		mtx_assert(TMPFS_NODE_MTX(node), MA_OWNED);		\
 +		ASSERT_VOP_LOCKED((node)->tn_vnode, "tmpfs");		\
 +	} while (0)
 +#else
 +#define TMPFS_ASSERT_LOCKED(node) (void)0
 +#define TMPFS_ASSERT_ELOCKED(node) (void)0
 +#endif
  
  #define TMPFS_VNODE_ALLOCATING	1
  #define TMPFS_VNODE_WANT	2
 +#define TMPFS_VNODE_DOOMED	4
  /* --------------------------------------------------------------------- */
  
  /*
 
 Modified: head/sys/fs/tmpfs/tmpfs_subr.c
 ==============================================================================
 --- head/sys/fs/tmpfs/tmpfs_subr.c	Sun Oct 11 05:59:43 2009	(r197952)
 +++ head/sys/fs/tmpfs/tmpfs_subr.c	Sun Oct 11 07:03:56 2009	(r197953)
 @@ -124,7 +124,9 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp
  		nnode->tn_dir.tn_readdir_lastn = 0;
  		nnode->tn_dir.tn_readdir_lastp = NULL;
  		nnode->tn_links++;
 +		TMPFS_NODE_LOCK(nnode->tn_dir.tn_parent);
  		nnode->tn_dir.tn_parent->tn_links++;
 +		TMPFS_NODE_UNLOCK(nnode->tn_dir.tn_parent);
  		break;
  
  	case VFIFO:
 @@ -187,6 +189,7 @@ tmpfs_free_node(struct tmpfs_mount *tmp,
  #ifdef INVARIANTS
  	TMPFS_NODE_LOCK(node);
  	MPASS(node->tn_vnode == NULL);
 +	MPASS((node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0);
  	TMPFS_NODE_UNLOCK(node);
  #endif
  
 @@ -312,6 +315,7 @@ tmpfs_alloc_vp(struct mount *mp, struct 
  loop:
  	TMPFS_NODE_LOCK(node);
  	if ((vp = node->tn_vnode) != NULL) {
 +		MPASS((node->tn_vpstate & TMPFS_VNODE_DOOMED) == 0);
  		VI_LOCK(vp);
  		TMPFS_NODE_UNLOCK(node);
  		vholdl(vp);
 @@ -330,6 +334,14 @@ loop:
  		goto out;
  	}
  
 +	if ((node->tn_vpstate & TMPFS_VNODE_DOOMED) ||
 +	    (node->tn_type == VDIR && node->tn_dir.tn_parent == NULL)) {
 +		TMPFS_NODE_UNLOCK(node);
 +		error = ENOENT;
 +		vp = NULL;
 +		goto out;
 +	}
 +
  	/*
  	 * otherwise lock the vp list while we call getnewvnode
  	 * since that can block.
 @@ -375,6 +387,7 @@ loop:
  		vp->v_op = &tmpfs_fifoop_entries;
  		break;
  	case VDIR:
 +		MPASS(node->tn_dir.tn_parent != NULL);
  		if (node->tn_dir.tn_parent == node)
  			vp->v_vflag |= VV_ROOT;
  		break;
 @@ -428,10 +441,9 @@ tmpfs_free_vp(struct vnode *vp)
  
  	node = VP_TO_TMPFS_NODE(vp);
  
 -	TMPFS_NODE_LOCK(node);
 +	mtx_assert(TMPFS_NODE_MTX(node), MA_OWNED);
  	node->tn_vnode = NULL;
  	vp->v_data = NULL;
 -	TMPFS_NODE_UNLOCK(node);
  }
  
  /* --------------------------------------------------------------------- */
 @@ -653,7 +665,18 @@ tmpfs_dir_getdotdotdent(struct tmpfs_nod
  	TMPFS_VALIDATE_DIR(node);
  	MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT);
  
 +	/*
 +	 * Return ENOENT if the current node is already removed.
 +	 */
 +	TMPFS_ASSERT_LOCKED(node);
 +	if (node->tn_dir.tn_parent == NULL) {
 +		return (ENOENT);
 +	}
 +
 +	TMPFS_NODE_LOCK(node->tn_dir.tn_parent);
  	dent.d_fileno = node->tn_dir.tn_parent->tn_id;
 +	TMPFS_NODE_UNLOCK(node->tn_dir.tn_parent);
 +
  	dent.d_type = DT_DIR;
  	dent.d_namlen = 2;
  	dent.d_name[0] = '.';
 
 Modified: head/sys/fs/tmpfs/tmpfs_vnops.c
 ==============================================================================
 --- head/sys/fs/tmpfs/tmpfs_vnops.c	Sun Oct 11 05:59:43 2009	(r197952)
 +++ head/sys/fs/tmpfs/tmpfs_vnops.c	Sun Oct 11 07:03:56 2009	(r197953)
 @@ -87,6 +87,11 @@ tmpfs_lookup(struct vop_cachedlookup_arg
  	    dnode->tn_dir.tn_parent == dnode,
  	    !(cnp->cn_flags & ISDOTDOT)));
  
 +	TMPFS_ASSERT_LOCKED(dnode);
 +	if (dnode->tn_dir.tn_parent == NULL) {
 +		error = ENOENT;
 +		goto out;
 +	}
  	if (cnp->cn_flags & ISDOTDOT) {
  		int ltype = 0;
  
 @@ -914,6 +919,7 @@ tmpfs_rename(struct vop_rename_args *v)
  	char *newname;
  	int error;
  	struct tmpfs_dirent *de;
 +	struct tmpfs_mount *tmp;
  	struct tmpfs_node *fdnode;
  	struct tmpfs_node *fnode;
  	struct tmpfs_node *tnode;
 @@ -934,6 +940,7 @@ tmpfs_rename(struct vop_rename_args *v)
  		goto out;
  	}
  
 +	tmp = VFS_TO_TMPFS(tdvp->v_mount);
  	tdnode = VP_TO_TMPFS_DIR(tdvp);
  
  	/* If source and target are the same file, there is nothing to do. */
 @@ -1018,25 +1025,63 @@ tmpfs_rename(struct vop_rename_args *v)
  			 * directory being moved.  Otherwise, we'd end up
  			 * with stale nodes. */
  			n = tdnode;
 +			/* TMPFS_LOCK garanties that no nodes are freed while
 +			 * traversing the list. Nodes can only be marked as
 +			 * removed: tn_parent == NULL. */
 +			TMPFS_LOCK(tmp);
 +			TMPFS_NODE_LOCK(n);
  			while (n != n->tn_dir.tn_parent) {
 +				struct tmpfs_node *parent;
 +
  				if (n == fnode) {
 +					TMPFS_NODE_UNLOCK(n);
 +					TMPFS_UNLOCK(tmp);
  					error = EINVAL;
  					if (newname != NULL)
  						    free(newname, M_TMPFSNAME);
  					goto out_locked;
  				}
 -				n = n->tn_dir.tn_parent;
 +				parent = n->tn_dir.tn_parent;
 +				TMPFS_NODE_UNLOCK(n);
 +				if (parent == NULL) {
 +					n = NULL;
 +					break;
 +				}
 +				TMPFS_NODE_LOCK(parent);
 +				if (parent->tn_dir.tn_parent == NULL) {
 +					TMPFS_NODE_UNLOCK(parent);
 +					n = NULL;
 +					break;
 +				}
 +				n = parent;
 +			}
 +			TMPFS_UNLOCK(tmp);
 +			if (n == NULL) {
 +				error = EINVAL;
 +				if (newname != NULL)
 +					    free(newname, M_TMPFSNAME);
 +				goto out_locked;
  			}
 +			TMPFS_NODE_UNLOCK(n);
  
  			/* Adjust the parent pointer. */
  			TMPFS_VALIDATE_DIR(fnode);
 +			TMPFS_NODE_LOCK(de->td_node);
  			de->td_node->tn_dir.tn_parent = tdnode;
 +			TMPFS_NODE_UNLOCK(de->td_node);
  
  			/* As a result of changing the target of the '..'
  			 * entry, the link count of the source and target
  			 * directories has to be adjusted. */
 -			fdnode->tn_links--;
 +			TMPFS_NODE_LOCK(tdnode);
 +			TMPFS_ASSERT_LOCKED(tdnode);
  			tdnode->tn_links++;
 +			TMPFS_NODE_UNLOCK(tdnode);
 +
 +			TMPFS_NODE_LOCK(fdnode);
 +			TMPFS_ASSERT_LOCKED(fdnode);
 +			fdnode->tn_links--;
 +			TMPFS_NODE_UNLOCK(fdnode);
  		}
  
  		/* Do the move: just remove the entry from the source directory
 @@ -1163,15 +1208,26 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
  		goto out;
  	}
  
 +
  	/* Detach the directory entry from the directory (dnode). */
  	tmpfs_dir_detach(dvp, de);
  
 +	/* No vnode should be allocated for this entry from this point */
 +	TMPFS_NODE_LOCK(node);
 +	TMPFS_ASSERT_ELOCKED(node);
  	node->tn_links--;
 +	node->tn_dir.tn_parent = NULL;
  	node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \
  	    TMPFS_NODE_MODIFIED;
 -	node->tn_dir.tn_parent->tn_links--;
 -	node->tn_dir.tn_parent->tn_status |= TMPFS_NODE_ACCESSED | \
 +
 +	TMPFS_NODE_UNLOCK(node);
 +
 +	TMPFS_NODE_LOCK(dnode);
 +	TMPFS_ASSERT_ELOCKED(dnode);
 +	dnode->tn_links--;
 +	dnode->tn_status |= TMPFS_NODE_ACCESSED | \
  	    TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED;
 +	TMPFS_NODE_UNLOCK(dnode);
  
  	cache_purge(dvp);
  	cache_purge(vp);
 @@ -1359,13 +1415,21 @@ tmpfs_reclaim(struct vop_reclaim_args *v
  
  	vnode_destroy_vobject(vp);
  	cache_purge(vp);
 +
 +	TMPFS_NODE_LOCK(node);
 +	TMPFS_ASSERT_ELOCKED(node);
  	tmpfs_free_vp(vp);
  
  	/* If the node referenced by this vnode was deleted by the user,
  	 * we must free its associated data structures (now that the vnode
  	 * is being reclaimed). */
 -	if (node->tn_links == 0)
 +	if (node->tn_links == 0 &&
 +	    (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0) {
 +		node->tn_vpstate = TMPFS_VNODE_DOOMED;
 +		TMPFS_NODE_UNLOCK(node);
  		tmpfs_free_node(tmp, node);
 +	} else
 +		TMPFS_NODE_UNLOCK(node);
  
  	MPASS(vp->v_data == NULL);
  	return 0;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: delphij 
State-Changed-When: Mon Dec 14 23:41:36 UTC 2009 
State-Changed-Why:  
Fixed with gk@'s patch. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=122038 
Responsible-Changed-From-To: delphij->gleb 
Responsible-Changed-By: delphij 
Responsible-Changed-When: Tue Feb 7 22:27:47 UTC 2012 
Responsible-Changed-Why:  
Change ownership to gleb@ since he is the original author of the patch. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=122038 
State-Changed-From-To: patched->closed 
State-Changed-By: eadler 
State-Changed-When: Fri Mar 15 23:34:48 UTC 2013 
State-Changed-Why:  
MFCed/fixed by now or it will never be MFCed 

http://www.freebsd.org/cgi/query-pr.cgi?pr=122038 
>Unformatted:
