aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pipe.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
commita0e881b7c189fa2bd76c024dbff91e79511c971d (patch)
tree0c801918565b08921d21aceee5b326f64d998f5f /fs/pipe.c
parenteff0d13f3823f35d70228cd151d2a2c89288ff32 (diff)
parentdbc6e0222d79e78925fe20733844a796a4b72cf9 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second vfs pile from Al Viro: "The stuff in there: fsfreeze deadlock fixes by Jan (essentially, the deadlock reproduced by xfstests 068), symlink and hardlink restriction patches, plus assorted cleanups and fixes. Note that another fsfreeze deadlock (emergency thaw one) is *not* dealt with - the series by Fernando conflicts a lot with Jan's, breaks userland ABI (FIFREEZE semantics gets changed) and trades the deadlock for massive vfsmount leak; this is going to be handled next cycle. There probably will be another pull request, but that stuff won't be in it." Fix up trivial conflicts due to unrelated changes next to each other in drivers/{staging/gdm72xx/usb_boot.c, usb/gadget/storage_common.c} * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (54 commits) delousing target_core_file a bit Documentation: Correct s_umount state for freeze_fs/unfreeze_fs fs: Remove old freezing mechanism ext2: Implement freezing btrfs: Convert to new freezing mechanism nilfs2: Convert to new freezing mechanism ntfs: Convert to new freezing mechanism fuse: Convert to new freezing mechanism gfs2: Convert to new freezing mechanism ocfs2: Convert to new freezing mechanism xfs: Convert to new freezing code ext4: Convert to new freezing mechanism fs: Protect write paths by sb_start_write - sb_end_write fs: Skip atime update on frozen filesystem fs: Add freezing handling to mnt_want_write() / mnt_drop_write() fs: Improve filesystem freezing handling switch the protection of percpu_counter list to spinlock nfsd: Push mnt_want_write() outside of i_mutex btrfs: Push mnt_want_write() outside of i_mutex fat: Push mnt_want_write() outside of i_mutex ...
Diffstat (limited to 'fs/pipe.c')
-rw-r--r--fs/pipe.c75
1 files changed, 26 insertions, 49 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index 95cbd6b227e6..8d85d7068c1e 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1016,18 +1016,16 @@ fail_inode:
1016 return NULL; 1016 return NULL;
1017} 1017}
1018 1018
1019struct file *create_write_pipe(int flags) 1019int create_pipe_files(struct file **res, int flags)
1020{ 1020{
1021 int err; 1021 int err;
1022 struct inode *inode; 1022 struct inode *inode = get_pipe_inode();
1023 struct file *f; 1023 struct file *f;
1024 struct path path; 1024 struct path path;
1025 struct qstr name = { .name = "" }; 1025 static struct qstr name = { .name = "" };
1026 1026
1027 err = -ENFILE;
1028 inode = get_pipe_inode();
1029 if (!inode) 1027 if (!inode)
1030 goto err; 1028 return -ENFILE;
1031 1029
1032 err = -ENOMEM; 1030 err = -ENOMEM;
1033 path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name); 1031 path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name);
@@ -1041,62 +1039,43 @@ struct file *create_write_pipe(int flags)
1041 f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops); 1039 f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops);
1042 if (!f) 1040 if (!f)
1043 goto err_dentry; 1041 goto err_dentry;
1044 f->f_mapping = inode->i_mapping;
1045 1042
1046 f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); 1043 f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
1047 f->f_version = 0;
1048 1044
1049 return f; 1045 res[0] = alloc_file(&path, FMODE_READ, &read_pipefifo_fops);
1046 if (!res[0])
1047 goto err_file;
1048
1049 path_get(&path);
1050 res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK);
1051 res[1] = f;
1052 return 0;
1050 1053
1051 err_dentry: 1054err_file:
1055 put_filp(f);
1056err_dentry:
1052 free_pipe_info(inode); 1057 free_pipe_info(inode);
1053 path_put(&path); 1058 path_put(&path);
1054 return ERR_PTR(err); 1059 return err;
1055 1060
1056 err_inode: 1061err_inode:
1057 free_pipe_info(inode); 1062 free_pipe_info(inode);
1058 iput(inode); 1063 iput(inode);
1059 err: 1064 return err;
1060 return ERR_PTR(err);
1061}
1062
1063void free_write_pipe(struct file *f)
1064{
1065 free_pipe_info(f->f_dentry->d_inode);
1066 path_put(&f->f_path);
1067 put_filp(f);
1068}
1069
1070struct file *create_read_pipe(struct file *wrf, int flags)
1071{
1072 /* Grab pipe from the writer */
1073 struct file *f = alloc_file(&wrf->f_path, FMODE_READ,
1074 &read_pipefifo_fops);
1075 if (!f)
1076 return ERR_PTR(-ENFILE);
1077
1078 path_get(&wrf->f_path);
1079 f->f_flags = O_RDONLY | (flags & O_NONBLOCK);
1080
1081 return f;
1082} 1065}
1083 1066
1084int do_pipe_flags(int *fd, int flags) 1067int do_pipe_flags(int *fd, int flags)
1085{ 1068{
1086 struct file *fw, *fr; 1069 struct file *files[2];
1087 int error; 1070 int error;
1088 int fdw, fdr; 1071 int fdw, fdr;
1089 1072
1090 if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT)) 1073 if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
1091 return -EINVAL; 1074 return -EINVAL;
1092 1075
1093 fw = create_write_pipe(flags); 1076 error = create_pipe_files(files, flags);
1094 if (IS_ERR(fw)) 1077 if (error)
1095 return PTR_ERR(fw); 1078 return error;
1096 fr = create_read_pipe(fw, flags);
1097 error = PTR_ERR(fr);
1098 if (IS_ERR(fr))
1099 goto err_write_pipe;
1100 1079
1101 error = get_unused_fd_flags(flags); 1080 error = get_unused_fd_flags(flags);
1102 if (error < 0) 1081 if (error < 0)
@@ -1109,8 +1088,8 @@ int do_pipe_flags(int *fd, int flags)
1109 fdw = error; 1088 fdw = error;
1110 1089
1111 audit_fd_pair(fdr, fdw); 1090 audit_fd_pair(fdr, fdw);
1112 fd_install(fdr, fr); 1091 fd_install(fdr, files[0]);
1113 fd_install(fdw, fw); 1092 fd_install(fdw, files[1]);
1114 fd[0] = fdr; 1093 fd[0] = fdr;
1115 fd[1] = fdw; 1094 fd[1] = fdw;
1116 1095
@@ -1119,10 +1098,8 @@ int do_pipe_flags(int *fd, int flags)
1119 err_fdr: 1098 err_fdr:
1120 put_unused_fd(fdr); 1099 put_unused_fd(fdr);
1121 err_read_pipe: 1100 err_read_pipe:
1122 path_put(&fr->f_path); 1101 fput(files[0]);
1123 put_filp(fr); 1102 fput(files[1]);
1124 err_write_pipe:
1125 free_write_pipe(fw);
1126 return error; 1103 return error;
1127} 1104}
1128 1105