diff options
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 65 |
1 files changed, 40 insertions, 25 deletions
@@ -207,7 +207,7 @@ int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf) | |||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static struct pipe_buf_operations anon_pipe_buf_ops = { | 210 | static const struct pipe_buf_operations anon_pipe_buf_ops = { |
211 | .can_merge = 1, | 211 | .can_merge = 1, |
212 | .map = generic_pipe_buf_map, | 212 | .map = generic_pipe_buf_map, |
213 | .unmap = generic_pipe_buf_unmap, | 213 | .unmap = generic_pipe_buf_unmap, |
@@ -222,7 +222,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, | |||
222 | unsigned long nr_segs, loff_t pos) | 222 | unsigned long nr_segs, loff_t pos) |
223 | { | 223 | { |
224 | struct file *filp = iocb->ki_filp; | 224 | struct file *filp = iocb->ki_filp; |
225 | struct inode *inode = filp->f_dentry->d_inode; | 225 | struct inode *inode = filp->f_path.dentry->d_inode; |
226 | struct pipe_inode_info *pipe; | 226 | struct pipe_inode_info *pipe; |
227 | int do_wakeup; | 227 | int do_wakeup; |
228 | ssize_t ret; | 228 | ssize_t ret; |
@@ -243,7 +243,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, | |||
243 | if (bufs) { | 243 | if (bufs) { |
244 | int curbuf = pipe->curbuf; | 244 | int curbuf = pipe->curbuf; |
245 | struct pipe_buffer *buf = pipe->bufs + curbuf; | 245 | struct pipe_buffer *buf = pipe->bufs + curbuf; |
246 | struct pipe_buf_operations *ops = buf->ops; | 246 | const struct pipe_buf_operations *ops = buf->ops; |
247 | void *addr; | 247 | void *addr; |
248 | size_t chars = buf->len; | 248 | size_t chars = buf->len; |
249 | int error, atomic; | 249 | int error, atomic; |
@@ -335,7 +335,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, | |||
335 | unsigned long nr_segs, loff_t ppos) | 335 | unsigned long nr_segs, loff_t ppos) |
336 | { | 336 | { |
337 | struct file *filp = iocb->ki_filp; | 337 | struct file *filp = iocb->ki_filp; |
338 | struct inode *inode = filp->f_dentry->d_inode; | 338 | struct inode *inode = filp->f_path.dentry->d_inode; |
339 | struct pipe_inode_info *pipe; | 339 | struct pipe_inode_info *pipe; |
340 | ssize_t ret; | 340 | ssize_t ret; |
341 | int do_wakeup; | 341 | int do_wakeup; |
@@ -365,7 +365,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, | |||
365 | int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & | 365 | int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & |
366 | (PIPE_BUFFERS-1); | 366 | (PIPE_BUFFERS-1); |
367 | struct pipe_buffer *buf = pipe->bufs + lastbuf; | 367 | struct pipe_buffer *buf = pipe->bufs + lastbuf; |
368 | struct pipe_buf_operations *ops = buf->ops; | 368 | const struct pipe_buf_operations *ops = buf->ops; |
369 | int offset = buf->offset + buf->len; | 369 | int offset = buf->offset + buf->len; |
370 | 370 | ||
371 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { | 371 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { |
@@ -520,7 +520,7 @@ static int | |||
520 | pipe_ioctl(struct inode *pino, struct file *filp, | 520 | pipe_ioctl(struct inode *pino, struct file *filp, |
521 | unsigned int cmd, unsigned long arg) | 521 | unsigned int cmd, unsigned long arg) |
522 | { | 522 | { |
523 | struct inode *inode = filp->f_dentry->d_inode; | 523 | struct inode *inode = filp->f_path.dentry->d_inode; |
524 | struct pipe_inode_info *pipe; | 524 | struct pipe_inode_info *pipe; |
525 | int count, buf, nrbufs; | 525 | int count, buf, nrbufs; |
526 | 526 | ||
@@ -548,7 +548,7 @@ static unsigned int | |||
548 | pipe_poll(struct file *filp, poll_table *wait) | 548 | pipe_poll(struct file *filp, poll_table *wait) |
549 | { | 549 | { |
550 | unsigned int mask; | 550 | unsigned int mask; |
551 | struct inode *inode = filp->f_dentry->d_inode; | 551 | struct inode *inode = filp->f_path.dentry->d_inode; |
552 | struct pipe_inode_info *pipe = inode->i_pipe; | 552 | struct pipe_inode_info *pipe = inode->i_pipe; |
553 | int nrbufs; | 553 | int nrbufs; |
554 | 554 | ||
@@ -601,7 +601,7 @@ pipe_release(struct inode *inode, int decr, int decw) | |||
601 | static int | 601 | static int |
602 | pipe_read_fasync(int fd, struct file *filp, int on) | 602 | pipe_read_fasync(int fd, struct file *filp, int on) |
603 | { | 603 | { |
604 | struct inode *inode = filp->f_dentry->d_inode; | 604 | struct inode *inode = filp->f_path.dentry->d_inode; |
605 | int retval; | 605 | int retval; |
606 | 606 | ||
607 | mutex_lock(&inode->i_mutex); | 607 | mutex_lock(&inode->i_mutex); |
@@ -618,7 +618,7 @@ pipe_read_fasync(int fd, struct file *filp, int on) | |||
618 | static int | 618 | static int |
619 | pipe_write_fasync(int fd, struct file *filp, int on) | 619 | pipe_write_fasync(int fd, struct file *filp, int on) |
620 | { | 620 | { |
621 | struct inode *inode = filp->f_dentry->d_inode; | 621 | struct inode *inode = filp->f_path.dentry->d_inode; |
622 | int retval; | 622 | int retval; |
623 | 623 | ||
624 | mutex_lock(&inode->i_mutex); | 624 | mutex_lock(&inode->i_mutex); |
@@ -635,7 +635,7 @@ pipe_write_fasync(int fd, struct file *filp, int on) | |||
635 | static int | 635 | static int |
636 | pipe_rdwr_fasync(int fd, struct file *filp, int on) | 636 | pipe_rdwr_fasync(int fd, struct file *filp, int on) |
637 | { | 637 | { |
638 | struct inode *inode = filp->f_dentry->d_inode; | 638 | struct inode *inode = filp->f_path.dentry->d_inode; |
639 | struct pipe_inode_info *pipe = inode->i_pipe; | 639 | struct pipe_inode_info *pipe = inode->i_pipe; |
640 | int retval; | 640 | int retval; |
641 | 641 | ||
@@ -756,7 +756,7 @@ const struct file_operations rdwr_fifo_fops = { | |||
756 | .fasync = pipe_rdwr_fasync, | 756 | .fasync = pipe_rdwr_fasync, |
757 | }; | 757 | }; |
758 | 758 | ||
759 | static struct file_operations read_pipe_fops = { | 759 | static const struct file_operations read_pipe_fops = { |
760 | .llseek = no_llseek, | 760 | .llseek = no_llseek, |
761 | .read = do_sync_read, | 761 | .read = do_sync_read, |
762 | .aio_read = pipe_read, | 762 | .aio_read = pipe_read, |
@@ -768,7 +768,7 @@ static struct file_operations read_pipe_fops = { | |||
768 | .fasync = pipe_read_fasync, | 768 | .fasync = pipe_read_fasync, |
769 | }; | 769 | }; |
770 | 770 | ||
771 | static struct file_operations write_pipe_fops = { | 771 | static const struct file_operations write_pipe_fops = { |
772 | .llseek = no_llseek, | 772 | .llseek = no_llseek, |
773 | .read = bad_pipe_r, | 773 | .read = bad_pipe_r, |
774 | .write = do_sync_write, | 774 | .write = do_sync_write, |
@@ -780,7 +780,7 @@ static struct file_operations write_pipe_fops = { | |||
780 | .fasync = pipe_write_fasync, | 780 | .fasync = pipe_write_fasync, |
781 | }; | 781 | }; |
782 | 782 | ||
783 | static struct file_operations rdwr_pipe_fops = { | 783 | static const struct file_operations rdwr_pipe_fops = { |
784 | .llseek = no_llseek, | 784 | .llseek = no_llseek, |
785 | .read = do_sync_read, | 785 | .read = do_sync_read, |
786 | .aio_read = pipe_read, | 786 | .aio_read = pipe_read, |
@@ -830,7 +830,14 @@ void free_pipe_info(struct inode *inode) | |||
830 | static struct vfsmount *pipe_mnt __read_mostly; | 830 | static struct vfsmount *pipe_mnt __read_mostly; |
831 | static int pipefs_delete_dentry(struct dentry *dentry) | 831 | static int pipefs_delete_dentry(struct dentry *dentry) |
832 | { | 832 | { |
833 | return 1; | 833 | /* |
834 | * At creation time, we pretended this dentry was hashed | ||
835 | * (by clearing DCACHE_UNHASHED bit in d_flags) | ||
836 | * At delete time, we restore the truth : not hashed. | ||
837 | * (so that dput() can proceed correctly) | ||
838 | */ | ||
839 | dentry->d_flags |= DCACHE_UNHASHED; | ||
840 | return 0; | ||
834 | } | 841 | } |
835 | 842 | ||
836 | static struct dentry_operations pipefs_dentry_operations = { | 843 | static struct dentry_operations pipefs_dentry_operations = { |
@@ -891,19 +898,24 @@ struct file *create_write_pipe(void) | |||
891 | if (!inode) | 898 | if (!inode) |
892 | goto err_file; | 899 | goto err_file; |
893 | 900 | ||
894 | sprintf(name, "[%lu]", inode->i_ino); | 901 | this.len = sprintf(name, "[%lu]", inode->i_ino); |
895 | this.name = name; | 902 | this.name = name; |
896 | this.len = strlen(name); | 903 | this.hash = 0; |
897 | this.hash = inode->i_ino; /* will go */ | ||
898 | err = -ENOMEM; | 904 | err = -ENOMEM; |
899 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); | 905 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); |
900 | if (!dentry) | 906 | if (!dentry) |
901 | goto err_inode; | 907 | goto err_inode; |
902 | 908 | ||
903 | dentry->d_op = &pipefs_dentry_operations; | 909 | dentry->d_op = &pipefs_dentry_operations; |
904 | d_add(dentry, inode); | 910 | /* |
905 | f->f_vfsmnt = mntget(pipe_mnt); | 911 | * We dont want to publish this dentry into global dentry hash table. |
906 | f->f_dentry = dentry; | 912 | * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED |
913 | * This permits a working /proc/$pid/fd/XXX on pipes | ||
914 | */ | ||
915 | dentry->d_flags &= ~DCACHE_UNHASHED; | ||
916 | d_instantiate(dentry, inode); | ||
917 | f->f_path.mnt = mntget(pipe_mnt); | ||
918 | f->f_path.dentry = dentry; | ||
907 | f->f_mapping = inode->i_mapping; | 919 | f->f_mapping = inode->i_mapping; |
908 | 920 | ||
909 | f->f_flags = O_WRONLY; | 921 | f->f_flags = O_WRONLY; |
@@ -923,8 +935,9 @@ struct file *create_write_pipe(void) | |||
923 | 935 | ||
924 | void free_write_pipe(struct file *f) | 936 | void free_write_pipe(struct file *f) |
925 | { | 937 | { |
926 | mntput(f->f_vfsmnt); | 938 | free_pipe_info(f->f_dentry->d_inode); |
927 | dput(f->f_dentry); | 939 | dput(f->f_path.dentry); |
940 | mntput(f->f_path.mnt); | ||
928 | put_filp(f); | 941 | put_filp(f); |
929 | } | 942 | } |
930 | 943 | ||
@@ -935,9 +948,9 @@ struct file *create_read_pipe(struct file *wrf) | |||
935 | return ERR_PTR(-ENFILE); | 948 | return ERR_PTR(-ENFILE); |
936 | 949 | ||
937 | /* Grab pipe from the writer */ | 950 | /* Grab pipe from the writer */ |
938 | f->f_vfsmnt = mntget(wrf->f_vfsmnt); | 951 | f->f_path.mnt = mntget(wrf->f_path.mnt); |
939 | f->f_dentry = dget(wrf->f_dentry); | 952 | f->f_path.dentry = dget(wrf->f_path.dentry); |
940 | f->f_mapping = wrf->f_dentry->d_inode->i_mapping; | 953 | f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; |
941 | 954 | ||
942 | f->f_pos = 0; | 955 | f->f_pos = 0; |
943 | f->f_flags = O_RDONLY; | 956 | f->f_flags = O_RDONLY; |
@@ -982,6 +995,8 @@ int do_pipe(int *fd) | |||
982 | err_fdr: | 995 | err_fdr: |
983 | put_unused_fd(fdr); | 996 | put_unused_fd(fdr); |
984 | err_read_pipe: | 997 | err_read_pipe: |
998 | dput(fr->f_dentry); | ||
999 | mntput(fr->f_vfsmnt); | ||
985 | put_filp(fr); | 1000 | put_filp(fr); |
986 | err_write_pipe: | 1001 | err_write_pipe: |
987 | free_write_pipe(fw); | 1002 | free_write_pipe(fw); |