Skip to content
Snippets Groups Projects
Commit 9ce32c00 authored by Gleb Natapov's avatar Gleb Natapov Committed by Pekka Enberg
Browse files

vfs: remove dentry of a destination after rename()


If dentry has elevated reference count during rename (a file is opened
for instance) it is not destroyed and remains in the dentry hash. As a
result old file is accessible by destination path instead of new one.

Signed-off-by: default avatarGleb Natapov <gleb@cloudius-systems.com>
Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
parent a8526d28
No related branches found
No related tags found
No related merge requests found
...@@ -140,6 +140,7 @@ int fs_noop(void); ...@@ -140,6 +140,7 @@ int fs_noop(void);
struct dentry *dentry_alloc(struct dentry *parent_dp, struct vnode *vp, const char *path); struct dentry *dentry_alloc(struct dentry *parent_dp, struct vnode *vp, const char *path);
void dentry_move(struct dentry *dp, struct dentry *parent_dp, char *path); void dentry_move(struct dentry *dp, struct dentry *parent_dp, char *path);
void dentry_remove(struct dentry *dp);
void dref(struct dentry *dp); void dref(struct dentry *dp);
void drele(struct dentry *dp); void drele(struct dentry *dp);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#define DENTRY_BUCKETS 32 #define DENTRY_BUCKETS 32
static LIST_HEAD(dentry_hash_head, dentry) dentry_hash_table[DENTRY_BUCKETS]; static LIST_HEAD(dentry_hash_head, dentry) dentry_hash_table[DENTRY_BUCKETS];
static LIST_HEAD(fake, dentry) fake;
static struct mutex dentry_hash_lock; static struct mutex dentry_hash_lock;
/* /*
...@@ -129,6 +130,16 @@ dentry_move(struct dentry *dp, struct dentry *parent_dp, char *path) ...@@ -129,6 +130,16 @@ dentry_move(struct dentry *dp, struct dentry *parent_dp, char *path)
free(old_path); free(old_path);
} }
void
dentry_remove(struct dentry *dp)
{
mutex_lock(&dentry_hash_lock);
LIST_REMOVE(dp, d_link);
/* put it on a fake list for drele() to work*/
LIST_INSERT_HEAD(&fake, dp, d_link);
mutex_unlock(&dentry_hash_lock);
}
void void
dref(struct dentry *dp) dref(struct dentry *dp)
{ {
......
...@@ -722,6 +722,8 @@ sys_rename(char *src, char *dest) ...@@ -722,6 +722,8 @@ sys_rename(char *src, char *dest)
error = VOP_RENAME(dvp1, vp1, sname, dvp2, vp2, dname); error = VOP_RENAME(dvp1, vp1, sname, dvp2, vp2, dname);
dentry_move(dp1, ddp2, dname); dentry_move(dp1, ddp2, dname);
if (dp2)
dentry_remove(dp2);
err4: err4:
vn_unlock(dvp2); vn_unlock(dvp2);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment