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 /fs/pipe.c | |
parent | f776c738883bc949e654568a565aee5a7d3fe133 (diff) |
pipe: fold file_operations instances in one
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 221 |
1 files changed, 32 insertions, 189 deletions
@@ -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 | /* |