aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r--fs/proc/generic.c21
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)
374 return 1; 374 return 1;
375} 375}
376 376
377static int proc_revalidate_dentry(struct dentry *dentry, struct nameidata *nd)
378{
379 d_drop(dentry);
380 return 0;
381}
382
377static struct dentry_operations proc_dentry_operations = 383static struct dentry_operations proc_dentry_operations =
378{ 384{
379 .d_delete = proc_delete_dentry, 385 .d_delete = proc_delete_dentry,
386 .d_revalidate = proc_revalidate_dentry,
380}; 387};
381 388
382/* 389/*
@@ -397,8 +404,11 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam
397 if (de->namelen != dentry->d_name.len) 404 if (de->namelen != dentry->d_name.len)
398 continue; 405 continue;
399 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { 406 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
400 unsigned int ino = de->low_ino; 407 unsigned int ino;
401 408
409 if (de->shadow_proc)
410 de = de->shadow_proc(current, de);
411 ino = de->low_ino;
402 de_get(de); 412 de_get(de);
403 spin_unlock(&proc_subdir_lock); 413 spin_unlock(&proc_subdir_lock);
404 error = -EINVAL; 414 error = -EINVAL;
@@ -585,6 +595,7 @@ static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
585 ent->namelen = len; 595 ent->namelen = len;
586 ent->mode = mode; 596 ent->mode = mode;
587 ent->nlink = nlink; 597 ent->nlink = nlink;
598 atomic_set(&ent->count, 1);
588 ent->pde_users = 0; 599 ent->pde_users = 0;
589 spin_lock_init(&ent->pde_unload_lock); 600 spin_lock_init(&ent->pde_unload_lock);
590 ent->pde_unload_completion = NULL; 601 ent->pde_unload_completion = NULL;
@@ -682,7 +693,6 @@ void free_proc_entry(struct proc_dir_entry *de)
682 693
683/* 694/*
684 * Remove a /proc entry and free it if it's not currently in use. 695 * Remove a /proc entry and free it if it's not currently in use.
685 * If it is in use, we set the 'deleted' flag.
686 */ 696 */
687void remove_proc_entry(const char *name, struct proc_dir_entry *parent) 697void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
688{ 698{
@@ -731,13 +741,8 @@ continue_removing:
731 parent->nlink--; 741 parent->nlink--;
732 de->nlink = 0; 742 de->nlink = 0;
733 WARN_ON(de->subdir); 743 WARN_ON(de->subdir);
734 if (!atomic_read(&de->count)) 744 if (atomic_dec_and_test(&de->count))
735 free_proc_entry(de); 745 free_proc_entry(de);
736 else {
737 de->deleted = 1;
738 printk("remove_proc_entry: %s/%s busy, count=%d\n",
739 parent->name, de->name, atomic_read(&de->count));
740 }
741 break; 746 break;
742 } 747 }
743 spin_unlock(&proc_subdir_lock); 748 spin_unlock(&proc_subdir_lock);