diff options
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r-- | fs/proc/generic.c | 46 |
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 | */ | ||
561 | static 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 | |||
588 | 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, |
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 | */ |
717 | 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) |
718 | { | 691 | { |
@@ -759,17 +732,10 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | |||
759 | continue_removing: | 732 | continue_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); |