diff options
Diffstat (limited to 'fs/pipe.c')
| -rw-r--r-- | fs/pipe.c | 75 | 
1 files changed, 26 insertions, 49 deletions
| 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;  } | 
