diff options
Diffstat (limited to 'net/socket.c')
| -rw-r--r-- | net/socket.c | 123 |
1 files changed, 30 insertions, 93 deletions
diff --git a/net/socket.c b/net/socket.c index 418795caa897..bbedbfcb42c2 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -113,10 +113,8 @@ unsigned int sysctl_net_busy_read __read_mostly; | |||
| 113 | unsigned int sysctl_net_busy_poll __read_mostly; | 113 | unsigned int sysctl_net_busy_poll __read_mostly; |
| 114 | #endif | 114 | #endif |
| 115 | 115 | ||
| 116 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, | 116 | static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to); |
| 117 | unsigned long nr_segs, loff_t pos); | 117 | static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from); |
| 118 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, | ||
| 119 | unsigned long nr_segs, loff_t pos); | ||
| 120 | static int sock_mmap(struct file *file, struct vm_area_struct *vma); | 118 | static int sock_mmap(struct file *file, struct vm_area_struct *vma); |
| 121 | 119 | ||
| 122 | static int sock_close(struct inode *inode, struct file *file); | 120 | static int sock_close(struct inode *inode, struct file *file); |
| @@ -142,8 +140,10 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | |||
| 142 | static const struct file_operations socket_file_ops = { | 140 | static const struct file_operations socket_file_ops = { |
| 143 | .owner = THIS_MODULE, | 141 | .owner = THIS_MODULE, |
| 144 | .llseek = no_llseek, | 142 | .llseek = no_llseek, |
| 145 | .aio_read = sock_aio_read, | 143 | .read = new_sync_read, |
| 146 | .aio_write = sock_aio_write, | 144 | .write = new_sync_write, |
| 145 | .read_iter = sock_read_iter, | ||
| 146 | .write_iter = sock_write_iter, | ||
| 147 | .poll = sock_poll, | 147 | .poll = sock_poll, |
| 148 | .unlocked_ioctl = sock_ioctl, | 148 | .unlocked_ioctl = sock_ioctl, |
| 149 | #ifdef CONFIG_COMPAT | 149 | #ifdef CONFIG_COMPAT |
| @@ -613,13 +613,6 @@ EXPORT_SYMBOL(__sock_tx_timestamp); | |||
| 613 | static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock, | 613 | static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock, |
| 614 | struct msghdr *msg, size_t size) | 614 | struct msghdr *msg, size_t size) |
| 615 | { | 615 | { |
| 616 | struct sock_iocb *si = kiocb_to_siocb(iocb); | ||
| 617 | |||
| 618 | si->sock = sock; | ||
| 619 | si->scm = NULL; | ||
| 620 | si->msg = msg; | ||
| 621 | si->size = size; | ||
| 622 | |||
| 623 | return sock->ops->sendmsg(iocb, sock, msg, size); | 616 | return sock->ops->sendmsg(iocb, sock, msg, size); |
| 624 | } | 617 | } |
| 625 | 618 | ||
| @@ -635,11 +628,9 @@ static int do_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
| 635 | size_t size, bool nosec) | 628 | size_t size, bool nosec) |
| 636 | { | 629 | { |
| 637 | struct kiocb iocb; | 630 | struct kiocb iocb; |
| 638 | struct sock_iocb siocb; | ||
| 639 | int ret; | 631 | int ret; |
| 640 | 632 | ||
| 641 | init_sync_kiocb(&iocb, NULL); | 633 | init_sync_kiocb(&iocb, NULL); |
| 642 | iocb.private = &siocb; | ||
| 643 | ret = nosec ? __sock_sendmsg_nosec(&iocb, sock, msg, size) : | 634 | ret = nosec ? __sock_sendmsg_nosec(&iocb, sock, msg, size) : |
| 644 | __sock_sendmsg(&iocb, sock, msg, size); | 635 | __sock_sendmsg(&iocb, sock, msg, size); |
| 645 | if (-EIOCBQUEUED == ret) | 636 | if (-EIOCBQUEUED == ret) |
| @@ -756,14 +747,6 @@ EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops); | |||
| 756 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, | 747 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, |
| 757 | struct msghdr *msg, size_t size, int flags) | 748 | struct msghdr *msg, size_t size, int flags) |
| 758 | { | 749 | { |
| 759 | struct sock_iocb *si = kiocb_to_siocb(iocb); | ||
| 760 | |||
| 761 | si->sock = sock; | ||
| 762 | si->scm = NULL; | ||
| 763 | si->msg = msg; | ||
| 764 | si->size = size; | ||
| 765 | si->flags = flags; | ||
| 766 | |||
| 767 | return sock->ops->recvmsg(iocb, sock, msg, size, flags); | 750 | return sock->ops->recvmsg(iocb, sock, msg, size, flags); |
| 768 | } | 751 | } |
| 769 | 752 | ||
| @@ -779,11 +762,9 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg, | |||
| 779 | size_t size, int flags) | 762 | size_t size, int flags) |
| 780 | { | 763 | { |
| 781 | struct kiocb iocb; | 764 | struct kiocb iocb; |
| 782 | struct sock_iocb siocb; | ||
| 783 | int ret; | 765 | int ret; |
| 784 | 766 | ||
| 785 | init_sync_kiocb(&iocb, NULL); | 767 | init_sync_kiocb(&iocb, NULL); |
| 786 | iocb.private = &siocb; | ||
| 787 | ret = __sock_recvmsg(&iocb, sock, msg, size, flags); | 768 | ret = __sock_recvmsg(&iocb, sock, msg, size, flags); |
| 788 | if (-EIOCBQUEUED == ret) | 769 | if (-EIOCBQUEUED == ret) |
| 789 | ret = wait_on_sync_kiocb(&iocb); | 770 | ret = wait_on_sync_kiocb(&iocb); |
| @@ -795,11 +776,9 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, | |||
| 795 | size_t size, int flags) | 776 | size_t size, int flags) |
| 796 | { | 777 | { |
| 797 | struct kiocb iocb; | 778 | struct kiocb iocb; |
| 798 | struct sock_iocb siocb; | ||
| 799 | int ret; | 779 | int ret; |
| 800 | 780 | ||
| 801 | init_sync_kiocb(&iocb, NULL); | 781 | init_sync_kiocb(&iocb, NULL); |
| 802 | iocb.private = &siocb; | ||
| 803 | ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags); | 782 | ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags); |
| 804 | if (-EIOCBQUEUED == ret) | 783 | if (-EIOCBQUEUED == ret) |
| 805 | ret = wait_on_sync_kiocb(&iocb); | 784 | ret = wait_on_sync_kiocb(&iocb); |
| @@ -866,89 +845,47 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | |||
| 866 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); | 845 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); |
| 867 | } | 846 | } |
| 868 | 847 | ||
| 869 | static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, | 848 | static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to) |
| 870 | struct sock_iocb *siocb) | ||
| 871 | { | ||
| 872 | siocb->kiocb = iocb; | ||
| 873 | iocb->private = siocb; | ||
| 874 | return siocb; | ||
| 875 | } | ||
| 876 | |||
| 877 | static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, | ||
| 878 | struct file *file, const struct iovec *iov, | ||
| 879 | unsigned long nr_segs) | ||
| 880 | { | 849 | { |
| 850 | struct file *file = iocb->ki_filp; | ||
| 881 | struct socket *sock = file->private_data; | 851 | struct socket *sock = file->private_data; |
| 882 | size_t size = 0; | 852 | struct msghdr msg = {.msg_iter = *to}; |
| 883 | int i; | 853 | ssize_t res; |
| 884 | |||
| 885 | for (i = 0; i < nr_segs; i++) | ||
| 886 | size += iov[i].iov_len; | ||
| 887 | |||
| 888 | msg->msg_name = NULL; | ||
| 889 | msg->msg_namelen = 0; | ||
| 890 | msg->msg_control = NULL; | ||
| 891 | msg->msg_controllen = 0; | ||
| 892 | iov_iter_init(&msg->msg_iter, READ, iov, nr_segs, size); | ||
| 893 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; | ||
| 894 | |||
| 895 | return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags); | ||
| 896 | } | ||
| 897 | 854 | ||
| 898 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, | 855 | if (file->f_flags & O_NONBLOCK) |
| 899 | unsigned long nr_segs, loff_t pos) | 856 | msg.msg_flags = MSG_DONTWAIT; |
| 900 | { | ||
| 901 | struct sock_iocb siocb, *x; | ||
| 902 | 857 | ||
| 903 | if (pos != 0) | 858 | if (iocb->ki_pos != 0) |
| 904 | return -ESPIPE; | 859 | return -ESPIPE; |
| 905 | 860 | ||
| 906 | if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */ | 861 | if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */ |
| 907 | return 0; | 862 | return 0; |
| 908 | 863 | ||
| 909 | 864 | res = __sock_recvmsg(iocb, sock, &msg, | |
| 910 | x = alloc_sock_iocb(iocb, &siocb); | 865 | iocb->ki_nbytes, msg.msg_flags); |
| 911 | if (!x) | 866 | *to = msg.msg_iter; |
| 912 | return -ENOMEM; | 867 | return res; |
| 913 | return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs); | ||
| 914 | } | 868 | } |
| 915 | 869 | ||
| 916 | static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, | 870 | static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from) |
| 917 | struct file *file, const struct iovec *iov, | ||
| 918 | unsigned long nr_segs) | ||
| 919 | { | 871 | { |
| 872 | struct file *file = iocb->ki_filp; | ||
| 920 | struct socket *sock = file->private_data; | 873 | struct socket *sock = file->private_data; |
| 921 | size_t size = 0; | 874 | struct msghdr msg = {.msg_iter = *from}; |
| 922 | int i; | 875 | ssize_t res; |
| 923 | |||
| 924 | for (i = 0; i < nr_segs; i++) | ||
| 925 | size += iov[i].iov_len; | ||
| 926 | |||
| 927 | msg->msg_name = NULL; | ||
| 928 | msg->msg_namelen = 0; | ||
| 929 | msg->msg_control = NULL; | ||
| 930 | msg->msg_controllen = 0; | ||
| 931 | iov_iter_init(&msg->msg_iter, WRITE, iov, nr_segs, size); | ||
| 932 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; | ||
| 933 | if (sock->type == SOCK_SEQPACKET) | ||
| 934 | msg->msg_flags |= MSG_EOR; | ||
| 935 | |||
| 936 | return __sock_sendmsg(iocb, sock, msg, size); | ||
| 937 | } | ||
| 938 | 876 | ||
| 939 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, | 877 | if (iocb->ki_pos != 0) |
| 940 | unsigned long nr_segs, loff_t pos) | ||
| 941 | { | ||
| 942 | struct sock_iocb siocb, *x; | ||
| 943 | |||
| 944 | if (pos != 0) | ||
| 945 | return -ESPIPE; | 878 | return -ESPIPE; |
| 946 | 879 | ||
| 947 | x = alloc_sock_iocb(iocb, &siocb); | 880 | if (file->f_flags & O_NONBLOCK) |
| 948 | if (!x) | 881 | msg.msg_flags = MSG_DONTWAIT; |
| 949 | return -ENOMEM; | 882 | |
| 883 | if (sock->type == SOCK_SEQPACKET) | ||
| 884 | msg.msg_flags |= MSG_EOR; | ||
| 950 | 885 | ||
| 951 | return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs); | 886 | res = __sock_sendmsg(iocb, sock, &msg, iocb->ki_nbytes); |
| 887 | *from = msg.msg_iter; | ||
| 888 | return res; | ||
| 952 | } | 889 | } |
| 953 | 890 | ||
| 954 | /* | 891 | /* |
