kern/122038: [tmpfs] [panic] tmpfs: panic: tmpfs_alloc_vp: type 0xc7d2fab0 0

Gleb Kurtsou gleb.kurtsou at gmail.com
Fri Oct 2 22:30:04 UTC 2009


The following reply was made to PR kern/122038; it has been noted by GNATS.

From: Gleb Kurtsou <gleb.kurtsou at gmail.com>
To: bug-followup at FreeBSD.org, delphij at FreeBSD.org, gprspb at mail.ru
Cc: freebsd-fs at 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--


More information about the freebsd-fs mailing list