Commit 26dbc60f authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

proc: Generalize proc_sys_prune_dcache into proc_prune_siblings_dcache



This prepares the way for allowing the pid part of proc to use this
dcache pruning code as well.

Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
parent 0afa5ca8
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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 *);
+1 −34
Original line number Diff line number Diff line
@@ -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 */