diff options
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 214 |
1 files changed, 115 insertions, 99 deletions
@@ -218,9 +218,10 @@ static struct pipe_buf_operations anon_pipe_buf_ops = { | |||
218 | }; | 218 | }; |
219 | 219 | ||
220 | static ssize_t | 220 | static ssize_t |
221 | pipe_readv(struct file *filp, const struct iovec *_iov, | 221 | pipe_read(struct kiocb *iocb, const struct iovec *_iov, |
222 | unsigned long nr_segs, loff_t *ppos) | 222 | unsigned long nr_segs, loff_t pos) |
223 | { | 223 | { |
224 | struct file *filp = iocb->ki_filp; | ||
224 | struct inode *inode = filp->f_dentry->d_inode; | 225 | struct inode *inode = filp->f_dentry->d_inode; |
225 | struct pipe_inode_info *pipe; | 226 | struct pipe_inode_info *pipe; |
226 | int do_wakeup; | 227 | int do_wakeup; |
@@ -330,17 +331,10 @@ redo: | |||
330 | } | 331 | } |
331 | 332 | ||
332 | static ssize_t | 333 | static ssize_t |
333 | pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | 334 | pipe_write(struct kiocb *iocb, const struct iovec *_iov, |
334 | { | 335 | unsigned long nr_segs, loff_t ppos) |
335 | struct iovec iov = { .iov_base = buf, .iov_len = count }; | ||
336 | |||
337 | return pipe_readv(filp, &iov, 1, ppos); | ||
338 | } | ||
339 | |||
340 | static ssize_t | ||
341 | pipe_writev(struct file *filp, const struct iovec *_iov, | ||
342 | unsigned long nr_segs, loff_t *ppos) | ||
343 | { | 336 | { |
337 | struct file *filp = iocb->ki_filp; | ||
344 | struct inode *inode = filp->f_dentry->d_inode; | 338 | struct inode *inode = filp->f_dentry->d_inode; |
345 | struct pipe_inode_info *pipe; | 339 | struct pipe_inode_info *pipe; |
346 | ssize_t ret; | 340 | ssize_t ret; |
@@ -510,15 +504,6 @@ out: | |||
510 | } | 504 | } |
511 | 505 | ||
512 | static ssize_t | 506 | static ssize_t |
513 | pipe_write(struct file *filp, const char __user *buf, | ||
514 | size_t count, loff_t *ppos) | ||
515 | { | ||
516 | struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; | ||
517 | |||
518 | return pipe_writev(filp, &iov, 1, ppos); | ||
519 | } | ||
520 | |||
521 | static ssize_t | ||
522 | bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | 507 | bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) |
523 | { | 508 | { |
524 | return -EBADF; | 509 | return -EBADF; |
@@ -736,8 +721,8 @@ pipe_rdwr_open(struct inode *inode, struct file *filp) | |||
736 | */ | 721 | */ |
737 | const struct file_operations read_fifo_fops = { | 722 | const struct file_operations read_fifo_fops = { |
738 | .llseek = no_llseek, | 723 | .llseek = no_llseek, |
739 | .read = pipe_read, | 724 | .read = do_sync_read, |
740 | .readv = pipe_readv, | 725 | .aio_read = pipe_read, |
741 | .write = bad_pipe_w, | 726 | .write = bad_pipe_w, |
742 | .poll = pipe_poll, | 727 | .poll = pipe_poll, |
743 | .ioctl = pipe_ioctl, | 728 | .ioctl = pipe_ioctl, |
@@ -749,8 +734,8 @@ const struct file_operations read_fifo_fops = { | |||
749 | const struct file_operations write_fifo_fops = { | 734 | const struct file_operations write_fifo_fops = { |
750 | .llseek = no_llseek, | 735 | .llseek = no_llseek, |
751 | .read = bad_pipe_r, | 736 | .read = bad_pipe_r, |
752 | .write = pipe_write, | 737 | .write = do_sync_write, |
753 | .writev = pipe_writev, | 738 | .aio_write = pipe_write, |
754 | .poll = pipe_poll, | 739 | .poll = pipe_poll, |
755 | .ioctl = pipe_ioctl, | 740 | .ioctl = pipe_ioctl, |
756 | .open = pipe_write_open, | 741 | .open = pipe_write_open, |
@@ -760,10 +745,10 @@ const struct file_operations write_fifo_fops = { | |||
760 | 745 | ||
761 | const struct file_operations rdwr_fifo_fops = { | 746 | const struct file_operations rdwr_fifo_fops = { |
762 | .llseek = no_llseek, | 747 | .llseek = no_llseek, |
763 | .read = pipe_read, | 748 | .read = do_sync_read, |
764 | .readv = pipe_readv, | 749 | .aio_read = pipe_read, |
765 | .write = pipe_write, | 750 | .write = do_sync_write, |
766 | .writev = pipe_writev, | 751 | .aio_write = pipe_write, |
767 | .poll = pipe_poll, | 752 | .poll = pipe_poll, |
768 | .ioctl = pipe_ioctl, | 753 | .ioctl = pipe_ioctl, |
769 | .open = pipe_rdwr_open, | 754 | .open = pipe_rdwr_open, |
@@ -773,8 +758,8 @@ const struct file_operations rdwr_fifo_fops = { | |||
773 | 758 | ||
774 | static struct file_operations read_pipe_fops = { | 759 | static struct file_operations read_pipe_fops = { |
775 | .llseek = no_llseek, | 760 | .llseek = no_llseek, |
776 | .read = pipe_read, | 761 | .read = do_sync_read, |
777 | .readv = pipe_readv, | 762 | .aio_read = pipe_read, |
778 | .write = bad_pipe_w, | 763 | .write = bad_pipe_w, |
779 | .poll = pipe_poll, | 764 | .poll = pipe_poll, |
780 | .ioctl = pipe_ioctl, | 765 | .ioctl = pipe_ioctl, |
@@ -786,8 +771,8 @@ static struct file_operations read_pipe_fops = { | |||
786 | static struct file_operations write_pipe_fops = { | 771 | static struct file_operations write_pipe_fops = { |
787 | .llseek = no_llseek, | 772 | .llseek = no_llseek, |
788 | .read = bad_pipe_r, | 773 | .read = bad_pipe_r, |
789 | .write = pipe_write, | 774 | .write = do_sync_write, |
790 | .writev = pipe_writev, | 775 | .aio_write = pipe_write, |
791 | .poll = pipe_poll, | 776 | .poll = pipe_poll, |
792 | .ioctl = pipe_ioctl, | 777 | .ioctl = pipe_ioctl, |
793 | .open = pipe_write_open, | 778 | .open = pipe_write_open, |
@@ -797,10 +782,10 @@ static struct file_operations write_pipe_fops = { | |||
797 | 782 | ||
798 | static struct file_operations rdwr_pipe_fops = { | 783 | static struct file_operations rdwr_pipe_fops = { |
799 | .llseek = no_llseek, | 784 | .llseek = no_llseek, |
800 | .read = pipe_read, | 785 | .read = do_sync_read, |
801 | .readv = pipe_readv, | 786 | .aio_read = pipe_read, |
802 | .write = pipe_write, | 787 | .write = do_sync_write, |
803 | .writev = pipe_writev, | 788 | .aio_write = pipe_write, |
804 | .poll = pipe_poll, | 789 | .poll = pipe_poll, |
805 | .ioctl = pipe_ioctl, | 790 | .ioctl = pipe_ioctl, |
806 | .open = pipe_rdwr_open, | 791 | .open = pipe_rdwr_open, |
@@ -889,87 +874,118 @@ fail_inode: | |||
889 | return NULL; | 874 | return NULL; |
890 | } | 875 | } |
891 | 876 | ||
892 | int do_pipe(int *fd) | 877 | struct file *create_write_pipe(void) |
893 | { | 878 | { |
894 | struct qstr this; | 879 | int err; |
895 | char name[32]; | 880 | struct inode *inode; |
881 | struct file *f; | ||
896 | struct dentry *dentry; | 882 | struct dentry *dentry; |
897 | struct inode * inode; | 883 | char name[32]; |
898 | struct file *f1, *f2; | 884 | struct qstr this; |
899 | int error; | ||
900 | int i, j; | ||
901 | |||
902 | error = -ENFILE; | ||
903 | f1 = get_empty_filp(); | ||
904 | if (!f1) | ||
905 | goto no_files; | ||
906 | |||
907 | f2 = get_empty_filp(); | ||
908 | if (!f2) | ||
909 | goto close_f1; | ||
910 | 885 | ||
886 | f = get_empty_filp(); | ||
887 | if (!f) | ||
888 | return ERR_PTR(-ENFILE); | ||
889 | err = -ENFILE; | ||
911 | inode = get_pipe_inode(); | 890 | inode = get_pipe_inode(); |
912 | if (!inode) | 891 | if (!inode) |
913 | goto close_f12; | 892 | goto err_file; |
914 | |||
915 | error = get_unused_fd(); | ||
916 | if (error < 0) | ||
917 | goto close_f12_inode; | ||
918 | i = error; | ||
919 | |||
920 | error = get_unused_fd(); | ||
921 | if (error < 0) | ||
922 | goto close_f12_inode_i; | ||
923 | j = error; | ||
924 | 893 | ||
925 | error = -ENOMEM; | ||
926 | sprintf(name, "[%lu]", inode->i_ino); | 894 | sprintf(name, "[%lu]", inode->i_ino); |
927 | this.name = name; | 895 | this.name = name; |
928 | this.len = strlen(name); | 896 | this.len = strlen(name); |
929 | this.hash = inode->i_ino; /* will go */ | 897 | this.hash = inode->i_ino; /* will go */ |
898 | err = -ENOMEM; | ||
930 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); | 899 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); |
931 | if (!dentry) | 900 | if (!dentry) |
932 | goto close_f12_inode_i_j; | 901 | goto err_inode; |
933 | 902 | ||
934 | dentry->d_op = &pipefs_dentry_operations; | 903 | dentry->d_op = &pipefs_dentry_operations; |
935 | d_add(dentry, inode); | 904 | d_add(dentry, inode); |
936 | f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); | 905 | f->f_vfsmnt = mntget(pipe_mnt); |
937 | f1->f_dentry = f2->f_dentry = dget(dentry); | 906 | f->f_dentry = dentry; |
938 | f1->f_mapping = f2->f_mapping = inode->i_mapping; | 907 | f->f_mapping = inode->i_mapping; |
939 | |||
940 | /* read file */ | ||
941 | f1->f_pos = f2->f_pos = 0; | ||
942 | f1->f_flags = O_RDONLY; | ||
943 | f1->f_op = &read_pipe_fops; | ||
944 | f1->f_mode = FMODE_READ; | ||
945 | f1->f_version = 0; | ||
946 | |||
947 | /* write file */ | ||
948 | f2->f_flags = O_WRONLY; | ||
949 | f2->f_op = &write_pipe_fops; | ||
950 | f2->f_mode = FMODE_WRITE; | ||
951 | f2->f_version = 0; | ||
952 | |||
953 | fd_install(i, f1); | ||
954 | fd_install(j, f2); | ||
955 | fd[0] = i; | ||
956 | fd[1] = j; | ||
957 | 908 | ||
958 | return 0; | 909 | f->f_flags = O_WRONLY; |
910 | f->f_op = &write_pipe_fops; | ||
911 | f->f_mode = FMODE_WRITE; | ||
912 | f->f_version = 0; | ||
913 | |||
914 | return f; | ||
959 | 915 | ||
960 | close_f12_inode_i_j: | 916 | err_inode: |
961 | put_unused_fd(j); | ||
962 | close_f12_inode_i: | ||
963 | put_unused_fd(i); | ||
964 | close_f12_inode: | ||
965 | free_pipe_info(inode); | 917 | free_pipe_info(inode); |
966 | iput(inode); | 918 | iput(inode); |
967 | close_f12: | 919 | err_file: |
968 | put_filp(f2); | 920 | put_filp(f); |
969 | close_f1: | 921 | return ERR_PTR(err); |
970 | put_filp(f1); | 922 | } |
971 | no_files: | 923 | |
972 | return error; | 924 | void free_write_pipe(struct file *f) |
925 | { | ||
926 | mntput(f->f_vfsmnt); | ||
927 | dput(f->f_dentry); | ||
928 | put_filp(f); | ||
929 | } | ||
930 | |||
931 | struct file *create_read_pipe(struct file *wrf) | ||
932 | { | ||
933 | struct file *f = get_empty_filp(); | ||
934 | if (!f) | ||
935 | return ERR_PTR(-ENFILE); | ||
936 | |||
937 | /* Grab pipe from the writer */ | ||
938 | f->f_vfsmnt = mntget(wrf->f_vfsmnt); | ||
939 | f->f_dentry = dget(wrf->f_dentry); | ||
940 | f->f_mapping = wrf->f_dentry->d_inode->i_mapping; | ||
941 | |||
942 | f->f_pos = 0; | ||
943 | f->f_flags = O_RDONLY; | ||
944 | f->f_op = &read_pipe_fops; | ||
945 | f->f_mode = FMODE_READ; | ||
946 | f->f_version = 0; | ||
947 | |||
948 | return f; | ||
949 | } | ||
950 | |||
951 | int do_pipe(int *fd) | ||
952 | { | ||
953 | struct file *fw, *fr; | ||
954 | int error; | ||
955 | int fdw, fdr; | ||
956 | |||
957 | fw = create_write_pipe(); | ||
958 | if (IS_ERR(fw)) | ||
959 | return PTR_ERR(fw); | ||
960 | fr = create_read_pipe(fw); | ||
961 | error = PTR_ERR(fr); | ||
962 | if (IS_ERR(fr)) | ||
963 | goto err_write_pipe; | ||
964 | |||
965 | error = get_unused_fd(); | ||
966 | if (error < 0) | ||
967 | goto err_read_pipe; | ||
968 | fdr = error; | ||
969 | |||
970 | error = get_unused_fd(); | ||
971 | if (error < 0) | ||
972 | goto err_fdr; | ||
973 | fdw = error; | ||
974 | |||
975 | fd_install(fdr, fr); | ||
976 | fd_install(fdw, fw); | ||
977 | fd[0] = fdr; | ||
978 | fd[1] = fdw; | ||
979 | |||
980 | return 0; | ||
981 | |||
982 | err_fdr: | ||
983 | put_unused_fd(fdr); | ||
984 | err_read_pipe: | ||
985 | put_filp(fr); | ||
986 | err_write_pipe: | ||
987 | free_write_pipe(fw); | ||
988 | return error; | ||
973 | } | 989 | } |
974 | 990 | ||
975 | /* | 991 | /* |