diff options
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 45 |
1 files changed, 31 insertions, 14 deletions
@@ -382,7 +382,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, | |||
382 | error = ops->confirm(pipe, buf); | 382 | error = ops->confirm(pipe, buf); |
383 | if (error) { | 383 | if (error) { |
384 | if (!ret) | 384 | if (!ret) |
385 | error = ret; | 385 | ret = error; |
386 | break; | 386 | break; |
387 | } | 387 | } |
388 | 388 | ||
@@ -441,7 +441,7 @@ redo: | |||
441 | break; | 441 | break; |
442 | } | 442 | } |
443 | if (do_wakeup) { | 443 | if (do_wakeup) { |
444 | wake_up_interruptible_sync(&pipe->wait); | 444 | wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM); |
445 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | 445 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
446 | } | 446 | } |
447 | pipe_wait(pipe); | 447 | pipe_wait(pipe); |
@@ -450,7 +450,7 @@ redo: | |||
450 | 450 | ||
451 | /* Signal writers asynchronously that there is more room. */ | 451 | /* Signal writers asynchronously that there is more room. */ |
452 | if (do_wakeup) { | 452 | if (do_wakeup) { |
453 | wake_up_interruptible_sync(&pipe->wait); | 453 | wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM); |
454 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | 454 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
455 | } | 455 | } |
456 | if (ret > 0) | 456 | if (ret > 0) |
@@ -612,7 +612,7 @@ redo2: | |||
612 | break; | 612 | break; |
613 | } | 613 | } |
614 | if (do_wakeup) { | 614 | if (do_wakeup) { |
615 | wake_up_interruptible_sync(&pipe->wait); | 615 | wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM); |
616 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 616 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
617 | do_wakeup = 0; | 617 | do_wakeup = 0; |
618 | } | 618 | } |
@@ -623,7 +623,7 @@ redo2: | |||
623 | out: | 623 | out: |
624 | mutex_unlock(&inode->i_mutex); | 624 | mutex_unlock(&inode->i_mutex); |
625 | if (do_wakeup) { | 625 | if (do_wakeup) { |
626 | wake_up_interruptible_sync(&pipe->wait); | 626 | wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM); |
627 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 627 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
628 | } | 628 | } |
629 | if (ret > 0) | 629 | if (ret > 0) |
@@ -715,7 +715,7 @@ pipe_release(struct inode *inode, int decr, int decw) | |||
715 | if (!pipe->readers && !pipe->writers) { | 715 | if (!pipe->readers && !pipe->writers) { |
716 | free_pipe_info(inode); | 716 | free_pipe_info(inode); |
717 | } else { | 717 | } else { |
718 | wake_up_interruptible_sync(&pipe->wait); | 718 | wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM | POLLERR | POLLHUP); |
719 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 719 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
720 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | 720 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
721 | } | 721 | } |
@@ -954,6 +954,8 @@ static struct inode * get_pipe_inode(void) | |||
954 | if (!inode) | 954 | if (!inode) |
955 | goto fail_inode; | 955 | goto fail_inode; |
956 | 956 | ||
957 | inode->i_ino = get_next_ino(); | ||
958 | |||
957 | pipe = alloc_pipe_info(inode); | 959 | pipe = alloc_pipe_info(inode); |
958 | if (!pipe) | 960 | if (!pipe) |
959 | goto fail_iput; | 961 | goto fail_iput; |
@@ -997,12 +999,11 @@ struct file *create_write_pipe(int flags) | |||
997 | goto err; | 999 | goto err; |
998 | 1000 | ||
999 | err = -ENOMEM; | 1001 | err = -ENOMEM; |
1000 | path.dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); | 1002 | path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name); |
1001 | if (!path.dentry) | 1003 | if (!path.dentry) |
1002 | goto err_inode; | 1004 | goto err_inode; |
1003 | path.mnt = mntget(pipe_mnt); | 1005 | path.mnt = mntget(pipe_mnt); |
1004 | 1006 | ||
1005 | path.dentry->d_op = &pipefs_dentry_operations; | ||
1006 | d_instantiate(path.dentry, inode); | 1007 | d_instantiate(path.dentry, inode); |
1007 | 1008 | ||
1008 | err = -ENFILE; | 1009 | err = -ENFILE; |
@@ -1197,12 +1198,24 @@ int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, | |||
1197 | return ret; | 1198 | return ret; |
1198 | } | 1199 | } |
1199 | 1200 | ||
1201 | /* | ||
1202 | * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same | ||
1203 | * location, so checking ->i_pipe is not enough to verify that this is a | ||
1204 | * pipe. | ||
1205 | */ | ||
1206 | struct pipe_inode_info *get_pipe_info(struct file *file) | ||
1207 | { | ||
1208 | struct inode *i = file->f_path.dentry->d_inode; | ||
1209 | |||
1210 | return S_ISFIFO(i->i_mode) ? i->i_pipe : NULL; | ||
1211 | } | ||
1212 | |||
1200 | long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | 1213 | long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) |
1201 | { | 1214 | { |
1202 | struct pipe_inode_info *pipe; | 1215 | struct pipe_inode_info *pipe; |
1203 | long ret; | 1216 | long ret; |
1204 | 1217 | ||
1205 | pipe = file->f_path.dentry->d_inode->i_pipe; | 1218 | pipe = get_pipe_info(file); |
1206 | if (!pipe) | 1219 | if (!pipe) |
1207 | return -EBADF; | 1220 | return -EBADF; |
1208 | 1221 | ||
@@ -1239,22 +1252,26 @@ out: | |||
1239 | return ret; | 1252 | return ret; |
1240 | } | 1253 | } |
1241 | 1254 | ||
1255 | static const struct super_operations pipefs_ops = { | ||
1256 | .destroy_inode = free_inode_nonrcu, | ||
1257 | }; | ||
1258 | |||
1242 | /* | 1259 | /* |
1243 | * pipefs should _never_ be mounted by userland - too much of security hassle, | 1260 | * pipefs should _never_ be mounted by userland - too much of security hassle, |
1244 | * no real gain from having the whole whorehouse mounted. So we don't need | 1261 | * no real gain from having the whole whorehouse mounted. So we don't need |
1245 | * any operations on the root directory. However, we need a non-trivial | 1262 | * any operations on the root directory. However, we need a non-trivial |
1246 | * d_name - pipe: will go nicely and kill the special-casing in procfs. | 1263 | * d_name - pipe: will go nicely and kill the special-casing in procfs. |
1247 | */ | 1264 | */ |
1248 | static int pipefs_get_sb(struct file_system_type *fs_type, | 1265 | static struct dentry *pipefs_mount(struct file_system_type *fs_type, |
1249 | int flags, const char *dev_name, void *data, | 1266 | int flags, const char *dev_name, void *data) |
1250 | struct vfsmount *mnt) | ||
1251 | { | 1267 | { |
1252 | return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC, mnt); | 1268 | return mount_pseudo(fs_type, "pipe:", &pipefs_ops, |
1269 | &pipefs_dentry_operations, PIPEFS_MAGIC); | ||
1253 | } | 1270 | } |
1254 | 1271 | ||
1255 | static struct file_system_type pipe_fs_type = { | 1272 | static struct file_system_type pipe_fs_type = { |
1256 | .name = "pipefs", | 1273 | .name = "pipefs", |
1257 | .get_sb = pipefs_get_sb, | 1274 | .mount = pipefs_mount, |
1258 | .kill_sb = kill_anon_super, | 1275 | .kill_sb = kill_anon_super, |
1259 | }; | 1276 | }; |
1260 | 1277 | ||