diff options
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r-- | fs/proc/generic.c | 51 |
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 | */ | ||
561 | static 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 | |||
593 | static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent, | 561 | static 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 | */ |
722 | void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | 690 | void 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) | |||
764 | continue_removing: | 732 | continue_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); |