diff options
Diffstat (limited to 'fs/proc/namespaces.c')
| -rw-r--r-- | fs/proc/namespaces.c | 74 | 
1 files changed, 18 insertions, 56 deletions
| diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index 54bdc6701e9f..f6abbbbfad8a 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c @@ -213,74 +213,36 @@ out:  	return error;  } -static int proc_ns_fill_cache(struct file *filp, void *dirent, -	filldir_t filldir, struct task_struct *task, -	const struct proc_ns_operations *ops) +static int proc_ns_dir_readdir(struct file *file, struct dir_context *ctx)  { -	return proc_fill_cache(filp, dirent, filldir, -				ops->name, strlen(ops->name), -				proc_ns_instantiate, task, ops); -} - -static int proc_ns_dir_readdir(struct file *filp, void *dirent, -				filldir_t filldir) -{ -	int i; -	struct dentry *dentry = filp->f_path.dentry; -	struct inode *inode = dentry->d_inode; -	struct task_struct *task = get_proc_task(inode); +	struct task_struct *task = get_proc_task(file_inode(file));  	const struct proc_ns_operations **entry, **last; -	ino_t ino; -	int ret; -	ret = -ENOENT;  	if (!task) -		goto out_no_task; +		return -ENOENT; -	ret = 0; -	i = filp->f_pos; -	switch (i) { -	case 0: -		ino = inode->i_ino; -		if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) -			goto out; -		i++; -		filp->f_pos++; -		/* fall through */ -	case 1: -		ino = parent_ino(dentry); -		if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) -			goto out; -		i++; -		filp->f_pos++; -		/* fall through */ -	default: -		i -= 2; -		if (i >= ARRAY_SIZE(ns_entries)) { -			ret = 1; -			goto out; -		} -		entry = ns_entries + i; -		last = &ns_entries[ARRAY_SIZE(ns_entries) - 1]; -		while (entry <= last) { -			if (proc_ns_fill_cache(filp, dirent, filldir, -						task, *entry) < 0) -				goto out; -			filp->f_pos++; -			entry++; -		} +	if (!dir_emit_dots(file, ctx)) +		goto out; +	if (ctx->pos >= 2 + ARRAY_SIZE(ns_entries)) +		goto out; +	entry = ns_entries + (ctx->pos - 2); +	last = &ns_entries[ARRAY_SIZE(ns_entries) - 1]; +	while (entry <= last) { +		const struct proc_ns_operations *ops = *entry; +		if (!proc_fill_cache(file, ctx, ops->name, strlen(ops->name), +				     proc_ns_instantiate, task, ops)) +			break; +		ctx->pos++; +		entry++;  	} - -	ret = 1;  out:  	put_task_struct(task); -out_no_task: -	return ret; +	return 0;  }  const struct file_operations proc_ns_dir_operations = {  	.read		= generic_read_dir, -	.readdir	= proc_ns_dir_readdir, +	.iterate	= proc_ns_dir_readdir,  };  static struct dentry *proc_ns_dir_lookup(struct inode *dir, |