kern/122038: [tmpfs] [panic] tmpfs: panic: tmpfs_alloc_vp:
type 0xc7d2fab0 0
Gleb Kurtsou
gleb.kurtsou at gmail.com
Fri Oct 2 22:23:29 UTC 2009
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.
-------------- next part --------------
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);
More information about the freebsd-fs
mailing list