diff options
author | delphij <delphij@FreeBSD.org> | 2007-11-18 04:52:40 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2007-11-18 04:52:40 +0000 |
commit | c5d6580fd4b8e519f78c87346bdba7fc4637452b (patch) | |
tree | 9a3aa658a087f9d1188ba73686fc05b714847d07 /sys/fs/tmpfs/tmpfs_subr.c | |
parent | b0d971c673423f9db4d4c3a4e8ab7f2099487302 (diff) | |
download | FreeBSD-src-c5d6580fd4b8e519f78c87346bdba7fc4637452b.zip FreeBSD-src-c5d6580fd4b8e519f78c87346bdba7fc4637452b.tar.gz |
MFp4: Several fixes to tmpfs which makes it to survive from pho@'s
strees2 suite, to quote his letter, this change:
1. It removes the tn_lookup_dirent stuff. I think this cannot be fixed,
because nothing protects vnode/tmpfs node between lookup is done, and
actual operation is performed, in the case the vnode lock is dropped.
At least, this is the case with the from vnode for rename.
For now, we do the linear lookup in the parent node. This has its own
drawbacks. Not mentioning speed (that could be fixed by using hash), the
real problem is the situation where several hardlinks exist in the dvp.
But, I think this is fixable.
2. The patch restores the VV_ROOT flag on the root vnode after it became
reclaimed and allocated again. This fixes MPASS assertion at the start
of the tmpfs_lookup() reported by many.
Submitted by: kib
Diffstat (limited to 'sys/fs/tmpfs/tmpfs_subr.c')
-rw-r--r-- | sys/fs/tmpfs/tmpfs_subr.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index abfab9a..a855fd0 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -125,6 +125,8 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp, enum vtype type, case VDIR: TAILQ_INIT(&nnode->tn_dir.tn_dirhead); + MPASS(parent != nnode); + MPASS(IMPLIES(parent == NULL, tmp->tm_root == NULL)); nnode->tn_dir.tn_parent = (parent == NULL) ? nnode : parent; nnode->tn_dir.tn_readdir_lastn = 0; nnode->tn_dir.tn_readdir_lastp = NULL; @@ -370,8 +372,6 @@ loop: /* FALLTHROUGH */ case VCHR: /* FALLTHROUGH */ - case VDIR: - /* FALLTHROUGH */ case VLNK: /* FALLTHROUGH */ case VREG: @@ -381,6 +381,10 @@ loop: case VFIFO: vp->v_op = &tmpfs_fifoop_entries; break; + case VDIR: + if (node->tn_dir.tn_parent == node) + vp->v_vflag |= VV_ROOT; + break; default: MPASS(0); @@ -388,8 +392,11 @@ loop: vnode_pager_setsize(vp, node->tn_size); error = insmntque(vp, mp); - if (error) + if (error) { + vgone(vp); + vput(vp); vp = NULL; + } unlock: TMPFS_NODE_LOCK(node); @@ -480,6 +487,7 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap, } parent = dnode; + MPASS(parent != NULL); } else parent = NULL; @@ -598,6 +606,20 @@ tmpfs_dir_lookup(struct tmpfs_node *node, struct componentname *cnp) return found ? de : NULL; } +struct tmpfs_dirent * +tmpfs_dir_search(struct tmpfs_node *node, struct tmpfs_node *f) +{ + struct tmpfs_dirent *de; + + TMPFS_VALIDATE_DIR(node); + node->tn_status |= TMPFS_NODE_ACCESSED; + TAILQ_FOREACH(de, &node->tn_dir.tn_dirhead, td_entries) { + if (de->td_node == f) + return (de); + } + return (NULL); +} + /* --------------------------------------------------------------------- */ /* |