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.c46
1 files changed, 6 insertions, 40 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 1bdb62435758..6a2fe5187b62 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -397,8 +397,11 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam
397 if (de->namelen != dentry->d_name.len) 397 if (de->namelen != dentry->d_name.len)
398 continue; 398 continue;
399 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { 399 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
400 unsigned int ino = de->low_ino; 400 unsigned int ino;
401 401
402 if (de->shadow_proc)
403 de = de->shadow_proc(current, de);
404 ino = de->low_ino;
402 de_get(de); 405 de_get(de);
403 spin_unlock(&proc_subdir_lock); 406 spin_unlock(&proc_subdir_lock);
404 error = -EINVAL; 407 error = -EINVAL;
@@ -555,36 +558,6 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
555 return 0; 558 return 0;
556} 559}
557 560
558/*
559 * Kill an inode that got unregistered..
560 */
561static void proc_kill_inodes(struct proc_dir_entry *de)
562{
563 struct list_head *p;
564 struct super_block *sb = proc_mnt->mnt_sb;
565
566 /*
567 * Actually it's a partial revoke().
568 */
569 file_list_lock();
570 list_for_each(p, &sb->s_files) {
571 struct file * filp = list_entry(p, struct file, f_u.fu_list);
572 struct dentry * dentry = filp->f_path.dentry;
573 struct inode * inode;
574 const struct file_operations *fops;
575
576 if (dentry->d_op != &proc_dentry_operations)
577 continue;
578 inode = dentry->d_inode;
579 if (PDE(inode) != de)
580 continue;
581 fops = filp->f_op;
582 filp->f_op = NULL;
583 fops_put(fops);
584 }
585 file_list_unlock();
586}
587
588static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent, 561static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
589 const char *name, 562 const char *name,
590 mode_t mode, 563 mode_t mode,
@@ -615,6 +588,7 @@ static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
615 ent->namelen = len; 588 ent->namelen = len;
616 ent->mode = mode; 589 ent->mode = mode;
617 ent->nlink = nlink; 590 ent->nlink = nlink;
591 atomic_set(&ent->count, 1);
618 ent->pde_users = 0; 592 ent->pde_users = 0;
619 spin_lock_init(&ent->pde_unload_lock); 593 spin_lock_init(&ent->pde_unload_lock);
620 ent->pde_unload_completion = NULL; 594 ent->pde_unload_completion = NULL;
@@ -712,7 +686,6 @@ void free_proc_entry(struct proc_dir_entry *de)
712 686
713/* 687/*
714 * Remove a /proc entry and free it if it's not currently in use. 688 * Remove a /proc entry and free it if it's not currently in use.
715 * If it is in use, we set the 'deleted' flag.
716 */ 689 */
717void remove_proc_entry(const char *name, struct proc_dir_entry *parent) 690void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
718{ 691{
@@ -759,17 +732,10 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
759continue_removing: 732continue_removing:
760 if (S_ISDIR(de->mode)) 733 if (S_ISDIR(de->mode))
761 parent->nlink--; 734 parent->nlink--;
762 if (!S_ISREG(de->mode))
763 proc_kill_inodes(de);
764 de->nlink = 0; 735 de->nlink = 0;
765 WARN_ON(de->subdir); 736 WARN_ON(de->subdir);
766 if (!atomic_read(&de->count)) 737 if (atomic_dec_and_test(&de->count))
767 free_proc_entry(de); 738 free_proc_entry(de);
768 else {
769 de->deleted = 1;
770 printk("remove_proc_entry: %s/%s busy, count=%d\n",
771 parent->name, de->name, atomic_read(&de->count));
772 }
773 break; 739 break;
774 } 740 }
775 spin_unlock(&proc_subdir_lock); 741 spin_unlock(&proc_subdir_lock);