diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2013-03-12 09:58:10 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-04-09 14:12:58 -0400 |
| commit | 599a0ac14e065b7c08471ef2e75a504b7dec9267 (patch) | |
| tree | 21f9caef768eb84dad3ce19f76e646af0a5e4dfa | |
| parent | f776c738883bc949e654568a565aee5a7d3fe133 (diff) | |
pipe: fold file_operations instances in one
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/inode.c | 2 | ||||
| -rw-r--r-- | fs/internal.h | 5 | ||||
| -rw-r--r-- | fs/pipe.c | 221 | ||||
| -rw-r--r-- | include/linux/fs.h | 5 |
4 files changed, 38 insertions, 195 deletions
diff --git a/fs/inode.c b/fs/inode.c index f5f7c06c36fb..5b76d9b1a884 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -1803,7 +1803,7 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) | |||
| 1803 | inode->i_fop = &def_blk_fops; | 1803 | inode->i_fop = &def_blk_fops; |
| 1804 | inode->i_rdev = rdev; | 1804 | inode->i_rdev = rdev; |
| 1805 | } else if (S_ISFIFO(mode)) | 1805 | } else if (S_ISFIFO(mode)) |
| 1806 | inode->i_fop = &def_fifo_fops; | 1806 | inode->i_fop = &pipefifo_fops; |
| 1807 | else if (S_ISSOCK(mode)) | 1807 | else if (S_ISSOCK(mode)) |
| 1808 | inode->i_fop = &bad_sock_fops; | 1808 | inode->i_fop = &bad_sock_fops; |
| 1809 | else | 1809 | else |
diff --git a/fs/internal.h b/fs/internal.h index 4be78237d896..eaa75f75b625 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
| @@ -130,3 +130,8 @@ extern struct dentry *__d_alloc(struct super_block *, const struct qstr *); | |||
| 130 | * read_write.c | 130 | * read_write.c |
| 131 | */ | 131 | */ |
| 132 | extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); | 132 | extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); |
| 133 | |||
| 134 | /* | ||
| 135 | * pipe.c | ||
| 136 | */ | ||
| 137 | extern const struct file_operations pipefifo_fops; | ||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
| 26 | #include <asm/ioctls.h> | 26 | #include <asm/ioctls.h> |
| 27 | 27 | ||
| 28 | #include "internal.h" | ||
| 29 | |||
| 28 | /* | 30 | /* |
| 29 | * The max size that a non-root user is allowed to grow the pipe. Can | 31 | * The max size that a non-root user is allowed to grow the pipe. Can |
| 30 | * be set by root in /proc/sys/fs/pipe-max-size | 32 | * be set by root in /proc/sys/fs/pipe-max-size |
| @@ -662,19 +664,6 @@ out: | |||
| 662 | return ret; | 664 | return ret; |
| 663 | } | 665 | } |
| 664 | 666 | ||
| 665 | static ssize_t | ||
| 666 | bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | ||
| 667 | { | ||
| 668 | return -EBADF; | ||
| 669 | } | ||
| 670 | |||
| 671 | static ssize_t | ||
| 672 | bad_pipe_w(struct file *filp, const char __user *buf, size_t count, | ||
| 673 | loff_t *ppos) | ||
| 674 | { | ||
| 675 | return -EBADF; | ||
| 676 | } | ||
| 677 | |||
| 678 | static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 667 | static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
| 679 | { | 668 | { |
| 680 | struct inode *inode = file_inode(filp); | 669 | struct inode *inode = file_inode(filp); |
| @@ -734,14 +723,16 @@ pipe_poll(struct file *filp, poll_table *wait) | |||
| 734 | } | 723 | } |
| 735 | 724 | ||
| 736 | static int | 725 | static int |
| 737 | pipe_release(struct inode *inode, int decr, int decw) | 726 | pipe_release(struct inode *inode, struct file *file) |
| 738 | { | 727 | { |
| 739 | struct pipe_inode_info *pipe; | 728 | struct pipe_inode_info *pipe; |
| 740 | 729 | ||
| 741 | mutex_lock(&inode->i_mutex); | 730 | mutex_lock(&inode->i_mutex); |
| 742 | pipe = inode->i_pipe; | 731 | pipe = inode->i_pipe; |
| 743 | pipe->readers -= decr; | 732 | if (file->f_mode & FMODE_READ) |
| 744 | pipe->writers -= decw; | 733 | pipe->readers--; |
| 734 | if (file->f_mode & FMODE_WRITE) | ||
| 735 | pipe->writers--; | ||
| 745 | 736 | ||
| 746 | if (!pipe->readers && !pipe->writers) { | 737 | if (!pipe->readers && !pipe->writers) { |
| 747 | free_pipe_info(inode); | 738 | free_pipe_info(inode); |
| @@ -756,174 +747,25 @@ pipe_release(struct inode *inode, int decr, int decw) | |||
| 756 | } | 747 | } |
| 757 | 748 | ||
| 758 | static int | 749 | static int |
| 759 | pipe_read_fasync(int fd, struct file *filp, int on) | 750 | pipe_fasync(int fd, struct file *filp, int on) |
| 760 | { | ||
| 761 | struct inode *inode = file_inode(filp); | ||
| 762 | int retval; | ||
| 763 | |||
| 764 | mutex_lock(&inode->i_mutex); | ||
| 765 | retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers); | ||
| 766 | mutex_unlock(&inode->i_mutex); | ||
| 767 | |||
| 768 | return retval; | ||
| 769 | } | ||
| 770 | |||
| 771 | |||
| 772 | static int | ||
| 773 | pipe_write_fasync(int fd, struct file *filp, int on) | ||
| 774 | { | ||
| 775 | struct inode *inode = file_inode(filp); | ||
| 776 | int retval; | ||
| 777 | |||
| 778 | mutex_lock(&inode->i_mutex); | ||
| 779 | retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers); | ||
| 780 | mutex_unlock(&inode->i_mutex); | ||
| 781 | |||
| 782 | return retval; | ||
| 783 | } | ||
| 784 | |||
| 785 | |||
| 786 | static int | ||
| 787 | pipe_rdwr_fasync(int fd, struct file *filp, int on) | ||
| 788 | { | 751 | { |
| 789 | struct inode *inode = file_inode(filp); | 752 | struct inode *inode = file_inode(filp); |
| 790 | struct pipe_inode_info *pipe = inode->i_pipe; | 753 | struct pipe_inode_info *pipe = inode->i_pipe; |
| 791 | int retval; | 754 | int retval = 0; |
| 792 | 755 | ||
| 793 | mutex_lock(&inode->i_mutex); | 756 | mutex_lock(&inode->i_mutex); |
| 794 | retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); | 757 | if (filp->f_mode & FMODE_READ) |
| 795 | if (retval >= 0) { | 758 | retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); |
| 759 | if ((filp->f_mode & FMODE_WRITE) && retval >= 0) { | ||
| 796 | retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); | 760 | retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); |
| 797 | if (retval < 0) /* this can happen only if on == T */ | 761 | if (retval < 0 && (filp->f_mode & FMODE_READ)) |
| 762 | /* this can happen only if on == T */ | ||
| 798 | fasync_helper(-1, filp, 0, &pipe->fasync_readers); | 763 | fasync_helper(-1, filp, 0, &pipe->fasync_readers); |
| 799 | } | 764 | } |
| 800 | mutex_unlock(&inode->i_mutex); | 765 | mutex_unlock(&inode->i_mutex); |
| 801 | return retval; | 766 | return retval; |
| 802 | } | 767 | } |
| 803 | 768 | ||
| 804 | |||
| 805 | static int | ||
| 806 | pipe_read_release(struct inode *inode, struct file *filp) | ||
| 807 | { | ||
| 808 | return pipe_release(inode, 1, 0); | ||
| 809 | } | ||
| 810 | |||
| 811 | static int | ||
| 812 | pipe_write_release(struct inode *inode, struct file *filp) | ||
| 813 | { | ||
| 814 | return pipe_release(inode, 0, 1); | ||
| 815 | } | ||
| 816 | |||
| 817 | static int | ||
| 818 | pipe_rdwr_release(struct inode *inode, struct file *filp) | ||
| 819 | { | ||
| 820 | int decr, decw; | ||
| 821 | |||
| 822 | decr = (filp->f_mode & FMODE_READ) != 0; | ||
| 823 | decw = (filp->f_mode & FMODE_WRITE) != 0; | ||
| 824 | return pipe_release(inode, decr, decw); | ||
| 825 | } | ||
| 826 | |||
| 827 | static int | ||
| 828 | pipe_read_open(struct inode *inode, struct file *filp) | ||
| 829 | { | ||
| 830 | int ret = -ENOENT; | ||
| 831 | |||
| 832 | mutex_lock(&inode->i_mutex); | ||
| 833 | |||
| 834 | if (inode->i_pipe) { | ||
| 835 | ret = 0; | ||
| 836 | inode->i_pipe->readers++; | ||
| 837 | } | ||
| 838 | |||
| 839 | mutex_unlock(&inode->i_mutex); | ||
| 840 | |||
| 841 | return ret; | ||
| 842 | } | ||
| 843 | |||
| 844 | static int | ||
| 845 | pipe_write_open(struct inode *inode, struct file *filp) | ||
| 846 | { | ||
| 847 | int ret = -ENOENT; | ||
| 848 | |||
| 849 | mutex_lock(&inode->i_mutex); | ||
| 850 | |||
| 851 | if (inode->i_pipe) { | ||
| 852 | ret = 0; | ||
| 853 | inode->i_pipe->writers++; | ||
| 854 | } | ||
| 855 | |||
| 856 | mutex_unlock(&inode->i_mutex); | ||
| 857 | |||
| 858 | return ret; | ||
| 859 | } | ||
| 860 | |||
| 861 | static int | ||
| 862 | pipe_rdwr_open(struct inode *inode, struct file *filp) | ||
| 863 | { | ||
| 864 | int ret = -ENOENT; | ||
| 865 | |||
| 866 | if (!(filp->f_mode & (FMODE_READ|FMODE_WRITE))) | ||
| 867 | return -EINVAL; | ||
| 868 | |||
| 869 | mutex_lock(&inode->i_mutex); | ||
| 870 | |||
| 871 | if (inode->i_pipe) { | ||
| 872 | ret = 0; | ||
| 873 | if (filp->f_mode & FMODE_READ) | ||
| 874 | inode->i_pipe->readers++; | ||
| 875 | if (filp->f_mode & FMODE_WRITE) | ||
| 876 | inode->i_pipe->writers++; | ||
| 877 | } | ||
| 878 | |||
| 879 | mutex_unlock(&inode->i_mutex); | ||
| 880 | |||
| 881 | return ret; | ||
| 882 | } | ||
| 883 | |||
| 884 | /* | ||
| 885 | * The file_operations structs are not static because they | ||
| 886 | * are also used in linux/fs/fifo.c to do operations on FIFOs. | ||
| 887 | * | ||
| 888 | * Pipes reuse fifos' file_operations structs. | ||
| 889 | */ | ||
| 890 | const struct file_operations read_pipefifo_fops = { | ||
| 891 | .llseek = no_llseek, | ||
| 892 | .read = do_sync_read, | ||
| 893 | .aio_read = pipe_read, | ||
| 894 | .write = bad_pipe_w, | ||
| 895 | .poll = pipe_poll, | ||
| 896 | .unlocked_ioctl = pipe_ioctl, | ||
| 897 | .open = pipe_read_open, | ||
| 898 | .release = pipe_read_release, | ||
| 899 | .fasync = pipe_read_fasync, | ||
| 900 | }; | ||
| 901 | |||
| 902 | const struct file_operations write_pipefifo_fops = { | ||
| 903 | .llseek = no_llseek, | ||
| 904 | .read = bad_pipe_r, | ||
| 905 | .write = do_sync_write, | ||
| 906 | .aio_write = pipe_write, | ||
| 907 | .poll = pipe_poll, | ||
| 908 | .unlocked_ioctl = pipe_ioctl, | ||
| 909 | .open = pipe_write_open, | ||
| 910 | .release = pipe_write_release, | ||
| 911 | .fasync = pipe_write_fasync, | ||
| 912 | }; | ||
| 913 | |||
| 914 | const struct file_operations rdwr_pipefifo_fops = { | ||
| 915 | .llseek = no_llseek, | ||
| 916 | .read = do_sync_read, | ||
| 917 | .aio_read = pipe_read, | ||
| 918 | .write = do_sync_write, | ||
| 919 | .aio_write = pipe_write, | ||
| 920 | .poll = pipe_poll, | ||
| 921 | .unlocked_ioctl = pipe_ioctl, | ||
| 922 | .open = pipe_rdwr_open, | ||
| 923 | .release = pipe_rdwr_release, | ||
| 924 | .fasync = pipe_rdwr_fasync, | ||
| 925 | }; | ||
| 926 | |||
| 927 | struct pipe_inode_info * alloc_pipe_info(struct inode *inode) | 769 | struct pipe_inode_info * alloc_pipe_info(struct inode *inode) |
| 928 | { | 770 | { |
| 929 | struct pipe_inode_info *pipe; | 771 | struct pipe_inode_info *pipe; |
| @@ -996,7 +838,7 @@ static struct inode * get_pipe_inode(void) | |||
| 996 | inode->i_pipe = pipe; | 838 | inode->i_pipe = pipe; |
| 997 | 839 | ||
| 998 | pipe->readers = pipe->writers = 1; | 840 | pipe->readers = pipe->writers = 1; |
| 999 | inode->i_fop = &rdwr_pipefifo_fops; | 841 | inode->i_fop = &pipefifo_fops; |
| 1000 | 842 | ||
| 1001 | /* | 843 | /* |
| 1002 | * Mark the inode dirty from the very beginning, | 844 | * Mark the inode dirty from the very beginning, |
| @@ -1039,13 +881,13 @@ int create_pipe_files(struct file **res, int flags) | |||
| 1039 | d_instantiate(path.dentry, inode); | 881 | d_instantiate(path.dentry, inode); |
| 1040 | 882 | ||
| 1041 | err = -ENFILE; | 883 | err = -ENFILE; |
| 1042 | f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops); | 884 | f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops); |
| 1043 | if (IS_ERR(f)) | 885 | if (IS_ERR(f)) |
| 1044 | goto err_dentry; | 886 | goto err_dentry; |
| 1045 | 887 | ||
| 1046 | f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); | 888 | f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); |
| 1047 | 889 | ||
| 1048 | res[0] = alloc_file(&path, FMODE_READ, &read_pipefifo_fops); | 890 | res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops); |
| 1049 | if (IS_ERR(res[0])) | 891 | if (IS_ERR(res[0])) |
| 1050 | goto err_file; | 892 | goto err_file; |
| 1051 | 893 | ||
| @@ -1164,6 +1006,7 @@ static void wake_up_partner(struct inode* inode) | |||
| 1164 | static int fifo_open(struct inode *inode, struct file *filp) | 1006 | static int fifo_open(struct inode *inode, struct file *filp) |
| 1165 | { | 1007 | { |
| 1166 | struct pipe_inode_info *pipe; | 1008 | struct pipe_inode_info *pipe; |
| 1009 | bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC; | ||
| 1167 | int ret; | 1010 | int ret; |
| 1168 | 1011 | ||
| 1169 | mutex_lock(&inode->i_mutex); | 1012 | mutex_lock(&inode->i_mutex); |
| @@ -1187,12 +1030,11 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
| 1187 | * POSIX.1 says that O_NONBLOCK means return with the FIFO | 1030 | * POSIX.1 says that O_NONBLOCK means return with the FIFO |
| 1188 | * opened, even when there is no process writing the FIFO. | 1031 | * opened, even when there is no process writing the FIFO. |
| 1189 | */ | 1032 | */ |
| 1190 | filp->f_op = &read_pipefifo_fops; | ||
| 1191 | pipe->r_counter++; | 1033 | pipe->r_counter++; |
| 1192 | if (pipe->readers++ == 0) | 1034 | if (pipe->readers++ == 0) |
| 1193 | wake_up_partner(inode); | 1035 | wake_up_partner(inode); |
| 1194 | 1036 | ||
| 1195 | if (!pipe->writers) { | 1037 | if (!is_pipe && !pipe->writers) { |
| 1196 | if ((filp->f_flags & O_NONBLOCK)) { | 1038 | if ((filp->f_flags & O_NONBLOCK)) { |
| 1197 | /* suppress POLLHUP until we have | 1039 | /* suppress POLLHUP until we have |
| 1198 | * seen a writer */ | 1040 | * seen a writer */ |
| @@ -1211,15 +1053,14 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
| 1211 | * errno=ENXIO when there is no process reading the FIFO. | 1053 | * errno=ENXIO when there is no process reading the FIFO. |
| 1212 | */ | 1054 | */ |
| 1213 | ret = -ENXIO; | 1055 | ret = -ENXIO; |
| 1214 | if ((filp->f_flags & O_NONBLOCK) && !pipe->readers) | 1056 | if (!is_pipe && (filp->f_flags & O_NONBLOCK) && !pipe->readers) |
| 1215 | goto err; | 1057 | goto err; |
| 1216 | 1058 | ||
| 1217 | filp->f_op = &write_pipefifo_fops; | ||
| 1218 | pipe->w_counter++; | 1059 | pipe->w_counter++; |
| 1219 | if (!pipe->writers++) | 1060 | if (!pipe->writers++) |
| 1220 | wake_up_partner(inode); | 1061 | wake_up_partner(inode); |
| 1221 | 1062 | ||
| 1222 | if (!pipe->readers) { | 1063 | if (!is_pipe && !pipe->readers) { |
| 1223 | if (wait_for_partner(inode, &pipe->r_counter)) | 1064 | if (wait_for_partner(inode, &pipe->r_counter)) |
| 1224 | goto err_wr; | 1065 | goto err_wr; |
| 1225 | } | 1066 | } |
| @@ -1232,7 +1073,6 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
| 1232 | * This implementation will NEVER block on a O_RDWR open, since | 1073 | * This implementation will NEVER block on a O_RDWR open, since |
| 1233 | * the process can at least talk to itself. | 1074 | * the process can at least talk to itself. |
| 1234 | */ | 1075 | */ |
| 1235 | filp->f_op = &rdwr_pipefifo_fops; | ||
| 1236 | 1076 | ||
| 1237 | pipe->readers++; | 1077 | pipe->readers++; |
| 1238 | pipe->writers++; | 1078 | pipe->writers++; |
| @@ -1272,14 +1112,17 @@ err_nocleanup: | |||
| 1272 | return ret; | 1112 | return ret; |
| 1273 | } | 1113 | } |
| 1274 | 1114 | ||
| 1275 | /* | 1115 | const struct file_operations pipefifo_fops = { |
| 1276 | * Dummy default file-operations: the only thing this does | 1116 | .open = fifo_open, |
| 1277 | * is contain the open that then fills in the correct operations | 1117 | .llseek = no_llseek, |
| 1278 | * depending on the access mode of the file... | 1118 | .read = do_sync_read, |
| 1279 | */ | 1119 | .aio_read = pipe_read, |
| 1280 | const struct file_operations def_fifo_fops = { | 1120 | .write = do_sync_write, |
| 1281 | .open = fifo_open, /* will set read_ or write_pipefifo_fops */ | 1121 | .aio_write = pipe_write, |
| 1282 | .llseek = noop_llseek, | 1122 | .poll = pipe_poll, |
| 1123 | .unlocked_ioctl = pipe_ioctl, | ||
| 1124 | .release = pipe_release, | ||
| 1125 | .fasync = pipe_fasync, | ||
| 1283 | }; | 1126 | }; |
| 1284 | 1127 | ||
| 1285 | /* | 1128 | /* |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 578a66e6ee72..b1f28b02ede6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -2080,7 +2080,6 @@ extern int sync_filesystem(struct super_block *); | |||
| 2080 | extern const struct file_operations def_blk_fops; | 2080 | extern const struct file_operations def_blk_fops; |
| 2081 | extern const struct file_operations def_chr_fops; | 2081 | extern const struct file_operations def_chr_fops; |
| 2082 | extern const struct file_operations bad_sock_fops; | 2082 | extern const struct file_operations bad_sock_fops; |
| 2083 | extern const struct file_operations def_fifo_fops; | ||
| 2084 | #ifdef CONFIG_BLOCK | 2083 | #ifdef CONFIG_BLOCK |
| 2085 | extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); | 2084 | extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); |
| 2086 | extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); | 2085 | extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); |
| @@ -2152,10 +2151,6 @@ extern void init_special_inode(struct inode *, umode_t, dev_t); | |||
| 2152 | extern void make_bad_inode(struct inode *); | 2151 | extern void make_bad_inode(struct inode *); |
| 2153 | extern int is_bad_inode(struct inode *); | 2152 | extern int is_bad_inode(struct inode *); |
| 2154 | 2153 | ||
| 2155 | extern const struct file_operations read_pipefifo_fops; | ||
| 2156 | extern const struct file_operations write_pipefifo_fops; | ||
| 2157 | extern const struct file_operations rdwr_pipefifo_fops; | ||
| 2158 | |||
| 2159 | #ifdef CONFIG_BLOCK | 2154 | #ifdef CONFIG_BLOCK |
| 2160 | /* | 2155 | /* |
| 2161 | * return READ, READA, or WRITE | 2156 | * return READ, READA, or WRITE |
