aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-10-01 02:29:26 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:33 -0400
commitd6cbd281d189977b38eac7eb2a4678de19b6b483 (patch)
treef853d303687275cd4328bfac53780b7c7c2c67ef
parent65da4d81f48e092f71feaf04bf2ccd096b5a5171 (diff)
[PATCH] Some cleanup in the pipe code
Split the big and hard to read do_pipe function into smaller pieces. This creates new create_write_pipe/free_write_pipe/create_read_pipe functions. These functions are made global so that they can be used by other parts of the kernel. The resulting code is more generic and easier to read and has cleaner error handling and less gotos. [akpm@osdl.org: cleanup] Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/pipe.c155
-rw-r--r--include/linux/fs.h3
2 files changed, 96 insertions, 62 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index 2e60e1c8815..b1626f269a3 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -874,87 +874,118 @@ fail_inode:
874 return NULL; 874 return NULL;
875} 875}
876 876
877int do_pipe(int *fd) 877struct 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
945close_f12_inode_i_j: 914 return f;
946 put_unused_fd(j); 915
947close_f12_inode_i: 916 err_inode:
948 put_unused_fd(i);
949close_f12_inode:
950 free_pipe_info(inode); 917 free_pipe_info(inode);
951 iput(inode); 918 iput(inode);
952close_f12: 919 err_file:
953 put_filp(f2); 920 put_filp(f);
954close_f1: 921 return ERR_PTR(err);
955 put_filp(f1); 922}
956no_files: 923
957 return error; 924void free_write_pipe(struct file *f)
925{
926 mntput(f->f_vfsmnt);
927 dput(f->f_dentry);
928 put_filp(f);
929}
930
931struct 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
951int 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/*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3493d2828f7..2e29a2edaee 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1641,6 +1641,9 @@ static inline void allow_write_access(struct file *file)
1641 atomic_inc(&file->f_dentry->d_inode->i_writecount); 1641 atomic_inc(&file->f_dentry->d_inode->i_writecount);
1642} 1642}
1643extern int do_pipe(int *); 1643extern int do_pipe(int *);
1644extern struct file *create_read_pipe(struct file *f);
1645extern struct file *create_write_pipe(void);
1646extern void free_write_pipe(struct file *);
1644 1647
1645extern int open_namei(int dfd, const char *, int, int, struct nameidata *); 1648extern int open_namei(int dfd, const char *, int, int, struct nameidata *);
1646extern int may_open(struct nameidata *, int, int); 1649extern int may_open(struct nameidata *, int, int);