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.c51
1 files changed, 6 insertions, 45 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index a9806bc21ec3..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,41 +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;
565
566 /*
567 * Actually it's a partial revoke().
568 */
569 spin_lock(&sb_lock);
570 list_for_each_entry(sb, &proc_fs_type.fs_supers, s_instances) {
571 file_list_lock();
572 list_for_each(p, &sb->s_files) {
573 struct file *filp = list_entry(p, struct file,
574 f_u.fu_list);
575 struct dentry *dentry = filp->f_path.dentry;
576 struct inode *inode;
577 const struct file_operations *fops;
578
579 if (dentry->d_op != &proc_dentry_operations)
580 continue;
581 inode = dentry->d_inode;
582 if (PDE(inode) != de)
583 continue;
584 fops = filp->f_op;
585 filp->f_op = NULL;
586 fops_put(fops);
587 }
588 file_list_unlock();
589 }
590 spin_unlock(&sb_lock);
591}
592
593static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent, 561static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
594 const char *name, 562 const char *name,
595 mode_t mode, 563 mode_t mode,
@@ -620,6 +588,7 @@ static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
620 ent->namelen = len; 588 ent->namelen = len;
621 ent->mode = mode; 589 ent->mode = mode;
622 ent->nlink = nlink; 590 ent->nlink = nlink;
591 atomic_set(&ent->count, 1);
623 ent->pde_users = 0; 592 ent->pde_users = 0;
624 spin_lock_init(&ent->pde_unload_lock); 593 spin_lock_init(&ent->pde_unload_lock);
625 ent->pde_unload_completion = NULL; 594 ent->pde_unload_completion = NULL;
@@ -717,7 +686,6 @@ void free_proc_entry(struct proc_dir_entry *de)
717 686
718/* 687/*
719 * 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.
720 * If it is in use, we set the 'deleted' flag.
721 */ 689 */
722void remove_proc_entry(const char *name, struct proc_dir_entry *parent) 690void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
723{ 691{
@@ -764,17 +732,10 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
764continue_removing: 732continue_removing:
765 if (S_ISDIR(de->mode)) 733 if (S_ISDIR(de->mode))
766 parent->nlink--; 734 parent->nlink--;
767 if (!S_ISREG(de->mode))
768 proc_kill_inodes(de);
769 de->nlink = 0; 735 de->nlink = 0;
770 WARN_ON(de->subdir); 736 WARN_ON(de->subdir);
771 if (!atomic_read(&de->count)) 737 if (atomic_dec_and_test(&de->count))
772 free_proc_entry(de); 738 free_proc_entry(de);
773 else {
774 de->deleted = 1;
775 printk("remove_proc_entry: %s/%s busy, count=%d\n",
776 parent->name, de->name, atomic_read(&de->count));
777 }
778 break; 739 break;
779 } 740 }
780 spin_unlock(&proc_subdir_lock); 741 spin_unlock(&proc_subdir_lock);