diff options
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r-- | fs/proc/generic.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 39f3d6519035..8d49838e5554 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -374,9 +374,16 @@ static int proc_delete_dentry(struct dentry * dentry) return 1; } +static int proc_revalidate_dentry(struct dentry *dentry, struct nameidata *nd) +{ + d_drop(dentry); + return 0; +} + static struct dentry_operations proc_dentry_operations = { .d_delete = proc_delete_dentry, + .d_revalidate = proc_revalidate_dentry, }; /* @@ -397,8 +404,11 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam if (de->namelen != dentry->d_name.len) continue; if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { - unsigned int ino = de->low_ino; + unsigned int ino; + if (de->shadow_proc) + de = de->shadow_proc(current, de); + ino = de->low_ino; de_get(de); spin_unlock(&proc_subdir_lock); error = -EINVAL; @@ -585,6 +595,7 @@ static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent, ent->namelen = len; ent->mode = mode; ent->nlink = nlink; + atomic_set(&ent->count, 1); ent->pde_users = 0; spin_lock_init(&ent->pde_unload_lock); ent->pde_unload_completion = NULL; @@ -682,7 +693,6 @@ void free_proc_entry(struct proc_dir_entry *de) /* * Remove a /proc entry and free it if it's not currently in use. - * If it is in use, we set the 'deleted' flag. */ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) { @@ -731,13 +741,8 @@ continue_removing: parent->nlink--; de->nlink = 0; WARN_ON(de->subdir); - if (!atomic_read(&de->count)) + if (atomic_dec_and_test(&de->count)) free_proc_entry(de); - else { - de->deleted = 1; - printk("remove_proc_entry: %s/%s busy, count=%d\n", - parent->name, de->name, atomic_read(&de->count)); - } break; } spin_unlock(&proc_subdir_lock); |