Loading fs/proc/inode.c +38 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,44 @@ void __init proc_init_kmemcache(void) BUILD_BUG_ON(sizeof(struct proc_dir_entry) >= SIZEOF_PDE); } void proc_prune_siblings_dcache(struct hlist_head *inodes, spinlock_t *lock) { struct inode *inode; struct proc_inode *ei; struct hlist_node *node; struct super_block *sb; rcu_read_lock(); for (;;) { node = hlist_first_rcu(inodes); if (!node) break; ei = hlist_entry(node, struct proc_inode, sibling_inodes); spin_lock(lock); hlist_del_init_rcu(&ei->sibling_inodes); spin_unlock(lock); inode = &ei->vfs_inode; sb = inode->i_sb; if (!atomic_inc_not_zero(&sb->s_active)) continue; inode = igrab(inode); rcu_read_unlock(); if (unlikely(!inode)) { deactivate_super(sb); rcu_read_lock(); continue; } d_prune_aliases(inode); iput(inode); deactivate_super(sb); rcu_read_lock(); } rcu_read_unlock(); } static int proc_show_options(struct seq_file *seq, struct dentry *root) { struct super_block *sb = root->d_sb; Loading fs/proc/internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ extern const struct inode_operations proc_pid_link_inode_operations; extern const struct super_operations proc_sops; void proc_init_kmemcache(void); void proc_prune_siblings_dcache(struct hlist_head *inodes, spinlock_t *lock); void set_proc_pid_nlink(void); extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); extern void proc_entry_rundown(struct proc_dir_entry *); Loading fs/proc/proc_sysctl.c +1 −34 Original line number Diff line number Diff line Loading @@ -269,40 +269,7 @@ static void unuse_table(struct ctl_table_header *p) static void proc_sys_prune_dcache(struct ctl_table_header *head) { struct inode *inode; struct proc_inode *ei; struct hlist_node *node; struct super_block *sb; rcu_read_lock(); for (;;) { node = hlist_first_rcu(&head->inodes); if (!node) break; ei = hlist_entry(node, struct proc_inode, sibling_inodes); spin_lock(&sysctl_lock); hlist_del_init_rcu(&ei->sibling_inodes); spin_unlock(&sysctl_lock); inode = &ei->vfs_inode; sb = inode->i_sb; if (!atomic_inc_not_zero(&sb->s_active)) continue; inode = igrab(inode); rcu_read_unlock(); if (unlikely(!inode)) { deactivate_super(sb); rcu_read_lock(); continue; } d_prune_aliases(inode); iput(inode); deactivate_super(sb); rcu_read_lock(); } rcu_read_unlock(); proc_prune_siblings_dcache(&head->inodes, &sysctl_lock); } /* called under sysctl_lock, will reacquire if has to wait */ Loading Loading
fs/proc/inode.c +38 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,44 @@ void __init proc_init_kmemcache(void) BUILD_BUG_ON(sizeof(struct proc_dir_entry) >= SIZEOF_PDE); } void proc_prune_siblings_dcache(struct hlist_head *inodes, spinlock_t *lock) { struct inode *inode; struct proc_inode *ei; struct hlist_node *node; struct super_block *sb; rcu_read_lock(); for (;;) { node = hlist_first_rcu(inodes); if (!node) break; ei = hlist_entry(node, struct proc_inode, sibling_inodes); spin_lock(lock); hlist_del_init_rcu(&ei->sibling_inodes); spin_unlock(lock); inode = &ei->vfs_inode; sb = inode->i_sb; if (!atomic_inc_not_zero(&sb->s_active)) continue; inode = igrab(inode); rcu_read_unlock(); if (unlikely(!inode)) { deactivate_super(sb); rcu_read_lock(); continue; } d_prune_aliases(inode); iput(inode); deactivate_super(sb); rcu_read_lock(); } rcu_read_unlock(); } static int proc_show_options(struct seq_file *seq, struct dentry *root) { struct super_block *sb = root->d_sb; Loading
fs/proc/internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ extern const struct inode_operations proc_pid_link_inode_operations; extern const struct super_operations proc_sops; void proc_init_kmemcache(void); void proc_prune_siblings_dcache(struct hlist_head *inodes, spinlock_t *lock); void set_proc_pid_nlink(void); extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); extern void proc_entry_rundown(struct proc_dir_entry *); Loading
fs/proc/proc_sysctl.c +1 −34 Original line number Diff line number Diff line Loading @@ -269,40 +269,7 @@ static void unuse_table(struct ctl_table_header *p) static void proc_sys_prune_dcache(struct ctl_table_header *head) { struct inode *inode; struct proc_inode *ei; struct hlist_node *node; struct super_block *sb; rcu_read_lock(); for (;;) { node = hlist_first_rcu(&head->inodes); if (!node) break; ei = hlist_entry(node, struct proc_inode, sibling_inodes); spin_lock(&sysctl_lock); hlist_del_init_rcu(&ei->sibling_inodes); spin_unlock(&sysctl_lock); inode = &ei->vfs_inode; sb = inode->i_sb; if (!atomic_inc_not_zero(&sb->s_active)) continue; inode = igrab(inode); rcu_read_unlock(); if (unlikely(!inode)) { deactivate_super(sb); rcu_read_lock(); continue; } d_prune_aliases(inode); iput(inode); deactivate_super(sb); rcu_read_lock(); } rcu_read_unlock(); proc_prune_siblings_dcache(&head->inodes, &sysctl_lock); } /* called under sysctl_lock, will reacquire if has to wait */ Loading