aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/inode.c')
-rw-r--r--fs/proc/inode.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 3ddb6068177..d6a7ca1fdac 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -27,6 +27,7 @@
27static void proc_evict_inode(struct inode *inode) 27static void proc_evict_inode(struct inode *inode)
28{ 28{
29 struct proc_dir_entry *de; 29 struct proc_dir_entry *de;
30 struct ctl_table_header *head;
30 31
31 truncate_inode_pages(&inode->i_data, 0); 32 truncate_inode_pages(&inode->i_data, 0);
32 end_writeback(inode); 33 end_writeback(inode);
@@ -38,8 +39,11 @@ static void proc_evict_inode(struct inode *inode)
38 de = PROC_I(inode)->pde; 39 de = PROC_I(inode)->pde;
39 if (de) 40 if (de)
40 pde_put(de); 41 pde_put(de);
41 if (PROC_I(inode)->sysctl) 42 head = PROC_I(inode)->sysctl;
42 sysctl_head_put(PROC_I(inode)->sysctl); 43 if (head) {
44 rcu_assign_pointer(PROC_I(inode)->sysctl, NULL);
45 sysctl_head_put(head);
46 }
43} 47}
44 48
45struct vfsmount *proc_mnt; 49struct vfsmount *proc_mnt;
@@ -65,11 +69,18 @@ static struct inode *proc_alloc_inode(struct super_block *sb)
65 return inode; 69 return inode;
66} 70}
67 71
68static void proc_destroy_inode(struct inode *inode) 72static void proc_i_callback(struct rcu_head *head)
69{ 73{
74 struct inode *inode = container_of(head, struct inode, i_rcu);
75 INIT_LIST_HEAD(&inode->i_dentry);
70 kmem_cache_free(proc_inode_cachep, PROC_I(inode)); 76 kmem_cache_free(proc_inode_cachep, PROC_I(inode));
71} 77}
72 78
79static void proc_destroy_inode(struct inode *inode)
80{
81 call_rcu(&inode->i_rcu, proc_i_callback);
82}
83
73static void init_once(void *foo) 84static void init_once(void *foo)
74{ 85{
75 struct proc_inode *ei = (struct proc_inode *) foo; 86 struct proc_inode *ei = (struct proc_inode *) foo;
@@ -409,12 +420,11 @@ static const struct file_operations proc_reg_file_ops_no_compat = {
409}; 420};
410#endif 421#endif
411 422
412struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, 423struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
413 struct proc_dir_entry *de)
414{ 424{
415 struct inode * inode; 425 struct inode * inode;
416 426
417 inode = iget_locked(sb, ino); 427 inode = iget_locked(sb, de->low_ino);
418 if (!inode) 428 if (!inode)
419 return NULL; 429 return NULL;
420 if (inode->i_state & I_NEW) { 430 if (inode->i_state & I_NEW) {
@@ -464,7 +474,7 @@ int proc_fill_super(struct super_block *s)
464 s->s_time_gran = 1; 474 s->s_time_gran = 1;
465 475
466 pde_get(&proc_root); 476 pde_get(&proc_root);
467 root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); 477 root_inode = proc_get_inode(s, &proc_root);
468 if (!root_inode) 478 if (!root_inode)
469 goto out_no_root; 479 goto out_no_root;
470 root_inode->i_uid = 0; 480 root_inode->i_uid = 0;