diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-21 15:33:25 +0400 | 
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-29 21:24:19 +0400 | 
| commit | e4fad8e5d220e3dfb1050eee752ee5058f29a232 (patch) | |
| tree | b56356fda1d1f4f47e1da63aa24080db999dafc1 | |
| parent | b5bcdda32736b94a7d178d156d80a69f536ad468 (diff) | |
consolidate pipe file creation
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/exec.c | 19 | ||||
| -rw-r--r-- | fs/pipe.c | 75 | ||||
| -rw-r--r-- | include/linux/fs.h | 3 | ||||
| -rw-r--r-- | include/linux/pipe_fs_i.h | 2 | 
4 files changed, 34 insertions, 65 deletions
| diff --git a/fs/exec.c b/fs/exec.c index da27b91ff1e8..b800fb87f6ce 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -2069,25 +2069,18 @@ static void wait_for_dump_helpers(struct file *file)   */  static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)  { -	struct file *rp, *wp; +	struct file *files[2];  	struct fdtable *fdt;  	struct coredump_params *cp = (struct coredump_params *)info->data;  	struct files_struct *cf = current->files; +	int err = create_pipe_files(files, 0); +	if (err) +		return err; -	wp = create_write_pipe(0); -	if (IS_ERR(wp)) -		return PTR_ERR(wp); - -	rp = create_read_pipe(wp, 0); -	if (IS_ERR(rp)) { -		free_write_pipe(wp); -		return PTR_ERR(rp); -	} - -	cp->file = wp; +	cp->file = files[1];  	sys_close(0); -	fd_install(0, rp); +	fd_install(0, files[0]);  	spin_lock(&cf->file_lock);  	fdt = files_fdtable(cf);  	__set_open_fd(0, fdt); diff --git a/fs/pipe.c b/fs/pipe.c index 49c1065256fd..7523d9d2a998 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1016,18 +1016,16 @@ fail_inode:  	return NULL;  } -struct file *create_write_pipe(int flags) +int create_pipe_files(struct file **res, int flags)  {  	int err; -	struct inode *inode; +	struct inode *inode = get_pipe_inode();  	struct file *f;  	struct path path; -	struct qstr name = { .name = "" }; +	static struct qstr name = { .name = "" }; -	err = -ENFILE; -	inode = get_pipe_inode();  	if (!inode) -		goto err; +		return -ENFILE;  	err = -ENOMEM;  	path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name); @@ -1041,62 +1039,43 @@ struct file *create_write_pipe(int flags)  	f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops);  	if (!f)  		goto err_dentry; -	f->f_mapping = inode->i_mapping;  	f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); -	f->f_version = 0; -	return f; +	res[0] = alloc_file(&path, FMODE_READ, &read_pipefifo_fops); +	if (!res[0]) +		goto err_file; + +	path_get(&path); +	res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK); +	res[1] = f; +	return 0; - err_dentry: +err_file: +	put_filp(f); +err_dentry:  	free_pipe_info(inode);  	path_put(&path); -	return ERR_PTR(err); +	return err; - err_inode: +err_inode:  	free_pipe_info(inode);  	iput(inode); - err: -	return ERR_PTR(err); -} - -void free_write_pipe(struct file *f) -{ -	free_pipe_info(f->f_dentry->d_inode); -	path_put(&f->f_path); -	put_filp(f); -} - -struct file *create_read_pipe(struct file *wrf, int flags) -{ -	/* Grab pipe from the writer */ -	struct file *f = alloc_file(&wrf->f_path, FMODE_READ, -				    &read_pipefifo_fops); -	if (!f) -		return ERR_PTR(-ENFILE); - -	path_get(&wrf->f_path); -	f->f_flags = O_RDONLY | (flags & O_NONBLOCK); - -	return f; +	return err;  }  int do_pipe_flags(int *fd, int flags)  { -	struct file *fw, *fr; +	struct file *files[2];  	int error;  	int fdw, fdr;  	if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))  		return -EINVAL; -	fw = create_write_pipe(flags); -	if (IS_ERR(fw)) -		return PTR_ERR(fw); -	fr = create_read_pipe(fw, flags); -	error = PTR_ERR(fr); -	if (IS_ERR(fr)) -		goto err_write_pipe; +	error = create_pipe_files(files, flags); +	if (error) +		return error;  	error = get_unused_fd_flags(flags);  	if (error < 0) @@ -1109,8 +1088,8 @@ int do_pipe_flags(int *fd, int flags)  	fdw = error;  	audit_fd_pair(fdr, fdw); -	fd_install(fdr, fr); -	fd_install(fdw, fw); +	fd_install(fdr, files[0]); +	fd_install(fdw, files[1]);  	fd[0] = fdr;  	fd[1] = fdw; @@ -1119,10 +1098,8 @@ int do_pipe_flags(int *fd, int flags)   err_fdr:  	put_unused_fd(fdr);   err_read_pipe: -	path_put(&fr->f_path); -	put_filp(fr); - err_write_pipe: -	free_write_pipe(fw); +	fput(files[0]); +	fput(files[1]);  	return error;  } diff --git a/include/linux/fs.h b/include/linux/fs.h index 8fabb037a48d..478237844648 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2326,9 +2326,6 @@ static inline void i_readcount_inc(struct inode *inode)  }  #endif  extern int do_pipe_flags(int *, int); -extern struct file *create_read_pipe(struct file *f, int flags); -extern struct file *create_write_pipe(int flags); -extern void free_write_pipe(struct file *);  extern int kernel_read(struct file *, loff_t, char *, unsigned long);  extern struct file * open_exec(const char *); diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index e1ac1ce16fb0..e16dcb31f0c7 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -162,4 +162,6 @@ void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);  long pipe_fcntl(struct file *, unsigned int, unsigned long arg);  struct pipe_inode_info *get_pipe_info(struct file *file); +int create_pipe_files(struct file **, int); +  #endif | 
