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>