summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-02-08 19:18:33 +0000
committerkib <kib@FreeBSD.org>2009-02-08 19:18:33 +0000
commit8571ced24c174eea12d164f46470290a8ed9cec6 (patch)
tree7dfcb5eedc4540a1aa55fa41015be168102928ea
parent185bd48df413b2f290b4b5ccd6fb5af7310ec8a3 (diff)
downloadFreeBSD-src-8571ced24c174eea12d164f46470290a8ed9cec6.zip
FreeBSD-src-8571ced24c174eea12d164f46470290a8ed9cec6.tar.gz
Lookup up the directory entry for the tmpfs node that are deleted by
both node pointer and name component. This does the right thing for hardlinks to the same node in the same directory. Submitted by: Yoshihiro Ota <ota j email ne jp> PR: kern/131356 MFC after: 2 weeks
-rw-r--r--sys/fs/tmpfs/tmpfs.h3
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c19
-rw-r--r--sys/fs/tmpfs/tmpfs_vnops.c10
3 files changed, 10 insertions, 22 deletions
diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h
index 5b3be11..1ae8ca6 100644
--- a/sys/fs/tmpfs/tmpfs.h
+++ b/sys/fs/tmpfs/tmpfs.h
@@ -408,9 +408,8 @@ int tmpfs_alloc_file(struct vnode *, struct vnode **, struct vattr *,
void tmpfs_dir_attach(struct vnode *, struct tmpfs_dirent *);
void tmpfs_dir_detach(struct vnode *, struct tmpfs_dirent *);
struct tmpfs_dirent * tmpfs_dir_lookup(struct tmpfs_node *node,
+ struct tmpfs_node *f,
struct componentname *cnp);
-struct tmpfs_dirent *tmpfs_dir_search(struct tmpfs_node *node,
- struct tmpfs_node *f);
int tmpfs_dir_getdotdent(struct tmpfs_node *, struct uio *);
int tmpfs_dir_getdotdotdent(struct tmpfs_node *, struct uio *);
struct tmpfs_dirent * tmpfs_dir_lookupbycookie(struct tmpfs_node *, off_t);
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index c0c6b50..3e5adf7 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -571,7 +571,8 @@ tmpfs_dir_detach(struct vnode *vp, struct tmpfs_dirent *de)
* Returns a pointer to the entry when found, otherwise NULL.
*/
struct tmpfs_dirent *
-tmpfs_dir_lookup(struct tmpfs_node *node, struct componentname *cnp)
+tmpfs_dir_lookup(struct tmpfs_node *node, struct tmpfs_node *f,
+ struct componentname *cnp)
{
boolean_t found;
struct tmpfs_dirent *de;
@@ -583,6 +584,8 @@ tmpfs_dir_lookup(struct tmpfs_node *node, struct componentname *cnp)
found = 0;
TAILQ_FOREACH(de, &node->tn_dir.tn_dirhead, td_entries) {
+ if (f != NULL && de->td_node != f)
+ continue;
MPASS(cnp->cn_namelen < 0xffff);
if (de->td_namelen == (uint16_t)cnp->cn_namelen &&
bcmp(de->td_name, cnp->cn_nameptr, de->td_namelen) == 0) {
@@ -595,20 +598,6 @@ 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);
-}
-
/* --------------------------------------------------------------------- */
/*
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
index 8f76bdf..38a127f 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -104,7 +104,7 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
*vpp = dvp;
error = 0;
} else {
- de = tmpfs_dir_lookup(dnode, cnp);
+ de = tmpfs_dir_lookup(dnode, NULL, cnp);
if (de == NULL) {
/* The entry was not found in the directory.
* This is OK if we are creating or renaming an
@@ -772,7 +772,7 @@ tmpfs_remove(struct vop_remove_args *v)
dnode = VP_TO_TMPFS_DIR(dvp);
node = VP_TO_TMPFS_NODE(vp);
tmp = VFS_TO_TMPFS(vp->v_mount);
- de = tmpfs_dir_search(dnode, node);
+ de = tmpfs_dir_lookup(dnode, node, v->a_cnp);
MPASS(de != NULL);
/* Files marked as immutable or append-only cannot be deleted. */
@@ -919,7 +919,7 @@ tmpfs_rename(struct vop_rename_args *v)
}
fdnode = VP_TO_TMPFS_DIR(fdvp);
fnode = VP_TO_TMPFS_NODE(fvp);
- de = tmpfs_dir_search(fdnode, fnode);
+ de = tmpfs_dir_lookup(fdnode, fnode, fcnp);
/* Avoid manipulating '.' and '..' entries. */
if (de == NULL) {
@@ -1031,7 +1031,7 @@ tmpfs_rename(struct vop_rename_args *v)
* from the target directory. */
if (tvp != NULL) {
/* Remove the old entry from the target directory. */
- de = tmpfs_dir_search(tdnode, tnode);
+ de = tmpfs_dir_lookup(tdnode, tnode, tcnp);
tmpfs_dir_detach(tdvp, de);
/* Free the directory entry we just deleted. Note that the
@@ -1119,7 +1119,7 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
/* Get the directory entry associated with node (vp). This was
* filled by tmpfs_lookup while looking up the entry. */
- de = tmpfs_dir_search(dnode, node);
+ de = tmpfs_dir_lookup(dnode, node, v->a_cnp);
MPASS(TMPFS_DIRENT_MATCHES(de,
v->a_cnp->cn_nameptr,
v->a_cnp->cn_namelen));
OpenPOWER on IntegriCloud