diff options
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 45 |
1 files changed, 11 insertions, 34 deletions
@@ -906,17 +906,6 @@ void free_pipe_info(struct inode *inode) | |||
906 | } | 906 | } |
907 | 907 | ||
908 | static struct vfsmount *pipe_mnt __read_mostly; | 908 | static struct vfsmount *pipe_mnt __read_mostly; |
909 | static int pipefs_delete_dentry(struct dentry *dentry) | ||
910 | { | ||
911 | /* | ||
912 | * At creation time, we pretended this dentry was hashed | ||
913 | * (by clearing DCACHE_UNHASHED bit in d_flags) | ||
914 | * At delete time, we restore the truth : not hashed. | ||
915 | * (so that dput() can proceed correctly) | ||
916 | */ | ||
917 | dentry->d_flags |= DCACHE_UNHASHED; | ||
918 | return 0; | ||
919 | } | ||
920 | 909 | ||
921 | /* | 910 | /* |
922 | * pipefs_dname() is called from d_path(). | 911 | * pipefs_dname() is called from d_path(). |
@@ -928,7 +917,6 @@ static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen) | |||
928 | } | 917 | } |
929 | 918 | ||
930 | static const struct dentry_operations pipefs_dentry_operations = { | 919 | static const struct dentry_operations pipefs_dentry_operations = { |
931 | .d_delete = pipefs_delete_dentry, | ||
932 | .d_dname = pipefs_dname, | 920 | .d_dname = pipefs_dname, |
933 | }; | 921 | }; |
934 | 922 | ||
@@ -974,7 +962,7 @@ struct file *create_write_pipe(int flags) | |||
974 | int err; | 962 | int err; |
975 | struct inode *inode; | 963 | struct inode *inode; |
976 | struct file *f; | 964 | struct file *f; |
977 | struct dentry *dentry; | 965 | struct path path; |
978 | struct qstr name = { .name = "" }; | 966 | struct qstr name = { .name = "" }; |
979 | 967 | ||
980 | err = -ENFILE; | 968 | err = -ENFILE; |
@@ -983,21 +971,16 @@ struct file *create_write_pipe(int flags) | |||
983 | goto err; | 971 | goto err; |
984 | 972 | ||
985 | err = -ENOMEM; | 973 | err = -ENOMEM; |
986 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); | 974 | path.dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); |
987 | if (!dentry) | 975 | if (!path.dentry) |
988 | goto err_inode; | 976 | goto err_inode; |
977 | path.mnt = mntget(pipe_mnt); | ||
989 | 978 | ||
990 | dentry->d_op = &pipefs_dentry_operations; | 979 | path.dentry->d_op = &pipefs_dentry_operations; |
991 | /* | 980 | d_instantiate(path.dentry, inode); |
992 | * We dont want to publish this dentry into global dentry hash table. | ||
993 | * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED | ||
994 | * This permits a working /proc/$pid/fd/XXX on pipes | ||
995 | */ | ||
996 | dentry->d_flags &= ~DCACHE_UNHASHED; | ||
997 | d_instantiate(dentry, inode); | ||
998 | 981 | ||
999 | err = -ENFILE; | 982 | err = -ENFILE; |
1000 | f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipefifo_fops); | 983 | f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops); |
1001 | if (!f) | 984 | if (!f) |
1002 | goto err_dentry; | 985 | goto err_dentry; |
1003 | f->f_mapping = inode->i_mapping; | 986 | f->f_mapping = inode->i_mapping; |
@@ -1009,7 +992,7 @@ struct file *create_write_pipe(int flags) | |||
1009 | 992 | ||
1010 | err_dentry: | 993 | err_dentry: |
1011 | free_pipe_info(inode); | 994 | free_pipe_info(inode); |
1012 | dput(dentry); | 995 | path_put(&path); |
1013 | return ERR_PTR(err); | 996 | return ERR_PTR(err); |
1014 | 997 | ||
1015 | err_inode: | 998 | err_inode: |
@@ -1028,20 +1011,14 @@ void free_write_pipe(struct file *f) | |||
1028 | 1011 | ||
1029 | struct file *create_read_pipe(struct file *wrf, int flags) | 1012 | struct file *create_read_pipe(struct file *wrf, int flags) |
1030 | { | 1013 | { |
1031 | struct file *f = get_empty_filp(); | 1014 | /* Grab pipe from the writer */ |
1015 | struct file *f = alloc_file(&wrf->f_path, FMODE_READ, | ||
1016 | &read_pipefifo_fops); | ||
1032 | if (!f) | 1017 | if (!f) |
1033 | return ERR_PTR(-ENFILE); | 1018 | return ERR_PTR(-ENFILE); |
1034 | 1019 | ||
1035 | /* Grab pipe from the writer */ | ||
1036 | f->f_path = wrf->f_path; | ||
1037 | path_get(&wrf->f_path); | 1020 | path_get(&wrf->f_path); |
1038 | f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; | ||
1039 | |||
1040 | f->f_pos = 0; | ||
1041 | f->f_flags = O_RDONLY | (flags & O_NONBLOCK); | 1021 | f->f_flags = O_RDONLY | (flags & O_NONBLOCK); |
1042 | f->f_op = &read_pipefifo_fops; | ||
1043 | f->f_mode = FMODE_READ; | ||
1044 | f->f_version = 0; | ||
1045 | 1022 | ||
1046 | return f; | 1023 | return f; |
1047 | } | 1024 | } |