Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 3 Oct 2009 01:23:06 +0300
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
Message-ID:  <20091002222306.GA1729@tops>
In-Reply-To: <200908121810.n7CIA8Qv058688@freefall.freebsd.org>
References:  <200908121810.n7CIA8Qv058688@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20091002222306.GA1729>