diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/pipe.c | 155 |
1 files changed, 93 insertions, 62 deletions
@@ -874,87 +874,118 @@ fail_inode: | |||
874 | return NULL; | 874 | return NULL; |
875 | } | 875 | } |
876 | 876 | ||
877 | int do_pipe(int *fd) | 877 | struct file *create_write_pipe(void) |
878 | { | 878 | { |
879 | struct qstr this; | 879 | int err; |
880 | char name[32]; | 880 | struct inode *inode; |
881 | struct file *f; | ||
881 | struct dentry *dentry; | 882 | struct dentry *dentry; |
882 | struct inode * inode; | 883 | char name[32]; |
883 | struct file *f1, *f2; | 884 | struct qstr this; |
884 | int error; | ||
885 | int i, j; | ||
886 | |||
887 | error = -ENFILE; | ||
888 | f1 = get_empty_filp(); | ||
889 | if (!f1) | ||
890 | goto no_files; | ||
891 | |||
892 | f2 = get_empty_filp(); | ||
893 | if (!f2) | ||
894 | goto close_f1; | ||
895 | 885 | ||
886 | f = get_empty_filp(); | ||
887 | if (!f) | ||
888 | return ERR_PTR(-ENFILE); | ||
889 | err = -ENFILE; | ||
896 | inode = get_pipe_inode(); | 890 | inode = get_pipe_inode(); |
897 | if (!inode) | 891 | if (!inode) |
898 | goto close_f12; | 892 | goto err_file; |
899 | 893 | ||
900 | error = get_unused_fd(); | ||
901 | if (error < 0) | ||
902 | goto close_f12_inode; | ||
903 | i = error; | ||
904 | |||
905 | error = get_unused_fd(); | ||
906 | if (error < 0) | ||
907 | goto close_f12_inode_i; | ||
908 | j = error; | ||
909 | |||
910 | error = -ENOMEM; | ||
911 | sprintf(name, "[%lu]", inode->i_ino); | 894 | sprintf(name, "[%lu]", inode->i_ino); |
912 | this.name = name; | 895 | this.name = name; |
913 | this.len = strlen(name); | 896 | this.len = strlen(name); |
914 | this.hash = inode->i_ino; /* will go */ | 897 | this.hash = inode->i_ino; /* will go */ |
898 | err = -ENOMEM; | ||
915 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); | 899 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); |
916 | if (!dentry) | 900 | if (!dentry) |
917 | goto close_f12_inode_i_j; | 901 | goto err_inode; |
918 | 902 | ||
919 | dentry->d_op = &pipefs_dentry_operations; | 903 | dentry->d_op = &pipefs_dentry_operations; |
920 | d_add(dentry, inode); | 904 | d_add(dentry, inode); |
921 | f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); | 905 | f->f_vfsmnt = mntget(pipe_mnt); |
922 | f1->f_dentry = f2->f_dentry = dget(dentry); | 906 | f->f_dentry = dentry; |
923 | f1->f_mapping = f2->f_mapping = inode->i_mapping; | 907 | f->f_mapping = inode->i_mapping; |
924 | |||
925 | /* read file */ | ||
926 | f1->f_pos = f2->f_pos = 0; | ||
927 | f1->f_flags = O_RDONLY; | ||
928 | f1->f_op = &read_pipe_fops; | ||
929 | f1->f_mode = FMODE_READ; | ||
930 | f1->f_version = 0; | ||
931 | |||
932 | /* write file */ | ||
933 | f2->f_flags = O_WRONLY; | ||
934 | f2->f_op = &write_pipe_fops; | ||
935 | f2->f_mode = FMODE_WRITE; | ||
936 | f2->f_version = 0; | ||
937 | |||
938 | fd_install(i, f1); | ||
939 | fd_install(j, f2); | ||
940 | fd[0] = i; | ||
941 | fd[1] = j; | ||
942 | 908 | ||
943 | 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; | ||
944 | 913 | ||
945 | close_f12_inode_i_j: | 914 | return f; |
946 | put_unused_fd(j); | 915 | |
947 | close_f12_inode_i: | 916 | err_inode: |
948 | put_unused_fd(i); | ||
949 | close_f12_inode: | ||
950 | free_pipe_info(inode); | 917 | free_pipe_info(inode); |
951 | iput(inode); | 918 | iput(inode); |
952 | close_f12: | 919 | err_file: |
953 | put_filp(f2); | 920 | put_filp(f); |
954 | close_f1: | 921 | return ERR_PTR(err); |
955 | put_filp(f1); | 922 | } |
956 | no_files: | 923 | |
957 | 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; | ||
958 | } | 989 | } |
959 | 990 | ||
960 | /* | 991 | /* |