diff options
author | David S. Miller <davem@davemloft.net> | 2014-11-25 20:02:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-25 20:02:51 -0500 |
commit | d3fc6b3fddd54c2220a075aefc4e5e5ca25cff34 (patch) | |
tree | 794bd9737e15ecc636e2e3ef4c060c8e24488ca3 | |
parent | aa99c47933d2c9a7622440d1b08ebb46ad8bd741 (diff) | |
parent | 083735f4b01b703184c0e11c2e384b2c60a8aea4 (diff) |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
More work from Al Viro to move away from modifying iovecs
by using iov_iter instead.
Signed-off-by: David S. Miller <davem@davemloft.net>
68 files changed, 343 insertions, 466 deletions
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 850246206b12..35c93ff11f35 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c | |||
@@ -174,7 +174,7 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock, | |||
174 | goto unlock; | 174 | goto unlock; |
175 | } | 175 | } |
176 | 176 | ||
177 | err = memcpy_toiovec(msg->msg_iov, ctx->result, len); | 177 | err = memcpy_to_msg(msg, ctx->result, len); |
178 | 178 | ||
179 | unlock: | 179 | unlock: |
180 | release_sock(sk); | 180 | release_sock(sk); |
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 83187f497c7c..c3b482bee208 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c | |||
@@ -298,9 +298,9 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, | |||
298 | len = min_t(unsigned long, len, | 298 | len = min_t(unsigned long, len, |
299 | PAGE_SIZE - sg->offset - sg->length); | 299 | PAGE_SIZE - sg->offset - sg->length); |
300 | 300 | ||
301 | err = memcpy_fromiovec(page_address(sg_page(sg)) + | 301 | err = memcpy_from_msg(page_address(sg_page(sg)) + |
302 | sg->offset + sg->length, | 302 | sg->offset + sg->length, |
303 | msg->msg_iov, len); | 303 | msg, len); |
304 | if (err) | 304 | if (err) |
305 | goto unlock; | 305 | goto unlock; |
306 | 306 | ||
@@ -337,8 +337,8 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, | |||
337 | if (!sg_page(sg + i)) | 337 | if (!sg_page(sg + i)) |
338 | goto unlock; | 338 | goto unlock; |
339 | 339 | ||
340 | err = memcpy_fromiovec(page_address(sg_page(sg + i)), | 340 | err = memcpy_from_msg(page_address(sg_page(sg + i)), |
341 | msg->msg_iov, plen); | 341 | msg, plen); |
342 | if (err) { | 342 | if (err) { |
343 | __free_page(sg_page(sg + i)); | 343 | __free_page(sg_page(sg + i)); |
344 | sg_assign_page(sg + i, NULL); | 344 | sg_assign_page(sg + i, NULL); |
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index dcbd8589f0c4..84b35925ee4d 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c | |||
@@ -203,7 +203,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
203 | if (!skb) | 203 | if (!skb) |
204 | goto done; | 204 | goto done; |
205 | 205 | ||
206 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 206 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { |
207 | err = -EFAULT; | 207 | err = -EFAULT; |
208 | goto done; | 208 | goto done; |
209 | } | 209 | } |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 42a80d3de839..22b4cf2fa108 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -640,12 +640,12 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, | |||
640 | 640 | ||
641 | /* Get packet from user space buffer */ | 641 | /* Get packet from user space buffer */ |
642 | static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | 642 | static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, |
643 | const struct iovec *iv, unsigned long total_len, | 643 | struct iov_iter *from, int noblock) |
644 | size_t count, int noblock) | ||
645 | { | 644 | { |
646 | int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN); | 645 | int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN); |
647 | struct sk_buff *skb; | 646 | struct sk_buff *skb; |
648 | struct macvlan_dev *vlan; | 647 | struct macvlan_dev *vlan; |
648 | unsigned long total_len = iov_iter_count(from); | ||
649 | unsigned long len = total_len; | 649 | unsigned long len = total_len; |
650 | int err; | 650 | int err; |
651 | struct virtio_net_hdr vnet_hdr = { 0 }; | 651 | struct virtio_net_hdr vnet_hdr = { 0 }; |
@@ -653,6 +653,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | |||
653 | int copylen = 0; | 653 | int copylen = 0; |
654 | bool zerocopy = false; | 654 | bool zerocopy = false; |
655 | size_t linear; | 655 | size_t linear; |
656 | ssize_t n; | ||
656 | 657 | ||
657 | if (q->flags & IFF_VNET_HDR) { | 658 | if (q->flags & IFF_VNET_HDR) { |
658 | vnet_hdr_len = q->vnet_hdr_sz; | 659 | vnet_hdr_len = q->vnet_hdr_sz; |
@@ -662,10 +663,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | |||
662 | goto err; | 663 | goto err; |
663 | len -= vnet_hdr_len; | 664 | len -= vnet_hdr_len; |
664 | 665 | ||
665 | err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, | 666 | err = -EFAULT; |
666 | sizeof(vnet_hdr)); | 667 | n = copy_from_iter(&vnet_hdr, sizeof(vnet_hdr), from); |
667 | if (err < 0) | 668 | if (n != sizeof(vnet_hdr)) |
668 | goto err; | 669 | goto err; |
670 | iov_iter_advance(from, vnet_hdr_len - sizeof(vnet_hdr)); | ||
669 | if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && | 671 | if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && |
670 | vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 > | 672 | vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 > |
671 | vnet_hdr.hdr_len) | 673 | vnet_hdr.hdr_len) |
@@ -680,17 +682,16 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | |||
680 | if (unlikely(len < ETH_HLEN)) | 682 | if (unlikely(len < ETH_HLEN)) |
681 | goto err; | 683 | goto err; |
682 | 684 | ||
683 | err = -EMSGSIZE; | ||
684 | if (unlikely(count > UIO_MAXIOV)) | ||
685 | goto err; | ||
686 | |||
687 | if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) { | 685 | if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) { |
686 | struct iov_iter i; | ||
687 | |||
688 | copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN; | 688 | copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN; |
689 | if (copylen > good_linear) | 689 | if (copylen > good_linear) |
690 | copylen = good_linear; | 690 | copylen = good_linear; |
691 | linear = copylen; | 691 | linear = copylen; |
692 | if (iov_pages(iv, vnet_hdr_len + copylen, count) | 692 | i = *from; |
693 | <= MAX_SKB_FRAGS) | 693 | iov_iter_advance(&i, copylen); |
694 | if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS) | ||
694 | zerocopy = true; | 695 | zerocopy = true; |
695 | } | 696 | } |
696 | 697 | ||
@@ -708,10 +709,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | |||
708 | goto err; | 709 | goto err; |
709 | 710 | ||
710 | if (zerocopy) | 711 | if (zerocopy) |
711 | err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count); | 712 | err = zerocopy_sg_from_iter(skb, from); |
712 | else { | 713 | else { |
713 | err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, | 714 | err = skb_copy_datagram_from_iter(skb, 0, from, len); |
714 | len); | ||
715 | if (!err && m && m->msg_control) { | 715 | if (!err && m && m->msg_control) { |
716 | struct ubuf_info *uarg = m->msg_control; | 716 | struct ubuf_info *uarg = m->msg_control; |
717 | uarg->callback(uarg, false); | 717 | uarg->callback(uarg, false); |
@@ -764,16 +764,12 @@ err: | |||
764 | return err; | 764 | return err; |
765 | } | 765 | } |
766 | 766 | ||
767 | static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv, | 767 | static ssize_t macvtap_write_iter(struct kiocb *iocb, struct iov_iter *from) |
768 | unsigned long count, loff_t pos) | ||
769 | { | 768 | { |
770 | struct file *file = iocb->ki_filp; | 769 | struct file *file = iocb->ki_filp; |
771 | ssize_t result = -ENOLINK; | ||
772 | struct macvtap_queue *q = file->private_data; | 770 | struct macvtap_queue *q = file->private_data; |
773 | 771 | ||
774 | result = macvtap_get_user(q, NULL, iv, iov_length(iv, count), count, | 772 | return macvtap_get_user(q, NULL, from, file->f_flags & O_NONBLOCK); |
775 | file->f_flags & O_NONBLOCK); | ||
776 | return result; | ||
777 | } | 773 | } |
778 | 774 | ||
779 | /* Put packet to the user space buffer */ | 775 | /* Put packet to the user space buffer */ |
@@ -831,64 +827,55 @@ done: | |||
831 | } | 827 | } |
832 | 828 | ||
833 | static ssize_t macvtap_do_read(struct macvtap_queue *q, | 829 | static ssize_t macvtap_do_read(struct macvtap_queue *q, |
834 | const struct iovec *iv, unsigned long segs, | 830 | struct iov_iter *to, |
835 | unsigned long len, | ||
836 | int noblock) | 831 | int noblock) |
837 | { | 832 | { |
838 | DEFINE_WAIT(wait); | 833 | DEFINE_WAIT(wait); |
839 | struct sk_buff *skb; | 834 | struct sk_buff *skb; |
840 | ssize_t ret = 0; | 835 | ssize_t ret = 0; |
841 | struct iov_iter iter; | ||
842 | 836 | ||
843 | while (len) { | 837 | if (!iov_iter_count(to)) |
838 | return 0; | ||
839 | |||
840 | while (1) { | ||
844 | if (!noblock) | 841 | if (!noblock) |
845 | prepare_to_wait(sk_sleep(&q->sk), &wait, | 842 | prepare_to_wait(sk_sleep(&q->sk), &wait, |
846 | TASK_INTERRUPTIBLE); | 843 | TASK_INTERRUPTIBLE); |
847 | 844 | ||
848 | /* Read frames from the queue */ | 845 | /* Read frames from the queue */ |
849 | skb = skb_dequeue(&q->sk.sk_receive_queue); | 846 | skb = skb_dequeue(&q->sk.sk_receive_queue); |
850 | if (!skb) { | 847 | if (skb) |
851 | if (noblock) { | 848 | break; |
852 | ret = -EAGAIN; | 849 | if (noblock) { |
853 | break; | 850 | ret = -EAGAIN; |
854 | } | 851 | break; |
855 | if (signal_pending(current)) { | 852 | } |
856 | ret = -ERESTARTSYS; | 853 | if (signal_pending(current)) { |
857 | break; | 854 | ret = -ERESTARTSYS; |
858 | } | 855 | break; |
859 | /* Nothing to read, let's sleep */ | ||
860 | schedule(); | ||
861 | continue; | ||
862 | } | 856 | } |
863 | iov_iter_init(&iter, READ, iv, segs, len); | 857 | /* Nothing to read, let's sleep */ |
864 | ret = macvtap_put_user(q, skb, &iter); | 858 | schedule(); |
859 | } | ||
860 | if (skb) { | ||
861 | ret = macvtap_put_user(q, skb, to); | ||
865 | kfree_skb(skb); | 862 | kfree_skb(skb); |
866 | break; | ||
867 | } | 863 | } |
868 | |||
869 | if (!noblock) | 864 | if (!noblock) |
870 | finish_wait(sk_sleep(&q->sk), &wait); | 865 | finish_wait(sk_sleep(&q->sk), &wait); |
871 | return ret; | 866 | return ret; |
872 | } | 867 | } |
873 | 868 | ||
874 | static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, | 869 | static ssize_t macvtap_read_iter(struct kiocb *iocb, struct iov_iter *to) |
875 | unsigned long count, loff_t pos) | ||
876 | { | 870 | { |
877 | struct file *file = iocb->ki_filp; | 871 | struct file *file = iocb->ki_filp; |
878 | struct macvtap_queue *q = file->private_data; | 872 | struct macvtap_queue *q = file->private_data; |
879 | ssize_t len, ret = 0; | 873 | ssize_t len = iov_iter_count(to), ret; |
880 | |||
881 | len = iov_length(iv, count); | ||
882 | if (len < 0) { | ||
883 | ret = -EINVAL; | ||
884 | goto out; | ||
885 | } | ||
886 | 874 | ||
887 | ret = macvtap_do_read(q, iv, count, len, file->f_flags & O_NONBLOCK); | 875 | ret = macvtap_do_read(q, to, file->f_flags & O_NONBLOCK); |
888 | ret = min_t(ssize_t, ret, len); | 876 | ret = min_t(ssize_t, ret, len); |
889 | if (ret > 0) | 877 | if (ret > 0) |
890 | iocb->ki_pos = ret; | 878 | iocb->ki_pos = ret; |
891 | out: | ||
892 | return ret; | 879 | return ret; |
893 | } | 880 | } |
894 | 881 | ||
@@ -1089,8 +1076,10 @@ static const struct file_operations macvtap_fops = { | |||
1089 | .owner = THIS_MODULE, | 1076 | .owner = THIS_MODULE, |
1090 | .open = macvtap_open, | 1077 | .open = macvtap_open, |
1091 | .release = macvtap_release, | 1078 | .release = macvtap_release, |
1092 | .aio_read = macvtap_aio_read, | 1079 | .read = new_sync_read, |
1093 | .aio_write = macvtap_aio_write, | 1080 | .write = new_sync_write, |
1081 | .read_iter = macvtap_read_iter, | ||
1082 | .write_iter = macvtap_write_iter, | ||
1094 | .poll = macvtap_poll, | 1083 | .poll = macvtap_poll, |
1095 | .llseek = no_llseek, | 1084 | .llseek = no_llseek, |
1096 | .unlocked_ioctl = macvtap_ioctl, | 1085 | .unlocked_ioctl = macvtap_ioctl, |
@@ -1103,8 +1092,9 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1103 | struct msghdr *m, size_t total_len) | 1092 | struct msghdr *m, size_t total_len) |
1104 | { | 1093 | { |
1105 | struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock); | 1094 | struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock); |
1106 | return macvtap_get_user(q, m, m->msg_iov, total_len, m->msg_iovlen, | 1095 | struct iov_iter from; |
1107 | m->msg_flags & MSG_DONTWAIT); | 1096 | iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len); |
1097 | return macvtap_get_user(q, m, &from, m->msg_flags & MSG_DONTWAIT); | ||
1108 | } | 1098 | } |
1109 | 1099 | ||
1110 | static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock, | 1100 | static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock, |
@@ -1112,11 +1102,12 @@ static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1112 | int flags) | 1102 | int flags) |
1113 | { | 1103 | { |
1114 | struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock); | 1104 | struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock); |
1105 | struct iov_iter to; | ||
1115 | int ret; | 1106 | int ret; |
1116 | if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) | 1107 | if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) |
1117 | return -EINVAL; | 1108 | return -EINVAL; |
1118 | ret = macvtap_do_read(q, m->msg_iov, m->msg_iovlen, total_len, | 1109 | iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len); |
1119 | flags & MSG_DONTWAIT); | 1110 | ret = macvtap_do_read(q, &to, flags & MSG_DONTWAIT); |
1120 | if (ret > total_len) { | 1111 | if (ret > total_len) { |
1121 | m->msg_flags |= MSG_TRUNC; | 1112 | m->msg_flags |= MSG_TRUNC; |
1122 | ret = flags & MSG_TRUNC ? ret : total_len; | 1113 | ret = flags & MSG_TRUNC ? ret : total_len; |
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index 443cbbf5c55f..d2408a5e43a6 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c | |||
@@ -869,7 +869,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
869 | ph = (struct pppoe_hdr *)skb_put(skb, total_len + sizeof(struct pppoe_hdr)); | 869 | ph = (struct pppoe_hdr *)skb_put(skb, total_len + sizeof(struct pppoe_hdr)); |
870 | start = (char *)&ph->tag[0]; | 870 | start = (char *)&ph->tag[0]; |
871 | 871 | ||
872 | error = memcpy_fromiovec(start, m->msg_iov, total_len); | 872 | error = memcpy_from_msg(start, m, total_len); |
873 | if (error < 0) { | 873 | if (error < 0) { |
874 | kfree_skb(skb); | 874 | kfree_skb(skb); |
875 | goto end; | 875 | goto end; |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index ac53a7316ecd..4b743c612624 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -1012,28 +1012,29 @@ static struct sk_buff *tun_alloc_skb(struct tun_file *tfile, | |||
1012 | 1012 | ||
1013 | /* Get packet from user space buffer */ | 1013 | /* Get packet from user space buffer */ |
1014 | static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | 1014 | static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, |
1015 | void *msg_control, const struct iovec *iv, | 1015 | void *msg_control, struct iov_iter *from, |
1016 | size_t total_len, size_t count, int noblock) | 1016 | int noblock) |
1017 | { | 1017 | { |
1018 | struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; | 1018 | struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; |
1019 | struct sk_buff *skb; | 1019 | struct sk_buff *skb; |
1020 | size_t total_len = iov_iter_count(from); | ||
1020 | size_t len = total_len, align = NET_SKB_PAD, linear; | 1021 | size_t len = total_len, align = NET_SKB_PAD, linear; |
1021 | struct virtio_net_hdr gso = { 0 }; | 1022 | struct virtio_net_hdr gso = { 0 }; |
1022 | int good_linear; | 1023 | int good_linear; |
1023 | int offset = 0; | ||
1024 | int copylen; | 1024 | int copylen; |
1025 | bool zerocopy = false; | 1025 | bool zerocopy = false; |
1026 | int err; | 1026 | int err; |
1027 | u32 rxhash; | 1027 | u32 rxhash; |
1028 | ssize_t n; | ||
1028 | 1029 | ||
1029 | if (!(tun->flags & TUN_NO_PI)) { | 1030 | if (!(tun->flags & TUN_NO_PI)) { |
1030 | if (len < sizeof(pi)) | 1031 | if (len < sizeof(pi)) |
1031 | return -EINVAL; | 1032 | return -EINVAL; |
1032 | len -= sizeof(pi); | 1033 | len -= sizeof(pi); |
1033 | 1034 | ||
1034 | if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi))) | 1035 | n = copy_from_iter(&pi, sizeof(pi), from); |
1036 | if (n != sizeof(pi)) | ||
1035 | return -EFAULT; | 1037 | return -EFAULT; |
1036 | offset += sizeof(pi); | ||
1037 | } | 1038 | } |
1038 | 1039 | ||
1039 | if (tun->flags & TUN_VNET_HDR) { | 1040 | if (tun->flags & TUN_VNET_HDR) { |
@@ -1041,7 +1042,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1041 | return -EINVAL; | 1042 | return -EINVAL; |
1042 | len -= tun->vnet_hdr_sz; | 1043 | len -= tun->vnet_hdr_sz; |
1043 | 1044 | ||
1044 | if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) | 1045 | n = copy_from_iter(&gso, sizeof(gso), from); |
1046 | if (n != sizeof(gso)) | ||
1045 | return -EFAULT; | 1047 | return -EFAULT; |
1046 | 1048 | ||
1047 | if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && | 1049 | if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && |
@@ -1050,7 +1052,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1050 | 1052 | ||
1051 | if (gso.hdr_len > len) | 1053 | if (gso.hdr_len > len) |
1052 | return -EINVAL; | 1054 | return -EINVAL; |
1053 | offset += tun->vnet_hdr_sz; | 1055 | iov_iter_advance(from, tun->vnet_hdr_sz); |
1054 | } | 1056 | } |
1055 | 1057 | ||
1056 | if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { | 1058 | if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { |
@@ -1063,6 +1065,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1063 | good_linear = SKB_MAX_HEAD(align); | 1065 | good_linear = SKB_MAX_HEAD(align); |
1064 | 1066 | ||
1065 | if (msg_control) { | 1067 | if (msg_control) { |
1068 | struct iov_iter i = *from; | ||
1069 | |||
1066 | /* There are 256 bytes to be copied in skb, so there is | 1070 | /* There are 256 bytes to be copied in skb, so there is |
1067 | * enough room for skb expand head in case it is used. | 1071 | * enough room for skb expand head in case it is used. |
1068 | * The rest of the buffer is mapped from userspace. | 1072 | * The rest of the buffer is mapped from userspace. |
@@ -1071,7 +1075,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1071 | if (copylen > good_linear) | 1075 | if (copylen > good_linear) |
1072 | copylen = good_linear; | 1076 | copylen = good_linear; |
1073 | linear = copylen; | 1077 | linear = copylen; |
1074 | if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS) | 1078 | iov_iter_advance(&i, copylen); |
1079 | if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS) | ||
1075 | zerocopy = true; | 1080 | zerocopy = true; |
1076 | } | 1081 | } |
1077 | 1082 | ||
@@ -1091,9 +1096,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1091 | } | 1096 | } |
1092 | 1097 | ||
1093 | if (zerocopy) | 1098 | if (zerocopy) |
1094 | err = zerocopy_sg_from_iovec(skb, iv, offset, count); | 1099 | err = zerocopy_sg_from_iter(skb, from); |
1095 | else { | 1100 | else { |
1096 | err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len); | 1101 | err = skb_copy_datagram_from_iter(skb, 0, from, len); |
1097 | if (!err && msg_control) { | 1102 | if (!err && msg_control) { |
1098 | struct ubuf_info *uarg = msg_control; | 1103 | struct ubuf_info *uarg = msg_control; |
1099 | uarg->callback(uarg, false); | 1104 | uarg->callback(uarg, false); |
@@ -1207,8 +1212,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1207 | return total_len; | 1212 | return total_len; |
1208 | } | 1213 | } |
1209 | 1214 | ||
1210 | static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, | 1215 | static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from) |
1211 | unsigned long count, loff_t pos) | ||
1212 | { | 1216 | { |
1213 | struct file *file = iocb->ki_filp; | 1217 | struct file *file = iocb->ki_filp; |
1214 | struct tun_struct *tun = tun_get(file); | 1218 | struct tun_struct *tun = tun_get(file); |
@@ -1218,10 +1222,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, | |||
1218 | if (!tun) | 1222 | if (!tun) |
1219 | return -EBADFD; | 1223 | return -EBADFD; |
1220 | 1224 | ||
1221 | tun_debug(KERN_INFO, tun, "tun_chr_write %ld\n", count); | 1225 | result = tun_get_user(tun, tfile, NULL, from, file->f_flags & O_NONBLOCK); |
1222 | |||
1223 | result = tun_get_user(tun, tfile, NULL, iv, iov_length(iv, count), | ||
1224 | count, file->f_flags & O_NONBLOCK); | ||
1225 | 1226 | ||
1226 | tun_put(tun); | 1227 | tun_put(tun); |
1227 | return result; | 1228 | return result; |
@@ -1339,18 +1340,17 @@ done: | |||
1339 | } | 1340 | } |
1340 | 1341 | ||
1341 | static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, | 1342 | static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, |
1342 | const struct iovec *iv, unsigned long segs, | 1343 | struct iov_iter *to, |
1343 | ssize_t len, int noblock) | 1344 | int noblock) |
1344 | { | 1345 | { |
1345 | struct sk_buff *skb; | 1346 | struct sk_buff *skb; |
1346 | ssize_t ret = 0; | 1347 | ssize_t ret; |
1347 | int peeked, err, off = 0; | 1348 | int peeked, err, off = 0; |
1348 | struct iov_iter iter; | ||
1349 | 1349 | ||
1350 | tun_debug(KERN_INFO, tun, "tun_do_read\n"); | 1350 | tun_debug(KERN_INFO, tun, "tun_do_read\n"); |
1351 | 1351 | ||
1352 | if (!len) | 1352 | if (!iov_iter_count(to)) |
1353 | return ret; | 1353 | return 0; |
1354 | 1354 | ||
1355 | if (tun->dev->reg_state != NETREG_REGISTERED) | 1355 | if (tun->dev->reg_state != NETREG_REGISTERED) |
1356 | return -EIO; | 1356 | return -EIO; |
@@ -1359,37 +1359,27 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, | |||
1359 | skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0, | 1359 | skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0, |
1360 | &peeked, &off, &err); | 1360 | &peeked, &off, &err); |
1361 | if (!skb) | 1361 | if (!skb) |
1362 | return ret; | 1362 | return 0; |
1363 | 1363 | ||
1364 | iov_iter_init(&iter, READ, iv, segs, len); | 1364 | ret = tun_put_user(tun, tfile, skb, to); |
1365 | ret = tun_put_user(tun, tfile, skb, &iter); | ||
1366 | kfree_skb(skb); | 1365 | kfree_skb(skb); |
1367 | 1366 | ||
1368 | return ret; | 1367 | return ret; |
1369 | } | 1368 | } |
1370 | 1369 | ||
1371 | static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, | 1370 | static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) |
1372 | unsigned long count, loff_t pos) | ||
1373 | { | 1371 | { |
1374 | struct file *file = iocb->ki_filp; | 1372 | struct file *file = iocb->ki_filp; |
1375 | struct tun_file *tfile = file->private_data; | 1373 | struct tun_file *tfile = file->private_data; |
1376 | struct tun_struct *tun = __tun_get(tfile); | 1374 | struct tun_struct *tun = __tun_get(tfile); |
1377 | ssize_t len, ret; | 1375 | ssize_t len = iov_iter_count(to), ret; |
1378 | 1376 | ||
1379 | if (!tun) | 1377 | if (!tun) |
1380 | return -EBADFD; | 1378 | return -EBADFD; |
1381 | len = iov_length(iv, count); | 1379 | ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK); |
1382 | if (len < 0) { | ||
1383 | ret = -EINVAL; | ||
1384 | goto out; | ||
1385 | } | ||
1386 | |||
1387 | ret = tun_do_read(tun, tfile, iv, count, len, | ||
1388 | file->f_flags & O_NONBLOCK); | ||
1389 | ret = min_t(ssize_t, ret, len); | 1380 | ret = min_t(ssize_t, ret, len); |
1390 | if (ret > 0) | 1381 | if (ret > 0) |
1391 | iocb->ki_pos = ret; | 1382 | iocb->ki_pos = ret; |
1392 | out: | ||
1393 | tun_put(tun); | 1383 | tun_put(tun); |
1394 | return ret; | 1384 | return ret; |
1395 | } | 1385 | } |
@@ -1456,11 +1446,14 @@ static int tun_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1456 | int ret; | 1446 | int ret; |
1457 | struct tun_file *tfile = container_of(sock, struct tun_file, socket); | 1447 | struct tun_file *tfile = container_of(sock, struct tun_file, socket); |
1458 | struct tun_struct *tun = __tun_get(tfile); | 1448 | struct tun_struct *tun = __tun_get(tfile); |
1449 | struct iov_iter from; | ||
1459 | 1450 | ||
1460 | if (!tun) | 1451 | if (!tun) |
1461 | return -EBADFD; | 1452 | return -EBADFD; |
1462 | ret = tun_get_user(tun, tfile, m->msg_control, m->msg_iov, total_len, | 1453 | |
1463 | m->msg_iovlen, m->msg_flags & MSG_DONTWAIT); | 1454 | iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len); |
1455 | ret = tun_get_user(tun, tfile, m->msg_control, &from, | ||
1456 | m->msg_flags & MSG_DONTWAIT); | ||
1464 | tun_put(tun); | 1457 | tun_put(tun); |
1465 | return ret; | 1458 | return ret; |
1466 | } | 1459 | } |
@@ -1471,6 +1464,7 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1471 | { | 1464 | { |
1472 | struct tun_file *tfile = container_of(sock, struct tun_file, socket); | 1465 | struct tun_file *tfile = container_of(sock, struct tun_file, socket); |
1473 | struct tun_struct *tun = __tun_get(tfile); | 1466 | struct tun_struct *tun = __tun_get(tfile); |
1467 | struct iov_iter to; | ||
1474 | int ret; | 1468 | int ret; |
1475 | 1469 | ||
1476 | if (!tun) | 1470 | if (!tun) |
@@ -1485,8 +1479,8 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1485 | SOL_PACKET, TUN_TX_TIMESTAMP); | 1479 | SOL_PACKET, TUN_TX_TIMESTAMP); |
1486 | goto out; | 1480 | goto out; |
1487 | } | 1481 | } |
1488 | ret = tun_do_read(tun, tfile, m->msg_iov, m->msg_iovlen, total_len, | 1482 | iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len); |
1489 | flags & MSG_DONTWAIT); | 1483 | ret = tun_do_read(tun, tfile, &to, flags & MSG_DONTWAIT); |
1490 | if (ret > total_len) { | 1484 | if (ret > total_len) { |
1491 | m->msg_flags |= MSG_TRUNC; | 1485 | m->msg_flags |= MSG_TRUNC; |
1492 | ret = flags & MSG_TRUNC ? ret : total_len; | 1486 | ret = flags & MSG_TRUNC ? ret : total_len; |
@@ -2242,10 +2236,10 @@ static int tun_chr_show_fdinfo(struct seq_file *m, struct file *f) | |||
2242 | static const struct file_operations tun_fops = { | 2236 | static const struct file_operations tun_fops = { |
2243 | .owner = THIS_MODULE, | 2237 | .owner = THIS_MODULE, |
2244 | .llseek = no_llseek, | 2238 | .llseek = no_llseek, |
2245 | .read = do_sync_read, | 2239 | .read = new_sync_read, |
2246 | .aio_read = tun_chr_aio_read, | 2240 | .write = new_sync_write, |
2247 | .write = do_sync_write, | 2241 | .read_iter = tun_chr_read_iter, |
2248 | .aio_write = tun_chr_aio_write, | 2242 | .write_iter = tun_chr_write_iter, |
2249 | .poll = tun_chr_poll, | 2243 | .poll = tun_chr_poll, |
2250 | .unlocked_ioctl = tun_chr_ioctl, | 2244 | .unlocked_ioctl = tun_chr_ioctl, |
2251 | #ifdef CONFIG_COMPAT | 2245 | #ifdef CONFIG_COMPAT |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 78c299f40bac..7691ad5b4771 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -2651,13 +2651,16 @@ static inline int skb_copy_datagram_msg(const struct sk_buff *from, int offset, | |||
2651 | } | 2651 | } |
2652 | int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen, | 2652 | int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen, |
2653 | struct iovec *iov); | 2653 | struct iovec *iov); |
2654 | int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | 2654 | static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen, |
2655 | const struct iovec *from, int from_offset, | 2655 | struct msghdr *msg) |
2656 | int len); | 2656 | { |
2657 | int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *frm, | 2657 | return skb_copy_and_csum_datagram_iovec(skb, hlen, msg->msg_iov); |
2658 | int offset, size_t count); | 2658 | } |
2659 | int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, | ||
2660 | struct iov_iter *from, int len); | ||
2659 | int skb_copy_datagram_iter(const struct sk_buff *from, int offset, | 2661 | int skb_copy_datagram_iter(const struct sk_buff *from, int offset, |
2660 | struct iov_iter *to, int size); | 2662 | struct iov_iter *to, int size); |
2663 | int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *frm); | ||
2661 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb); | 2664 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb); |
2662 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb); | 2665 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb); |
2663 | int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); | 2666 | int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); |
@@ -2682,6 +2685,16 @@ int skb_ensure_writable(struct sk_buff *skb, int write_len); | |||
2682 | int skb_vlan_pop(struct sk_buff *skb); | 2685 | int skb_vlan_pop(struct sk_buff *skb); |
2683 | int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); | 2686 | int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); |
2684 | 2687 | ||
2688 | static inline int memcpy_from_msg(void *data, struct msghdr *msg, int len) | ||
2689 | { | ||
2690 | return memcpy_fromiovec(data, msg->msg_iov, len); | ||
2691 | } | ||
2692 | |||
2693 | static inline int memcpy_to_msg(struct msghdr *msg, void *data, int len) | ||
2694 | { | ||
2695 | return memcpy_toiovec(msg->msg_iov, data, len); | ||
2696 | } | ||
2697 | |||
2685 | struct skb_checksum_ops { | 2698 | struct skb_checksum_ops { |
2686 | __wsum (*update)(const void *mem, int len, __wsum wsum); | 2699 | __wsum (*update)(const void *mem, int len, __wsum wsum); |
2687 | __wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len); | 2700 | __wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len); |
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index 428277869400..0d87674fb775 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h | |||
@@ -103,14 +103,14 @@ struct vsock_transport { | |||
103 | int (*dgram_dequeue)(struct kiocb *kiocb, struct vsock_sock *vsk, | 103 | int (*dgram_dequeue)(struct kiocb *kiocb, struct vsock_sock *vsk, |
104 | struct msghdr *msg, size_t len, int flags); | 104 | struct msghdr *msg, size_t len, int flags); |
105 | int (*dgram_enqueue)(struct vsock_sock *, struct sockaddr_vm *, | 105 | int (*dgram_enqueue)(struct vsock_sock *, struct sockaddr_vm *, |
106 | struct iovec *, size_t len); | 106 | struct msghdr *, size_t len); |
107 | bool (*dgram_allow)(u32 cid, u32 port); | 107 | bool (*dgram_allow)(u32 cid, u32 port); |
108 | 108 | ||
109 | /* STREAM. */ | 109 | /* STREAM. */ |
110 | /* TODO: stream_bind() */ | 110 | /* TODO: stream_bind() */ |
111 | ssize_t (*stream_dequeue)(struct vsock_sock *, struct iovec *, | 111 | ssize_t (*stream_dequeue)(struct vsock_sock *, struct msghdr *, |
112 | size_t len, int flags); | 112 | size_t len, int flags); |
113 | ssize_t (*stream_enqueue)(struct vsock_sock *, struct iovec *, | 113 | ssize_t (*stream_enqueue)(struct vsock_sock *, struct msghdr *, |
114 | size_t len); | 114 | size_t len); |
115 | s64 (*stream_has_data)(struct vsock_sock *); | 115 | s64 (*stream_has_data)(struct vsock_sock *); |
116 | s64 (*stream_has_space)(struct vsock_sock *); | 116 | s64 (*stream_has_space)(struct vsock_sock *); |
diff --git a/include/net/ipx.h b/include/net/ipx.h index 320f47b64a7a..e5cff6811b30 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h | |||
@@ -150,7 +150,7 @@ int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, | |||
150 | unsigned char *node); | 150 | unsigned char *node); |
151 | void ipxrtr_del_routes(struct ipx_interface *intrfc); | 151 | void ipxrtr_del_routes(struct ipx_interface *intrfc); |
152 | int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, | 152 | int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, |
153 | struct iovec *iov, size_t len, int noblock); | 153 | struct msghdr *msg, size_t len, int noblock); |
154 | int ipxrtr_route_skb(struct sk_buff *skb); | 154 | int ipxrtr_route_skb(struct sk_buff *skb); |
155 | struct ipx_route *ipxrtr_lookup(__be32 net); | 155 | struct ipx_route *ipxrtr_lookup(__be32 net); |
156 | int ipxrtr_ioctl(unsigned int cmd, void __user *arg); | 156 | int ipxrtr_ioctl(unsigned int cmd, void __user *arg); |
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 72a31db47ded..487ef34bbd63 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h | |||
@@ -219,7 +219,7 @@ struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *, | |||
219 | const struct sctp_chunk *, | 219 | const struct sctp_chunk *, |
220 | __u32 tsn); | 220 | __u32 tsn); |
221 | struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *, | 221 | struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *, |
222 | const struct msghdr *, size_t msg_len); | 222 | struct msghdr *, size_t msg_len); |
223 | struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, | 223 | struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, |
224 | const struct sctp_chunk *, | 224 | const struct sctp_chunk *, |
225 | const __u8 *, | 225 | const __u8 *, |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 806e3b5b3351..2bb2fcf5b11f 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -531,7 +531,7 @@ struct sctp_datamsg { | |||
531 | 531 | ||
532 | struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, | 532 | struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, |
533 | struct sctp_sndrcvinfo *, | 533 | struct sctp_sndrcvinfo *, |
534 | struct msghdr *, int len); | 534 | struct iov_iter *); |
535 | void sctp_datamsg_free(struct sctp_datamsg *); | 535 | void sctp_datamsg_free(struct sctp_datamsg *); |
536 | void sctp_datamsg_put(struct sctp_datamsg *); | 536 | void sctp_datamsg_put(struct sctp_datamsg *); |
537 | void sctp_chunk_fail(struct sctp_chunk *, int error); | 537 | void sctp_chunk_fail(struct sctp_chunk *, int error); |
@@ -647,8 +647,8 @@ struct sctp_chunk { | |||
647 | 647 | ||
648 | void sctp_chunk_hold(struct sctp_chunk *); | 648 | void sctp_chunk_hold(struct sctp_chunk *); |
649 | void sctp_chunk_put(struct sctp_chunk *); | 649 | void sctp_chunk_put(struct sctp_chunk *); |
650 | int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, | 650 | int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len, |
651 | struct iovec *data); | 651 | struct iov_iter *from); |
652 | void sctp_chunk_free(struct sctp_chunk *); | 652 | void sctp_chunk_free(struct sctp_chunk *); |
653 | void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); | 653 | void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); |
654 | struct sctp_chunk *sctp_chunkify(struct sk_buff *, | 654 | struct sctp_chunk *sctp_chunkify(struct sk_buff *, |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 425942db17f6..0d0766ea5ab1 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -1659,7 +1659,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr | |||
1659 | 1659 | ||
1660 | SOCK_DEBUG(sk, "SK %p: Copy user data (%Zd bytes).\n", sk, len); | 1660 | SOCK_DEBUG(sk, "SK %p: Copy user data (%Zd bytes).\n", sk, len); |
1661 | 1661 | ||
1662 | err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 1662 | err = memcpy_from_msg(skb_put(skb, len), msg, len); |
1663 | if (err) { | 1663 | if (err) { |
1664 | kfree_skb(skb); | 1664 | kfree_skb(skb); |
1665 | err = -EFAULT; | 1665 | err = -EFAULT; |
diff --git a/net/atm/common.c b/net/atm/common.c index 9cd1ccae9a11..f59112944c91 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -570,15 +570,16 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
570 | } | 570 | } |
571 | 571 | ||
572 | int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | 572 | int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, |
573 | size_t total_len) | 573 | size_t size) |
574 | { | 574 | { |
575 | struct sock *sk = sock->sk; | 575 | struct sock *sk = sock->sk; |
576 | DEFINE_WAIT(wait); | 576 | DEFINE_WAIT(wait); |
577 | struct atm_vcc *vcc; | 577 | struct atm_vcc *vcc; |
578 | struct sk_buff *skb; | 578 | struct sk_buff *skb; |
579 | int eff, error; | 579 | int eff, error; |
580 | const void __user *buff; | 580 | struct iov_iter from; |
581 | int size; | 581 | |
582 | iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, size); | ||
582 | 583 | ||
583 | lock_sock(sk); | 584 | lock_sock(sk); |
584 | if (sock->state != SS_CONNECTED) { | 585 | if (sock->state != SS_CONNECTED) { |
@@ -589,12 +590,6 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | |||
589 | error = -EISCONN; | 590 | error = -EISCONN; |
590 | goto out; | 591 | goto out; |
591 | } | 592 | } |
592 | if (m->msg_iovlen != 1) { | ||
593 | error = -ENOSYS; /* fix this later @@@ */ | ||
594 | goto out; | ||
595 | } | ||
596 | buff = m->msg_iov->iov_base; | ||
597 | size = m->msg_iov->iov_len; | ||
598 | vcc = ATM_SD(sock); | 593 | vcc = ATM_SD(sock); |
599 | if (test_bit(ATM_VF_RELEASED, &vcc->flags) || | 594 | if (test_bit(ATM_VF_RELEASED, &vcc->flags) || |
600 | test_bit(ATM_VF_CLOSE, &vcc->flags) || | 595 | test_bit(ATM_VF_CLOSE, &vcc->flags) || |
@@ -607,7 +602,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | |||
607 | error = 0; | 602 | error = 0; |
608 | goto out; | 603 | goto out; |
609 | } | 604 | } |
610 | if (size < 0 || size > vcc->qos.txtp.max_sdu) { | 605 | if (size > vcc->qos.txtp.max_sdu) { |
611 | error = -EMSGSIZE; | 606 | error = -EMSGSIZE; |
612 | goto out; | 607 | goto out; |
613 | } | 608 | } |
@@ -639,7 +634,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | |||
639 | goto out; | 634 | goto out; |
640 | skb->dev = NULL; /* for paths shared with net_device interfaces */ | 635 | skb->dev = NULL; /* for paths shared with net_device interfaces */ |
641 | ATM_SKB(skb)->atm_options = vcc->atm_options; | 636 | ATM_SKB(skb)->atm_options = vcc->atm_options; |
642 | if (copy_from_user(skb_put(skb, size), buff, size)) { | 637 | if (copy_from_iter(skb_put(skb, size), size, &from) != size) { |
643 | kfree_skb(skb); | 638 | kfree_skb(skb); |
644 | error = -EFAULT; | 639 | error = -EFAULT; |
645 | goto out; | 640 | goto out; |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index f4f835e19378..ca049a7c9287 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -1549,7 +1549,7 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1549 | skb_reserve(skb, size - len); | 1549 | skb_reserve(skb, size - len); |
1550 | 1550 | ||
1551 | /* User data follows immediately after the AX.25 data */ | 1551 | /* User data follows immediately after the AX.25 data */ |
1552 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 1552 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { |
1553 | err = -EFAULT; | 1553 | err = -EFAULT; |
1554 | kfree_skb(skb); | 1554 | kfree_skb(skb); |
1555 | goto out; | 1555 | goto out; |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 5e2cd2535978..2c245fdf319a 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -947,7 +947,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
947 | if (!skb) | 947 | if (!skb) |
948 | goto done; | 948 | goto done; |
949 | 949 | ||
950 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 950 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { |
951 | err = -EFAULT; | 951 | err = -EFAULT; |
952 | goto drop; | 952 | goto drop; |
953 | } | 953 | } |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index cbeef5f62f3b..f3e4a16fb157 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -5767,7 +5767,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
5767 | if (!buf) | 5767 | if (!buf) |
5768 | return -ENOMEM; | 5768 | return -ENOMEM; |
5769 | 5769 | ||
5770 | if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) { | 5770 | if (memcpy_from_msg(buf, msg, msglen)) { |
5771 | err = -EFAULT; | 5771 | err = -EFAULT; |
5772 | goto done; | 5772 | goto done; |
5773 | } | 5773 | } |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 8bbbb5ec468c..2348176401a0 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -588,7 +588,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
588 | } | 588 | } |
589 | skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE); | 589 | skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE); |
590 | 590 | ||
591 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 591 | err = memcpy_from_msg(skb_put(skb, size), msg, size); |
592 | if (err) { | 592 | if (err) { |
593 | kfree_skb(skb); | 593 | kfree_skb(skb); |
594 | if (sent == 0) | 594 | if (sent == 0) |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 7ee9e4ab00f8..30e5ea3f1ad3 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -285,7 +285,7 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) | |||
285 | if (!skb) | 285 | if (!skb) |
286 | return err; | 286 | return err; |
287 | 287 | ||
288 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 288 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { |
289 | kfree_skb(skb); | 289 | kfree_skb(skb); |
290 | return -EFAULT; | 290 | return -EFAULT; |
291 | } | 291 | } |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index fbcd156099fb..ac618b0b8a4f 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
@@ -418,7 +418,7 @@ unlock: | |||
418 | } | 418 | } |
419 | release_sock(sk); | 419 | release_sock(sk); |
420 | chunk = min_t(unsigned int, skb->len, size); | 420 | chunk = min_t(unsigned int, skb->len, size); |
421 | if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { | 421 | if (memcpy_to_msg(msg, skb->data, chunk)) { |
422 | skb_queue_head(&sk->sk_receive_queue, skb); | 422 | skb_queue_head(&sk->sk_receive_queue, skb); |
423 | if (copied == 0) | 423 | if (copied == 0) |
424 | copied = -EFAULT; | 424 | copied = -EFAULT; |
@@ -566,7 +566,7 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
566 | 566 | ||
567 | skb_reserve(skb, cf_sk->headroom); | 567 | skb_reserve(skb, cf_sk->headroom); |
568 | 568 | ||
569 | ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 569 | ret = memcpy_from_msg(skb_put(skb, len), msg, len); |
570 | 570 | ||
571 | if (ret) | 571 | if (ret) |
572 | goto err; | 572 | goto err; |
@@ -641,7 +641,7 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
641 | */ | 641 | */ |
642 | size = min_t(int, size, skb_tailroom(skb)); | 642 | size = min_t(int, size, skb_tailroom(skb)); |
643 | 643 | ||
644 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 644 | err = memcpy_from_msg(skb_put(skb, size), msg, size); |
645 | if (err) { | 645 | if (err) { |
646 | kfree_skb(skb); | 646 | kfree_skb(skb); |
647 | goto out_err; | 647 | goto out_err; |
diff --git a/net/can/bcm.c b/net/can/bcm.c index dcb75c0e66c1..01671187e3fe 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -858,8 +858,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
858 | 858 | ||
859 | /* update can_frames content */ | 859 | /* update can_frames content */ |
860 | for (i = 0; i < msg_head->nframes; i++) { | 860 | for (i = 0; i < msg_head->nframes; i++) { |
861 | err = memcpy_fromiovec((u8 *)&op->frames[i], | 861 | err = memcpy_from_msg((u8 *)&op->frames[i], msg, CFSIZ); |
862 | msg->msg_iov, CFSIZ); | ||
863 | 862 | ||
864 | if (op->frames[i].can_dlc > 8) | 863 | if (op->frames[i].can_dlc > 8) |
865 | err = -EINVAL; | 864 | err = -EINVAL; |
@@ -894,8 +893,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
894 | op->frames = &op->sframe; | 893 | op->frames = &op->sframe; |
895 | 894 | ||
896 | for (i = 0; i < msg_head->nframes; i++) { | 895 | for (i = 0; i < msg_head->nframes; i++) { |
897 | err = memcpy_fromiovec((u8 *)&op->frames[i], | 896 | err = memcpy_from_msg((u8 *)&op->frames[i], msg, CFSIZ); |
898 | msg->msg_iov, CFSIZ); | ||
899 | 897 | ||
900 | if (op->frames[i].can_dlc > 8) | 898 | if (op->frames[i].can_dlc > 8) |
901 | err = -EINVAL; | 899 | err = -EINVAL; |
@@ -1024,9 +1022,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
1024 | 1022 | ||
1025 | if (msg_head->nframes) { | 1023 | if (msg_head->nframes) { |
1026 | /* update can_frames content */ | 1024 | /* update can_frames content */ |
1027 | err = memcpy_fromiovec((u8 *)op->frames, | 1025 | err = memcpy_from_msg((u8 *)op->frames, msg, |
1028 | msg->msg_iov, | 1026 | msg_head->nframes * CFSIZ); |
1029 | msg_head->nframes * CFSIZ); | ||
1030 | if (err < 0) | 1027 | if (err < 0) |
1031 | return err; | 1028 | return err; |
1032 | 1029 | ||
@@ -1072,8 +1069,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
1072 | } | 1069 | } |
1073 | 1070 | ||
1074 | if (msg_head->nframes) { | 1071 | if (msg_head->nframes) { |
1075 | err = memcpy_fromiovec((u8 *)op->frames, msg->msg_iov, | 1072 | err = memcpy_from_msg((u8 *)op->frames, msg, |
1076 | msg_head->nframes * CFSIZ); | 1073 | msg_head->nframes * CFSIZ); |
1077 | if (err < 0) { | 1074 | if (err < 0) { |
1078 | if (op->frames != &op->sframe) | 1075 | if (op->frames != &op->sframe) |
1079 | kfree(op->frames); | 1076 | kfree(op->frames); |
@@ -1209,7 +1206,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk) | |||
1209 | 1206 | ||
1210 | can_skb_reserve(skb); | 1207 | can_skb_reserve(skb); |
1211 | 1208 | ||
1212 | err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ); | 1209 | err = memcpy_from_msg(skb_put(skb, CFSIZ), msg, CFSIZ); |
1213 | if (err < 0) { | 1210 | if (err < 0) { |
1214 | kfree_skb(skb); | 1211 | kfree_skb(skb); |
1215 | return err; | 1212 | return err; |
@@ -1285,7 +1282,7 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1285 | 1282 | ||
1286 | /* read message head information */ | 1283 | /* read message head information */ |
1287 | 1284 | ||
1288 | ret = memcpy_fromiovec((u8 *)&msg_head, msg->msg_iov, MHSIZ); | 1285 | ret = memcpy_from_msg((u8 *)&msg_head, msg, MHSIZ); |
1289 | if (ret < 0) | 1286 | if (ret < 0) |
1290 | return ret; | 1287 | return ret; |
1291 | 1288 | ||
@@ -1558,7 +1555,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1558 | if (skb->len < size) | 1555 | if (skb->len < size) |
1559 | size = skb->len; | 1556 | size = skb->len; |
1560 | 1557 | ||
1561 | err = memcpy_toiovec(msg->msg_iov, skb->data, size); | 1558 | err = memcpy_to_msg(msg, skb->data, size); |
1562 | if (err < 0) { | 1559 | if (err < 0) { |
1563 | skb_free_datagram(sk, skb); | 1560 | skb_free_datagram(sk, skb); |
1564 | return err; | 1561 | return err; |
diff --git a/net/can/raw.c b/net/can/raw.c index 081e81fd017f..dfdcffbb1070 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -703,7 +703,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
703 | can_skb_reserve(skb); | 703 | can_skb_reserve(skb); |
704 | can_skb_prv(skb)->ifindex = dev->ifindex; | 704 | can_skb_prv(skb)->ifindex = dev->ifindex; |
705 | 705 | ||
706 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 706 | err = memcpy_from_msg(skb_put(skb, size), msg, size); |
707 | if (err < 0) | 707 | if (err < 0) |
708 | goto free_skb; | 708 | goto free_skb; |
709 | 709 | ||
@@ -750,7 +750,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
750 | else | 750 | else |
751 | size = skb->len; | 751 | size = skb->len; |
752 | 752 | ||
753 | err = memcpy_toiovec(msg->msg_iov, skb->data, size); | 753 | err = memcpy_to_msg(msg, skb->data, size); |
754 | if (err < 0) { | 754 | if (err < 0) { |
755 | skb_free_datagram(sk, skb); | 755 | skb_free_datagram(sk, skb); |
756 | return err; | 756 | return err; |
diff --git a/net/core/datagram.c b/net/core/datagram.c index 26391a3fe3e5..b6e303b0f01f 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -480,18 +480,16 @@ short_copy: | |||
480 | EXPORT_SYMBOL(skb_copy_datagram_iter); | 480 | EXPORT_SYMBOL(skb_copy_datagram_iter); |
481 | 481 | ||
482 | /** | 482 | /** |
483 | * skb_copy_datagram_from_iovec - Copy a datagram from an iovec. | 483 | * skb_copy_datagram_from_iter - Copy a datagram from an iov_iter. |
484 | * @skb: buffer to copy | 484 | * @skb: buffer to copy |
485 | * @offset: offset in the buffer to start copying to | 485 | * @offset: offset in the buffer to start copying to |
486 | * @from: io vector to copy to | 486 | * @from: the copy source |
487 | * @from_offset: offset in the io vector to start copying from | ||
488 | * @len: amount of data to copy to buffer from iovec | 487 | * @len: amount of data to copy to buffer from iovec |
489 | * | 488 | * |
490 | * Returns 0 or -EFAULT. | 489 | * Returns 0 or -EFAULT. |
491 | * Note: the iovec is not modified during the copy. | ||
492 | */ | 490 | */ |
493 | int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | 491 | int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, |
494 | const struct iovec *from, int from_offset, | 492 | struct iov_iter *from, |
495 | int len) | 493 | int len) |
496 | { | 494 | { |
497 | int start = skb_headlen(skb); | 495 | int start = skb_headlen(skb); |
@@ -502,13 +500,11 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | |||
502 | if (copy > 0) { | 500 | if (copy > 0) { |
503 | if (copy > len) | 501 | if (copy > len) |
504 | copy = len; | 502 | copy = len; |
505 | if (memcpy_fromiovecend(skb->data + offset, from, from_offset, | 503 | if (copy_from_iter(skb->data + offset, copy, from) != copy) |
506 | copy)) | ||
507 | goto fault; | 504 | goto fault; |
508 | if ((len -= copy) == 0) | 505 | if ((len -= copy) == 0) |
509 | return 0; | 506 | return 0; |
510 | offset += copy; | 507 | offset += copy; |
511 | from_offset += copy; | ||
512 | } | 508 | } |
513 | 509 | ||
514 | /* Copy paged appendix. Hmm... why does this look so complicated? */ | 510 | /* Copy paged appendix. Hmm... why does this look so complicated? */ |
@@ -520,24 +516,19 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | |||
520 | 516 | ||
521 | end = start + skb_frag_size(frag); | 517 | end = start + skb_frag_size(frag); |
522 | if ((copy = end - offset) > 0) { | 518 | if ((copy = end - offset) > 0) { |
523 | int err; | 519 | size_t copied; |
524 | u8 *vaddr; | ||
525 | struct page *page = skb_frag_page(frag); | ||
526 | 520 | ||
527 | if (copy > len) | 521 | if (copy > len) |
528 | copy = len; | 522 | copy = len; |
529 | vaddr = kmap(page); | 523 | copied = copy_page_from_iter(skb_frag_page(frag), |
530 | err = memcpy_fromiovecend(vaddr + frag->page_offset + | 524 | frag->page_offset + offset - start, |
531 | offset - start, | 525 | copy, from); |
532 | from, from_offset, copy); | 526 | if (copied != copy) |
533 | kunmap(page); | ||
534 | if (err) | ||
535 | goto fault; | 527 | goto fault; |
536 | 528 | ||
537 | if (!(len -= copy)) | 529 | if (!(len -= copy)) |
538 | return 0; | 530 | return 0; |
539 | offset += copy; | 531 | offset += copy; |
540 | from_offset += copy; | ||
541 | } | 532 | } |
542 | start = end; | 533 | start = end; |
543 | } | 534 | } |
@@ -551,16 +542,13 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | |||
551 | if ((copy = end - offset) > 0) { | 542 | if ((copy = end - offset) > 0) { |
552 | if (copy > len) | 543 | if (copy > len) |
553 | copy = len; | 544 | copy = len; |
554 | if (skb_copy_datagram_from_iovec(frag_iter, | 545 | if (skb_copy_datagram_from_iter(frag_iter, |
555 | offset - start, | 546 | offset - start, |
556 | from, | 547 | from, copy)) |
557 | from_offset, | ||
558 | copy)) | ||
559 | goto fault; | 548 | goto fault; |
560 | if ((len -= copy) == 0) | 549 | if ((len -= copy) == 0) |
561 | return 0; | 550 | return 0; |
562 | offset += copy; | 551 | offset += copy; |
563 | from_offset += copy; | ||
564 | } | 552 | } |
565 | start = end; | 553 | start = end; |
566 | } | 554 | } |
@@ -570,78 +558,61 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | |||
570 | fault: | 558 | fault: |
571 | return -EFAULT; | 559 | return -EFAULT; |
572 | } | 560 | } |
573 | EXPORT_SYMBOL(skb_copy_datagram_from_iovec); | 561 | EXPORT_SYMBOL(skb_copy_datagram_from_iter); |
574 | 562 | ||
575 | /** | 563 | /** |
576 | * zerocopy_sg_from_iovec - Build a zerocopy datagram from an iovec | 564 | * zerocopy_sg_from_iter - Build a zerocopy datagram from an iov_iter |
577 | * @skb: buffer to copy | 565 | * @skb: buffer to copy |
578 | * @from: io vector to copy from | 566 | * @from: the source to copy from |
579 | * @offset: offset in the io vector to start copying from | ||
580 | * @count: amount of vectors to copy to buffer from | ||
581 | * | 567 | * |
582 | * The function will first copy up to headlen, and then pin the userspace | 568 | * The function will first copy up to headlen, and then pin the userspace |
583 | * pages and build frags through them. | 569 | * pages and build frags through them. |
584 | * | 570 | * |
585 | * Returns 0, -EFAULT or -EMSGSIZE. | 571 | * Returns 0, -EFAULT or -EMSGSIZE. |
586 | * Note: the iovec is not modified during the copy | ||
587 | */ | 572 | */ |
588 | int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, | 573 | int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from) |
589 | int offset, size_t count) | ||
590 | { | 574 | { |
591 | int len = iov_length(from, count) - offset; | 575 | int len = iov_iter_count(from); |
592 | int copy = min_t(int, skb_headlen(skb), len); | 576 | int copy = min_t(int, skb_headlen(skb), len); |
593 | int size; | 577 | int frag = 0; |
594 | int i = 0; | ||
595 | 578 | ||
596 | /* copy up to skb headlen */ | 579 | /* copy up to skb headlen */ |
597 | if (skb_copy_datagram_from_iovec(skb, 0, from, offset, copy)) | 580 | if (skb_copy_datagram_from_iter(skb, 0, from, copy)) |
598 | return -EFAULT; | 581 | return -EFAULT; |
599 | 582 | ||
600 | if (len == copy) | 583 | while (iov_iter_count(from)) { |
601 | return 0; | 584 | struct page *pages[MAX_SKB_FRAGS]; |
602 | 585 | size_t start; | |
603 | offset += copy; | 586 | ssize_t copied; |
604 | while (count--) { | ||
605 | struct page *page[MAX_SKB_FRAGS]; | ||
606 | int num_pages; | ||
607 | unsigned long base; | ||
608 | unsigned long truesize; | 587 | unsigned long truesize; |
588 | int n = 0; | ||
609 | 589 | ||
610 | /* Skip over from offset and copied */ | 590 | if (frag == MAX_SKB_FRAGS) |
611 | if (offset >= from->iov_len) { | ||
612 | offset -= from->iov_len; | ||
613 | ++from; | ||
614 | continue; | ||
615 | } | ||
616 | len = from->iov_len - offset; | ||
617 | base = (unsigned long)from->iov_base + offset; | ||
618 | size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; | ||
619 | if (i + size > MAX_SKB_FRAGS) | ||
620 | return -EMSGSIZE; | 591 | return -EMSGSIZE; |
621 | num_pages = get_user_pages_fast(base, size, 0, &page[i]); | 592 | |
622 | if (num_pages != size) { | 593 | copied = iov_iter_get_pages(from, pages, ~0U, |
623 | release_pages(&page[i], num_pages, 0); | 594 | MAX_SKB_FRAGS - frag, &start); |
595 | if (copied < 0) | ||
624 | return -EFAULT; | 596 | return -EFAULT; |
625 | } | 597 | |
626 | truesize = size * PAGE_SIZE; | 598 | iov_iter_advance(from, copied); |
627 | skb->data_len += len; | 599 | |
628 | skb->len += len; | 600 | truesize = PAGE_ALIGN(copied + start); |
601 | skb->data_len += copied; | ||
602 | skb->len += copied; | ||
629 | skb->truesize += truesize; | 603 | skb->truesize += truesize; |
630 | atomic_add(truesize, &skb->sk->sk_wmem_alloc); | 604 | atomic_add(truesize, &skb->sk->sk_wmem_alloc); |
631 | while (len) { | 605 | while (copied) { |
632 | int off = base & ~PAGE_MASK; | 606 | int size = min_t(int, copied, PAGE_SIZE - start); |
633 | int size = min_t(int, len, PAGE_SIZE - off); | 607 | skb_fill_page_desc(skb, frag++, pages[n], start, size); |
634 | skb_fill_page_desc(skb, i, page[i], off, size); | 608 | start = 0; |
635 | base += size; | 609 | copied -= size; |
636 | len -= size; | 610 | n++; |
637 | i++; | ||
638 | } | 611 | } |
639 | offset = 0; | ||
640 | ++from; | ||
641 | } | 612 | } |
642 | return 0; | 613 | return 0; |
643 | } | 614 | } |
644 | EXPORT_SYMBOL(zerocopy_sg_from_iovec); | 615 | EXPORT_SYMBOL(zerocopy_sg_from_iter); |
645 | 616 | ||
646 | static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, | 617 | static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, |
647 | u8 __user *to, int len, | 618 | u8 __user *to, int len, |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 8e6ae9422a7b..19f038739087 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -781,7 +781,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
781 | goto out_release; | 781 | goto out_release; |
782 | 782 | ||
783 | skb_reserve(skb, sk->sk_prot->max_header); | 783 | skb_reserve(skb, sk->sk_prot->max_header); |
784 | rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 784 | rc = memcpy_from_msg(skb_put(skb, len), msg, len); |
785 | if (rc != 0) | 785 | if (rc != 0) |
786 | goto out_discard; | 786 | goto out_discard; |
787 | 787 | ||
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 25733d538147..810228646de3 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -1760,7 +1760,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1760 | if ((chunk + copied) > size) | 1760 | if ((chunk + copied) > size) |
1761 | chunk = size - copied; | 1761 | chunk = size - copied; |
1762 | 1762 | ||
1763 | if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { | 1763 | if (memcpy_to_msg(msg, skb->data, chunk)) { |
1764 | rv = -EFAULT; | 1764 | rv = -EFAULT; |
1765 | break; | 1765 | break; |
1766 | } | 1766 | } |
@@ -2032,7 +2032,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
2032 | 2032 | ||
2033 | skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER); | 2033 | skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER); |
2034 | 2034 | ||
2035 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 2035 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { |
2036 | err = -EFAULT; | 2036 | err = -EFAULT; |
2037 | goto out; | 2037 | goto out; |
2038 | } | 2038 | } |
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index b8555ec71387..2c7a93e7167e 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c | |||
@@ -276,7 +276,7 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
276 | if (err < 0) | 276 | if (err < 0) |
277 | goto out_skb; | 277 | goto out_skb; |
278 | 278 | ||
279 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 279 | err = memcpy_from_msg(skb_put(skb, size), msg, size); |
280 | if (err < 0) | 280 | if (err < 0) |
281 | goto out_skb; | 281 | goto out_skb; |
282 | 282 | ||
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c index 21c38945ab8b..61e9d2972947 100644 --- a/net/ieee802154/raw.c +++ b/net/ieee802154/raw.c | |||
@@ -150,7 +150,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
150 | skb_reset_mac_header(skb); | 150 | skb_reset_mac_header(skb); |
151 | skb_reset_network_header(skb); | 151 | skb_reset_network_header(skb); |
152 | 152 | ||
153 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 153 | err = memcpy_from_msg(skb_put(skb, size), msg, size); |
154 | if (err < 0) | 154 | if (err < 0) |
155 | goto out_skb; | 155 | goto out_skb; |
156 | 156 | ||
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index ce2920f5bef3..ef8f6ee90473 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -660,7 +660,7 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len, | |||
660 | * Fetch the ICMP header provided by the userland. | 660 | * Fetch the ICMP header provided by the userland. |
661 | * iovec is modified! The ICMP header is consumed. | 661 | * iovec is modified! The ICMP header is consumed. |
662 | */ | 662 | */ |
663 | if (memcpy_fromiovec(user_icmph, msg->msg_iov, icmph_len)) | 663 | if (memcpy_from_msg(user_icmph, msg, icmph_len)) |
664 | return -EFAULT; | 664 | return -EFAULT; |
665 | 665 | ||
666 | if (family == AF_INET) { | 666 | if (family == AF_INET) { |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index c239f4740d10..435443bfc3c3 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1349,7 +1349,7 @@ static int tcp_recv_urg(struct sock *sk, struct msghdr *msg, int len, int flags) | |||
1349 | 1349 | ||
1350 | if (len > 0) { | 1350 | if (len > 0) { |
1351 | if (!(flags & MSG_TRUNC)) | 1351 | if (!(flags & MSG_TRUNC)) |
1352 | err = memcpy_toiovec(msg->msg_iov, &c, 1); | 1352 | err = memcpy_to_msg(msg, &c, 1); |
1353 | len = 1; | 1353 | len = 1; |
1354 | } else | 1354 | } else |
1355 | msg->msg_flags |= MSG_TRUNC; | 1355 | msg->msg_flags |= MSG_TRUNC; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index d22a31f27ab4..69de1a1c05c9 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4368,7 +4368,7 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) | |||
4368 | if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) | 4368 | if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) |
4369 | goto err_free; | 4369 | goto err_free; |
4370 | 4370 | ||
4371 | if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size)) | 4371 | if (memcpy_from_msg(skb_put(skb, size), msg, size)) |
4372 | goto err_free; | 4372 | goto err_free; |
4373 | 4373 | ||
4374 | TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; | 4374 | TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 4a16b9129079..b2d606833ce4 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1284,9 +1284,8 @@ try_again: | |||
1284 | err = skb_copy_datagram_msg(skb, sizeof(struct udphdr), | 1284 | err = skb_copy_datagram_msg(skb, sizeof(struct udphdr), |
1285 | msg, copied); | 1285 | msg, copied); |
1286 | else { | 1286 | else { |
1287 | err = skb_copy_and_csum_datagram_iovec(skb, | 1287 | err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), |
1288 | sizeof(struct udphdr), | 1288 | msg); |
1289 | msg->msg_iov); | ||
1290 | 1289 | ||
1291 | if (err == -EINVAL) | 1290 | if (err == -EINVAL) |
1292 | goto csum_copy_err; | 1291 | goto csum_copy_err; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 0cbcf98f2cab..8baa53e17a30 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -492,7 +492,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
492 | goto csum_copy_err; | 492 | goto csum_copy_err; |
493 | err = skb_copy_datagram_msg(skb, 0, msg, copied); | 493 | err = skb_copy_datagram_msg(skb, 0, msg, copied); |
494 | } else { | 494 | } else { |
495 | err = skb_copy_and_csum_datagram_iovec(skb, 0, msg->msg_iov); | 495 | err = skb_copy_and_csum_datagram_msg(skb, 0, msg); |
496 | if (err == -EINVAL) | 496 | if (err == -EINVAL) |
497 | goto csum_copy_err; | 497 | goto csum_copy_err; |
498 | } | 498 | } |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index dbc0b042bdd6..7cfb5d745a2d 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -428,7 +428,7 @@ try_again: | |||
428 | err = skb_copy_datagram_msg(skb, sizeof(struct udphdr), | 428 | err = skb_copy_datagram_msg(skb, sizeof(struct udphdr), |
429 | msg, copied); | 429 | msg, copied); |
430 | else { | 430 | else { |
431 | err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); | 431 | err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), msg); |
432 | if (err == -EINVAL) | 432 | if (err == -EINVAL) |
433 | goto csum_copy_err; | 433 | goto csum_copy_err; |
434 | } | 434 | } |
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 97dc4320ac15..f11ad1d95e0e 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -1745,8 +1745,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1745 | memcpy(usipx->sipx_node, ipxs->dest_addr.node, IPX_NODE_LEN); | 1745 | memcpy(usipx->sipx_node, ipxs->dest_addr.node, IPX_NODE_LEN); |
1746 | } | 1746 | } |
1747 | 1747 | ||
1748 | rc = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, | 1748 | rc = ipxrtr_route_packet(sk, usipx, msg, len, flags & MSG_DONTWAIT); |
1749 | flags & MSG_DONTWAIT); | ||
1750 | if (rc >= 0) | 1749 | if (rc >= 0) |
1751 | rc = len; | 1750 | rc = len; |
1752 | out: | 1751 | out: |
diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c index 67e7ad3d46b1..3e2a32a9f3bd 100644 --- a/net/ipx/ipx_route.c +++ b/net/ipx/ipx_route.c | |||
@@ -165,7 +165,7 @@ int ipxrtr_route_skb(struct sk_buff *skb) | |||
165 | * Route an outgoing frame from a socket. | 165 | * Route an outgoing frame from a socket. |
166 | */ | 166 | */ |
167 | int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, | 167 | int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, |
168 | struct iovec *iov, size_t len, int noblock) | 168 | struct msghdr *msg, size_t len, int noblock) |
169 | { | 169 | { |
170 | struct sk_buff *skb; | 170 | struct sk_buff *skb; |
171 | struct ipx_sock *ipxs = ipx_sk(sk); | 171 | struct ipx_sock *ipxs = ipx_sk(sk); |
@@ -229,7 +229,7 @@ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, | |||
229 | memcpy(ipx->ipx_dest.node, usipx->sipx_node, IPX_NODE_LEN); | 229 | memcpy(ipx->ipx_dest.node, usipx->sipx_node, IPX_NODE_LEN); |
230 | ipx->ipx_dest.sock = usipx->sipx_port; | 230 | ipx->ipx_dest.sock = usipx->sipx_port; |
231 | 231 | ||
232 | rc = memcpy_fromiovec(skb_put(skb, len), iov, len); | 232 | rc = memcpy_from_msg(skb_put(skb, len), msg, len); |
233 | if (rc) { | 233 | if (rc) { |
234 | kfree_skb(skb); | 234 | kfree_skb(skb); |
235 | goto out_put; | 235 | goto out_put; |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index e8c409055922..568edc72d737 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -1319,7 +1319,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1319 | skb_reserve(skb, self->max_header_size + 16); | 1319 | skb_reserve(skb, self->max_header_size + 16); |
1320 | skb_reset_transport_header(skb); | 1320 | skb_reset_transport_header(skb); |
1321 | skb_put(skb, len); | 1321 | skb_put(skb, len); |
1322 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); | 1322 | err = memcpy_from_msg(skb_transport_header(skb), msg, len); |
1323 | if (err) { | 1323 | if (err) { |
1324 | kfree_skb(skb); | 1324 | kfree_skb(skb); |
1325 | goto out_err; | 1325 | goto out_err; |
@@ -1466,7 +1466,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1466 | } | 1466 | } |
1467 | 1467 | ||
1468 | chunk = min_t(unsigned int, skb->len, size); | 1468 | chunk = min_t(unsigned int, skb->len, size); |
1469 | if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { | 1469 | if (memcpy_to_msg(msg, skb->data, chunk)) { |
1470 | skb_queue_head(&sk->sk_receive_queue, skb); | 1470 | skb_queue_head(&sk->sk_receive_queue, skb); |
1471 | if (copied == 0) | 1471 | if (copied == 0) |
1472 | copied = -EFAULT; | 1472 | copied = -EFAULT; |
@@ -1569,7 +1569,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1569 | 1569 | ||
1570 | pr_debug("%s(), appending user data\n", __func__); | 1570 | pr_debug("%s(), appending user data\n", __func__); |
1571 | skb_put(skb, len); | 1571 | skb_put(skb, len); |
1572 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); | 1572 | err = memcpy_from_msg(skb_transport_header(skb), msg, len); |
1573 | if (err) { | 1573 | if (err) { |
1574 | kfree_skb(skb); | 1574 | kfree_skb(skb); |
1575 | goto out; | 1575 | goto out; |
@@ -1678,7 +1678,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
1678 | 1678 | ||
1679 | pr_debug("%s(), appending user data\n", __func__); | 1679 | pr_debug("%s(), appending user data\n", __func__); |
1680 | skb_put(skb, len); | 1680 | skb_put(skb, len); |
1681 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); | 1681 | err = memcpy_from_msg(skb_transport_header(skb), msg, len); |
1682 | if (err) { | 1682 | if (err) { |
1683 | kfree_skb(skb); | 1683 | kfree_skb(skb); |
1684 | goto out; | 1684 | goto out; |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 057b5647ef92..1cd3f8107239 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -1122,7 +1122,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1122 | } | 1122 | } |
1123 | if (iucv->transport == AF_IUCV_TRANS_HIPER) | 1123 | if (iucv->transport == AF_IUCV_TRANS_HIPER) |
1124 | skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN); | 1124 | skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN); |
1125 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 1125 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { |
1126 | err = -EFAULT; | 1126 | err = -EFAULT; |
1127 | goto fail; | 1127 | goto fail; |
1128 | } | 1128 | } |
diff --git a/net/key/af_key.c b/net/key/af_key.c index e5883091a8c6..f8ac939d52b4 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -3611,7 +3611,7 @@ static int pfkey_sendmsg(struct kiocb *kiocb, | |||
3611 | goto out; | 3611 | goto out; |
3612 | 3612 | ||
3613 | err = -EFAULT; | 3613 | err = -EFAULT; |
3614 | if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) | 3614 | if (memcpy_from_msg(skb_put(skb,len), msg, len)) |
3615 | goto out; | 3615 | goto out; |
3616 | 3616 | ||
3617 | hdr = pfkey_get_base_msg(skb, &err); | 3617 | hdr = pfkey_get_base_msg(skb, &err); |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index a6cc1fed2b52..05dfc8aa36af 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -441,7 +441,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
441 | *((__be32 *) skb_put(skb, 4)) = 0; | 441 | *((__be32 *) skb_put(skb, 4)) = 0; |
442 | 442 | ||
443 | /* Copy user data into skb */ | 443 | /* Copy user data into skb */ |
444 | rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 444 | rc = memcpy_from_msg(skb_put(skb, len), msg, len); |
445 | if (rc < 0) { | 445 | if (rc < 0) { |
446 | kfree_skb(skb); | 446 | kfree_skb(skb); |
447 | goto error; | 447 | goto error; |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index c559bcdf4679..cc7a828fc914 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -346,8 +346,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
346 | skb_put(skb, 2); | 346 | skb_put(skb, 2); |
347 | 347 | ||
348 | /* Copy user data into skb */ | 348 | /* Copy user data into skb */ |
349 | error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov, | 349 | error = memcpy_from_msg(skb_put(skb, total_len), m, total_len); |
350 | total_len); | ||
351 | if (error < 0) { | 350 | if (error < 0) { |
352 | kfree_skb(skb); | 351 | kfree_skb(skb); |
353 | goto error_put_sess_tun; | 352 | goto error_put_sess_tun; |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index af662669f951..2c0b83ce43bd 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -921,7 +921,7 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
921 | skb->dev = llc->dev; | 921 | skb->dev = llc->dev; |
922 | skb->protocol = llc_proto_type(addr->sllc_arphrd); | 922 | skb->protocol = llc_proto_type(addr->sllc_arphrd); |
923 | skb_reserve(skb, hdrlen); | 923 | skb_reserve(skb, hdrlen); |
924 | rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied); | 924 | rc = memcpy_from_msg(skb_put(skb, copied), msg, copied); |
925 | if (rc) | 925 | if (rc) |
926 | goto out; | 926 | goto out; |
927 | if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) { | 927 | if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) { |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index e1aad6eeac14..63aa5c8acf12 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -2325,7 +2325,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
2325 | NETLINK_CB(skb).flags = netlink_skb_flags; | 2325 | NETLINK_CB(skb).flags = netlink_skb_flags; |
2326 | 2326 | ||
2327 | err = -EFAULT; | 2327 | err = -EFAULT; |
2328 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 2328 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { |
2329 | kfree_skb(skb); | 2329 | kfree_skb(skb); |
2330 | goto out; | 2330 | goto out; |
2331 | } | 2331 | } |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 7e13f6afcd1f..69f1d5e9959f 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -1113,7 +1113,7 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1113 | skb_put(skb, len); | 1113 | skb_put(skb, len); |
1114 | 1114 | ||
1115 | /* User data follows immediately after the NET/ROM transport header */ | 1115 | /* User data follows immediately after the NET/ROM transport header */ |
1116 | if (memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len)) { | 1116 | if (memcpy_from_msg(skb_transport_header(skb), msg, len)) { |
1117 | kfree_skb(skb); | 1117 | kfree_skb(skb); |
1118 | err = -EFAULT; | 1118 | err = -EFAULT; |
1119 | goto out; | 1119 | goto out; |
diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index a3ad69a4c648..c4da0c2d8a14 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c | |||
@@ -665,7 +665,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | |||
665 | if (msg_data == NULL) | 665 | if (msg_data == NULL) |
666 | return -ENOMEM; | 666 | return -ENOMEM; |
667 | 667 | ||
668 | if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) { | 668 | if (memcpy_from_msg(msg_data, msg, len)) { |
669 | kfree(msg_data); | 669 | kfree(msg_data); |
670 | return -EFAULT; | 670 | return -EFAULT; |
671 | } | 671 | } |
@@ -731,7 +731,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, | |||
731 | if (msg_data == NULL) | 731 | if (msg_data == NULL) |
732 | return -ENOMEM; | 732 | return -ENOMEM; |
733 | 733 | ||
734 | if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) { | 734 | if (memcpy_from_msg(msg_data, msg, len)) { |
735 | kfree(msg_data); | 735 | kfree(msg_data); |
736 | return -EFAULT; | 736 | return -EFAULT; |
737 | } | 737 | } |
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 9d7d2b7ba5e4..373e138c0ab6 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c | |||
@@ -231,7 +231,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
231 | if (skb == NULL) | 231 | if (skb == NULL) |
232 | return rc; | 232 | return rc; |
233 | 233 | ||
234 | rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 234 | rc = memcpy_from_msg(skb_put(skb, len), msg, len); |
235 | if (rc < 0) { | 235 | if (rc < 0) { |
236 | kfree_skb(skb); | 236 | kfree_skb(skb); |
237 | return rc; | 237 | return rc; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 58af58026dd2..dfb148e9fdaa 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1676,7 +1676,7 @@ retry: | |||
1676 | if (len < hhlen) | 1676 | if (len < hhlen) |
1677 | skb_reset_network_header(skb); | 1677 | skb_reset_network_header(skb); |
1678 | } | 1678 | } |
1679 | err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 1679 | err = memcpy_from_msg(skb_put(skb, len), msg, len); |
1680 | if (err) | 1680 | if (err) |
1681 | goto out_free; | 1681 | goto out_free; |
1682 | goto retry; | 1682 | goto retry; |
@@ -2408,6 +2408,10 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2408 | unsigned short gso_type = 0; | 2408 | unsigned short gso_type = 0; |
2409 | int hlen, tlen; | 2409 | int hlen, tlen; |
2410 | int extra_len = 0; | 2410 | int extra_len = 0; |
2411 | struct iov_iter from; | ||
2412 | ssize_t n; | ||
2413 | |||
2414 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len); | ||
2411 | 2415 | ||
2412 | /* | 2416 | /* |
2413 | * Get and verify the address. | 2417 | * Get and verify the address. |
@@ -2446,9 +2450,9 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2446 | 2450 | ||
2447 | len -= vnet_hdr_len; | 2451 | len -= vnet_hdr_len; |
2448 | 2452 | ||
2449 | err = memcpy_fromiovec((void *)&vnet_hdr, msg->msg_iov, | 2453 | err = -EFAULT; |
2450 | vnet_hdr_len); | 2454 | n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from); |
2451 | if (err < 0) | 2455 | if (n != vnet_hdr_len) |
2452 | goto out_unlock; | 2456 | goto out_unlock; |
2453 | 2457 | ||
2454 | if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && | 2458 | if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && |
@@ -2518,7 +2522,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2518 | } | 2522 | } |
2519 | 2523 | ||
2520 | /* Returns -EFAULT on error */ | 2524 | /* Returns -EFAULT on error */ |
2521 | err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len); | 2525 | err = skb_copy_datagram_from_iter(skb, offset, &from, len); |
2522 | if (err) | 2526 | if (err) |
2523 | goto out_free; | 2527 | goto out_free; |
2524 | 2528 | ||
@@ -2950,8 +2954,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
2950 | vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID; | 2954 | vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID; |
2951 | } /* else everything is zero */ | 2955 | } /* else everything is zero */ |
2952 | 2956 | ||
2953 | err = memcpy_toiovec(msg->msg_iov, (void *)&vnet_hdr, | 2957 | err = memcpy_to_msg(msg, (void *)&vnet_hdr, vnet_hdr_len); |
2954 | vnet_hdr_len); | ||
2955 | if (err < 0) | 2958 | if (err < 0) |
2956 | goto out_free; | 2959 | goto out_free; |
2957 | } | 2960 | } |
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c index 0918bc21eae6..26054b4b467c 100644 --- a/net/phonet/datagram.c +++ b/net/phonet/datagram.c | |||
@@ -109,7 +109,7 @@ static int pn_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
109 | return err; | 109 | return err; |
110 | skb_reserve(skb, MAX_PHONET_HEADER); | 110 | skb_reserve(skb, MAX_PHONET_HEADER); |
111 | 111 | ||
112 | err = memcpy_fromiovec((void *)skb_put(skb, len), msg->msg_iov, len); | 112 | err = memcpy_from_msg((void *)skb_put(skb, len), msg, len); |
113 | if (err < 0) { | 113 | if (err < 0) { |
114 | kfree_skb(skb); | 114 | kfree_skb(skb); |
115 | return err; | 115 | return err; |
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 9cd069dfaf65..5d3f2b7507d4 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -1141,7 +1141,7 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1141 | return err; | 1141 | return err; |
1142 | 1142 | ||
1143 | skb_reserve(skb, MAX_PHONET_HEADER + 3 + pn->aligned); | 1143 | skb_reserve(skb, MAX_PHONET_HEADER + 3 + pn->aligned); |
1144 | err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 1144 | err = memcpy_from_msg(skb_put(skb, len), msg, len); |
1145 | if (err < 0) | 1145 | if (err < 0) |
1146 | goto outfree; | 1146 | goto outfree; |
1147 | 1147 | ||
diff --git a/net/rds/ib.h b/net/rds/ib.h index 7280ab8810c2..c36d713229e0 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h | |||
@@ -316,8 +316,7 @@ int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic); | |||
316 | void rds_ib_recv_free_caches(struct rds_ib_connection *ic); | 316 | void rds_ib_recv_free_caches(struct rds_ib_connection *ic); |
317 | void rds_ib_recv_refill(struct rds_connection *conn, int prefill); | 317 | void rds_ib_recv_refill(struct rds_connection *conn, int prefill); |
318 | void rds_ib_inc_free(struct rds_incoming *inc); | 318 | void rds_ib_inc_free(struct rds_incoming *inc); |
319 | int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, | 319 | int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to); |
320 | size_t size); | ||
321 | void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context); | 320 | void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context); |
322 | void rds_ib_recv_tasklet_fn(unsigned long data); | 321 | void rds_ib_recv_tasklet_fn(unsigned long data); |
323 | void rds_ib_recv_init_ring(struct rds_ib_connection *ic); | 322 | void rds_ib_recv_init_ring(struct rds_ib_connection *ic); |
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index d67de453c35a..1b981a4e42c2 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c | |||
@@ -472,15 +472,12 @@ static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache | |||
472 | return head; | 472 | return head; |
473 | } | 473 | } |
474 | 474 | ||
475 | int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, | 475 | int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to) |
476 | size_t size) | ||
477 | { | 476 | { |
478 | struct rds_ib_incoming *ibinc; | 477 | struct rds_ib_incoming *ibinc; |
479 | struct rds_page_frag *frag; | 478 | struct rds_page_frag *frag; |
480 | struct iovec *iov = first_iov; | ||
481 | unsigned long to_copy; | 479 | unsigned long to_copy; |
482 | unsigned long frag_off = 0; | 480 | unsigned long frag_off = 0; |
483 | unsigned long iov_off = 0; | ||
484 | int copied = 0; | 481 | int copied = 0; |
485 | int ret; | 482 | int ret; |
486 | u32 len; | 483 | u32 len; |
@@ -489,37 +486,25 @@ int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, | |||
489 | frag = list_entry(ibinc->ii_frags.next, struct rds_page_frag, f_item); | 486 | frag = list_entry(ibinc->ii_frags.next, struct rds_page_frag, f_item); |
490 | len = be32_to_cpu(inc->i_hdr.h_len); | 487 | len = be32_to_cpu(inc->i_hdr.h_len); |
491 | 488 | ||
492 | while (copied < size && copied < len) { | 489 | while (iov_iter_count(to) && copied < len) { |
493 | if (frag_off == RDS_FRAG_SIZE) { | 490 | if (frag_off == RDS_FRAG_SIZE) { |
494 | frag = list_entry(frag->f_item.next, | 491 | frag = list_entry(frag->f_item.next, |
495 | struct rds_page_frag, f_item); | 492 | struct rds_page_frag, f_item); |
496 | frag_off = 0; | 493 | frag_off = 0; |
497 | } | 494 | } |
498 | while (iov_off == iov->iov_len) { | 495 | to_copy = min_t(unsigned long, iov_iter_count(to), |
499 | iov_off = 0; | 496 | RDS_FRAG_SIZE - frag_off); |
500 | iov++; | ||
501 | } | ||
502 | |||
503 | to_copy = min(iov->iov_len - iov_off, RDS_FRAG_SIZE - frag_off); | ||
504 | to_copy = min_t(size_t, to_copy, size - copied); | ||
505 | to_copy = min_t(unsigned long, to_copy, len - copied); | 497 | to_copy = min_t(unsigned long, to_copy, len - copied); |
506 | 498 | ||
507 | rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag " | ||
508 | "[%p, %u] + %lu\n", | ||
509 | to_copy, iov->iov_base, iov->iov_len, iov_off, | ||
510 | sg_page(&frag->f_sg), frag->f_sg.offset, frag_off); | ||
511 | |||
512 | /* XXX needs + offset for multiple recvs per page */ | 499 | /* XXX needs + offset for multiple recvs per page */ |
513 | ret = rds_page_copy_to_user(sg_page(&frag->f_sg), | 500 | rds_stats_add(s_copy_to_user, to_copy); |
514 | frag->f_sg.offset + frag_off, | 501 | ret = copy_page_to_iter(sg_page(&frag->f_sg), |
515 | iov->iov_base + iov_off, | 502 | frag->f_sg.offset + frag_off, |
516 | to_copy); | 503 | to_copy, |
517 | if (ret) { | 504 | to); |
518 | copied = ret; | 505 | if (ret != to_copy) |
519 | break; | 506 | return -EFAULT; |
520 | } | ||
521 | 507 | ||
522 | iov_off += to_copy; | ||
523 | frag_off += to_copy; | 508 | frag_off += to_copy; |
524 | copied += to_copy; | 509 | copied += to_copy; |
525 | } | 510 | } |
diff --git a/net/rds/iw.h b/net/rds/iw.h index 04ce3b193f79..cbe6674e31ee 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h | |||
@@ -325,8 +325,7 @@ int rds_iw_recv(struct rds_connection *conn); | |||
325 | int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, | 325 | int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, |
326 | gfp_t page_gfp, int prefill); | 326 | gfp_t page_gfp, int prefill); |
327 | void rds_iw_inc_free(struct rds_incoming *inc); | 327 | void rds_iw_inc_free(struct rds_incoming *inc); |
328 | int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, | 328 | int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to); |
329 | size_t size); | ||
330 | void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context); | 329 | void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context); |
331 | void rds_iw_recv_tasklet_fn(unsigned long data); | 330 | void rds_iw_recv_tasklet_fn(unsigned long data); |
332 | void rds_iw_recv_init_ring(struct rds_iw_connection *ic); | 331 | void rds_iw_recv_init_ring(struct rds_iw_connection *ic); |
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c index aa8bf6786008..a66d1794b2d0 100644 --- a/net/rds/iw_recv.c +++ b/net/rds/iw_recv.c | |||
@@ -303,15 +303,12 @@ void rds_iw_inc_free(struct rds_incoming *inc) | |||
303 | BUG_ON(atomic_read(&rds_iw_allocation) < 0); | 303 | BUG_ON(atomic_read(&rds_iw_allocation) < 0); |
304 | } | 304 | } |
305 | 305 | ||
306 | int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, | 306 | int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to) |
307 | size_t size) | ||
308 | { | 307 | { |
309 | struct rds_iw_incoming *iwinc; | 308 | struct rds_iw_incoming *iwinc; |
310 | struct rds_page_frag *frag; | 309 | struct rds_page_frag *frag; |
311 | struct iovec *iov = first_iov; | ||
312 | unsigned long to_copy; | 310 | unsigned long to_copy; |
313 | unsigned long frag_off = 0; | 311 | unsigned long frag_off = 0; |
314 | unsigned long iov_off = 0; | ||
315 | int copied = 0; | 312 | int copied = 0; |
316 | int ret; | 313 | int ret; |
317 | u32 len; | 314 | u32 len; |
@@ -320,37 +317,25 @@ int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, | |||
320 | frag = list_entry(iwinc->ii_frags.next, struct rds_page_frag, f_item); | 317 | frag = list_entry(iwinc->ii_frags.next, struct rds_page_frag, f_item); |
321 | len = be32_to_cpu(inc->i_hdr.h_len); | 318 | len = be32_to_cpu(inc->i_hdr.h_len); |
322 | 319 | ||
323 | while (copied < size && copied < len) { | 320 | while (iov_iter_count(to) && copied < len) { |
324 | if (frag_off == RDS_FRAG_SIZE) { | 321 | if (frag_off == RDS_FRAG_SIZE) { |
325 | frag = list_entry(frag->f_item.next, | 322 | frag = list_entry(frag->f_item.next, |
326 | struct rds_page_frag, f_item); | 323 | struct rds_page_frag, f_item); |
327 | frag_off = 0; | 324 | frag_off = 0; |
328 | } | 325 | } |
329 | while (iov_off == iov->iov_len) { | 326 | to_copy = min_t(unsigned long, iov_iter_count(to), |
330 | iov_off = 0; | 327 | RDS_FRAG_SIZE - frag_off); |
331 | iov++; | ||
332 | } | ||
333 | |||
334 | to_copy = min(iov->iov_len - iov_off, RDS_FRAG_SIZE - frag_off); | ||
335 | to_copy = min_t(size_t, to_copy, size - copied); | ||
336 | to_copy = min_t(unsigned long, to_copy, len - copied); | 328 | to_copy = min_t(unsigned long, to_copy, len - copied); |
337 | 329 | ||
338 | rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag " | ||
339 | "[%p, %lu] + %lu\n", | ||
340 | to_copy, iov->iov_base, iov->iov_len, iov_off, | ||
341 | frag->f_page, frag->f_offset, frag_off); | ||
342 | |||
343 | /* XXX needs + offset for multiple recvs per page */ | 330 | /* XXX needs + offset for multiple recvs per page */ |
344 | ret = rds_page_copy_to_user(frag->f_page, | 331 | rds_stats_add(s_copy_to_user, to_copy); |
345 | frag->f_offset + frag_off, | 332 | ret = copy_page_to_iter(frag->f_page, |
346 | iov->iov_base + iov_off, | 333 | frag->f_offset + frag_off, |
347 | to_copy); | 334 | to_copy, |
348 | if (ret) { | 335 | to); |
349 | copied = ret; | 336 | if (ret != to_copy) |
350 | break; | 337 | return -EFAULT; |
351 | } | ||
352 | 338 | ||
353 | iov_off += to_copy; | ||
354 | frag_off += to_copy; | 339 | frag_off += to_copy; |
355 | copied += to_copy; | 340 | copied += to_copy; |
356 | } | 341 | } |
diff --git a/net/rds/message.c b/net/rds/message.c index aba232f9f308..ff2202218187 100644 --- a/net/rds/message.c +++ b/net/rds/message.c | |||
@@ -264,75 +264,54 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in | |||
264 | return rm; | 264 | return rm; |
265 | } | 265 | } |
266 | 266 | ||
267 | int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, | 267 | int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from) |
268 | size_t total_len) | ||
269 | { | 268 | { |
270 | unsigned long to_copy; | 269 | unsigned long to_copy; |
271 | unsigned long iov_off; | ||
272 | unsigned long sg_off; | 270 | unsigned long sg_off; |
273 | struct iovec *iov; | ||
274 | struct scatterlist *sg; | 271 | struct scatterlist *sg; |
275 | int ret = 0; | 272 | int ret = 0; |
276 | 273 | ||
277 | rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); | 274 | rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from)); |
278 | 275 | ||
279 | /* | 276 | /* |
280 | * now allocate and copy in the data payload. | 277 | * now allocate and copy in the data payload. |
281 | */ | 278 | */ |
282 | sg = rm->data.op_sg; | 279 | sg = rm->data.op_sg; |
283 | iov = first_iov; | ||
284 | iov_off = 0; | ||
285 | sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ | 280 | sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ |
286 | 281 | ||
287 | while (total_len) { | 282 | while (iov_iter_count(from)) { |
288 | if (!sg_page(sg)) { | 283 | if (!sg_page(sg)) { |
289 | ret = rds_page_remainder_alloc(sg, total_len, | 284 | ret = rds_page_remainder_alloc(sg, iov_iter_count(from), |
290 | GFP_HIGHUSER); | 285 | GFP_HIGHUSER); |
291 | if (ret) | 286 | if (ret) |
292 | goto out; | 287 | return ret; |
293 | rm->data.op_nents++; | 288 | rm->data.op_nents++; |
294 | sg_off = 0; | 289 | sg_off = 0; |
295 | } | 290 | } |
296 | 291 | ||
297 | while (iov_off == iov->iov_len) { | 292 | to_copy = min_t(unsigned long, iov_iter_count(from), |
298 | iov_off = 0; | 293 | sg->length - sg_off); |
299 | iov++; | ||
300 | } | ||
301 | |||
302 | to_copy = min(iov->iov_len - iov_off, sg->length - sg_off); | ||
303 | to_copy = min_t(size_t, to_copy, total_len); | ||
304 | |||
305 | rdsdebug("copying %lu bytes from user iov [%p, %zu] + %lu to " | ||
306 | "sg [%p, %u, %u] + %lu\n", | ||
307 | to_copy, iov->iov_base, iov->iov_len, iov_off, | ||
308 | (void *)sg_page(sg), sg->offset, sg->length, sg_off); | ||
309 | 294 | ||
310 | ret = rds_page_copy_from_user(sg_page(sg), sg->offset + sg_off, | 295 | rds_stats_add(s_copy_from_user, to_copy); |
311 | iov->iov_base + iov_off, | 296 | ret = copy_page_from_iter(sg_page(sg), sg->offset + sg_off, |
312 | to_copy); | 297 | to_copy, from); |
313 | if (ret) | 298 | if (ret != to_copy) |
314 | goto out; | 299 | return -EFAULT; |
315 | 300 | ||
316 | iov_off += to_copy; | ||
317 | total_len -= to_copy; | ||
318 | sg_off += to_copy; | 301 | sg_off += to_copy; |
319 | 302 | ||
320 | if (sg_off == sg->length) | 303 | if (sg_off == sg->length) |
321 | sg++; | 304 | sg++; |
322 | } | 305 | } |
323 | 306 | ||
324 | out: | ||
325 | return ret; | 307 | return ret; |
326 | } | 308 | } |
327 | 309 | ||
328 | int rds_message_inc_copy_to_user(struct rds_incoming *inc, | 310 | int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to) |
329 | struct iovec *first_iov, size_t size) | ||
330 | { | 311 | { |
331 | struct rds_message *rm; | 312 | struct rds_message *rm; |
332 | struct iovec *iov; | ||
333 | struct scatterlist *sg; | 313 | struct scatterlist *sg; |
334 | unsigned long to_copy; | 314 | unsigned long to_copy; |
335 | unsigned long iov_off; | ||
336 | unsigned long vec_off; | 315 | unsigned long vec_off; |
337 | int copied; | 316 | int copied; |
338 | int ret; | 317 | int ret; |
@@ -341,36 +320,20 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc, | |||
341 | rm = container_of(inc, struct rds_message, m_inc); | 320 | rm = container_of(inc, struct rds_message, m_inc); |
342 | len = be32_to_cpu(rm->m_inc.i_hdr.h_len); | 321 | len = be32_to_cpu(rm->m_inc.i_hdr.h_len); |
343 | 322 | ||
344 | iov = first_iov; | ||
345 | iov_off = 0; | ||
346 | sg = rm->data.op_sg; | 323 | sg = rm->data.op_sg; |
347 | vec_off = 0; | 324 | vec_off = 0; |
348 | copied = 0; | 325 | copied = 0; |
349 | 326 | ||
350 | while (copied < size && copied < len) { | 327 | while (iov_iter_count(to) && copied < len) { |
351 | while (iov_off == iov->iov_len) { | 328 | to_copy = min(iov_iter_count(to), sg->length - vec_off); |
352 | iov_off = 0; | ||
353 | iov++; | ||
354 | } | ||
355 | |||
356 | to_copy = min(iov->iov_len - iov_off, sg->length - vec_off); | ||
357 | to_copy = min_t(size_t, to_copy, size - copied); | ||
358 | to_copy = min_t(unsigned long, to_copy, len - copied); | 329 | to_copy = min_t(unsigned long, to_copy, len - copied); |
359 | 330 | ||
360 | rdsdebug("copying %lu bytes to user iov [%p, %zu] + %lu to " | 331 | rds_stats_add(s_copy_to_user, to_copy); |
361 | "sg [%p, %u, %u] + %lu\n", | 332 | ret = copy_page_to_iter(sg_page(sg), sg->offset + vec_off, |
362 | to_copy, iov->iov_base, iov->iov_len, iov_off, | 333 | to_copy, to); |
363 | sg_page(sg), sg->offset, sg->length, vec_off); | 334 | if (ret != to_copy) |
364 | 335 | return -EFAULT; | |
365 | ret = rds_page_copy_to_user(sg_page(sg), sg->offset + vec_off, | ||
366 | iov->iov_base + iov_off, | ||
367 | to_copy); | ||
368 | if (ret) { | ||
369 | copied = ret; | ||
370 | break; | ||
371 | } | ||
372 | 336 | ||
373 | iov_off += to_copy; | ||
374 | vec_off += to_copy; | 337 | vec_off += to_copy; |
375 | copied += to_copy; | 338 | copied += to_copy; |
376 | 339 | ||
diff --git a/net/rds/rds.h b/net/rds/rds.h index 48f8ffc60f8f..c2a5eef41343 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h | |||
@@ -431,8 +431,7 @@ struct rds_transport { | |||
431 | int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op); | 431 | int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op); |
432 | int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op); | 432 | int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op); |
433 | int (*recv)(struct rds_connection *conn); | 433 | int (*recv)(struct rds_connection *conn); |
434 | int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov, | 434 | int (*inc_copy_to_user)(struct rds_incoming *inc, struct iov_iter *to); |
435 | size_t size); | ||
436 | void (*inc_free)(struct rds_incoming *inc); | 435 | void (*inc_free)(struct rds_incoming *inc); |
437 | 436 | ||
438 | int (*cm_handle_connect)(struct rdma_cm_id *cm_id, | 437 | int (*cm_handle_connect)(struct rdma_cm_id *cm_id, |
@@ -657,8 +656,7 @@ rds_conn_connecting(struct rds_connection *conn) | |||
657 | /* message.c */ | 656 | /* message.c */ |
658 | struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp); | 657 | struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp); |
659 | struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents); | 658 | struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents); |
660 | int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, | 659 | int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from); |
661 | size_t total_len); | ||
662 | struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len); | 660 | struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len); |
663 | void rds_message_populate_header(struct rds_header *hdr, __be16 sport, | 661 | void rds_message_populate_header(struct rds_header *hdr, __be16 sport, |
664 | __be16 dport, u64 seq); | 662 | __be16 dport, u64 seq); |
@@ -667,8 +665,7 @@ int rds_message_add_extension(struct rds_header *hdr, | |||
667 | int rds_message_next_extension(struct rds_header *hdr, | 665 | int rds_message_next_extension(struct rds_header *hdr, |
668 | unsigned int *pos, void *buf, unsigned int *buflen); | 666 | unsigned int *pos, void *buf, unsigned int *buflen); |
669 | int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset); | 667 | int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset); |
670 | int rds_message_inc_copy_to_user(struct rds_incoming *inc, | 668 | int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to); |
671 | struct iovec *first_iov, size_t size); | ||
672 | void rds_message_inc_free(struct rds_incoming *inc); | 669 | void rds_message_inc_free(struct rds_incoming *inc); |
673 | void rds_message_addref(struct rds_message *rm); | 670 | void rds_message_addref(struct rds_message *rm); |
674 | void rds_message_put(struct rds_message *rm); | 671 | void rds_message_put(struct rds_message *rm); |
diff --git a/net/rds/recv.c b/net/rds/recv.c index bd82522534fc..47d7b1029b33 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
@@ -404,6 +404,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
404 | int ret = 0, nonblock = msg_flags & MSG_DONTWAIT; | 404 | int ret = 0, nonblock = msg_flags & MSG_DONTWAIT; |
405 | DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); | 405 | DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); |
406 | struct rds_incoming *inc = NULL; | 406 | struct rds_incoming *inc = NULL; |
407 | struct iov_iter to; | ||
407 | 408 | ||
408 | /* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ | 409 | /* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ |
409 | timeo = sock_rcvtimeo(sk, nonblock); | 410 | timeo = sock_rcvtimeo(sk, nonblock); |
@@ -449,8 +450,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
449 | rdsdebug("copying inc %p from %pI4:%u to user\n", inc, | 450 | rdsdebug("copying inc %p from %pI4:%u to user\n", inc, |
450 | &inc->i_conn->c_faddr, | 451 | &inc->i_conn->c_faddr, |
451 | ntohs(inc->i_hdr.h_sport)); | 452 | ntohs(inc->i_hdr.h_sport)); |
452 | ret = inc->i_conn->c_trans->inc_copy_to_user(inc, msg->msg_iov, | 453 | iov_iter_init(&to, READ, msg->msg_iov, msg->msg_iovlen, size); |
453 | size); | 454 | ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &to); |
454 | if (ret < 0) | 455 | if (ret < 0) |
455 | break; | 456 | break; |
456 | 457 | ||
diff --git a/net/rds/send.c b/net/rds/send.c index 0a64541020b0..4de62ead1c71 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -934,7 +934,9 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
934 | int queued = 0, allocated_mr = 0; | 934 | int queued = 0, allocated_mr = 0; |
935 | int nonblock = msg->msg_flags & MSG_DONTWAIT; | 935 | int nonblock = msg->msg_flags & MSG_DONTWAIT; |
936 | long timeo = sock_sndtimeo(sk, nonblock); | 936 | long timeo = sock_sndtimeo(sk, nonblock); |
937 | struct iov_iter from; | ||
937 | 938 | ||
939 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, payload_len); | ||
938 | /* Mirror Linux UDP mirror of BSD error message compatibility */ | 940 | /* Mirror Linux UDP mirror of BSD error message compatibility */ |
939 | /* XXX: Perhaps MSG_MORE someday */ | 941 | /* XXX: Perhaps MSG_MORE someday */ |
940 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_CMSG_COMPAT)) { | 942 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_CMSG_COMPAT)) { |
@@ -982,7 +984,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
982 | ret = -ENOMEM; | 984 | ret = -ENOMEM; |
983 | goto out; | 985 | goto out; |
984 | } | 986 | } |
985 | ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len); | 987 | ret = rds_message_copy_from_user(rm, &from); |
986 | if (ret) | 988 | if (ret) |
987 | goto out; | 989 | goto out; |
988 | } | 990 | } |
diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 65637491f728..0dbdd37162da 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h | |||
@@ -69,8 +69,7 @@ void rds_tcp_recv_exit(void); | |||
69 | void rds_tcp_data_ready(struct sock *sk); | 69 | void rds_tcp_data_ready(struct sock *sk); |
70 | int rds_tcp_recv(struct rds_connection *conn); | 70 | int rds_tcp_recv(struct rds_connection *conn); |
71 | void rds_tcp_inc_free(struct rds_incoming *inc); | 71 | void rds_tcp_inc_free(struct rds_incoming *inc); |
72 | int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, | 72 | int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to); |
73 | size_t size); | ||
74 | 73 | ||
75 | /* tcp_send.c */ | 74 | /* tcp_send.c */ |
76 | void rds_tcp_xmit_prepare(struct rds_connection *conn); | 75 | void rds_tcp_xmit_prepare(struct rds_connection *conn); |
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index 9ae6e0a264ec..fbc5ef88bc0e 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c | |||
@@ -59,50 +59,30 @@ void rds_tcp_inc_free(struct rds_incoming *inc) | |||
59 | /* | 59 | /* |
60 | * this is pretty lame, but, whatever. | 60 | * this is pretty lame, but, whatever. |
61 | */ | 61 | */ |
62 | int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, | 62 | int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to) |
63 | size_t size) | ||
64 | { | 63 | { |
65 | struct rds_tcp_incoming *tinc; | 64 | struct rds_tcp_incoming *tinc; |
66 | struct iovec *iov, tmp; | ||
67 | struct sk_buff *skb; | 65 | struct sk_buff *skb; |
68 | unsigned long to_copy, skb_off; | ||
69 | int ret = 0; | 66 | int ret = 0; |
70 | 67 | ||
71 | if (size == 0) | 68 | if (!iov_iter_count(to)) |
72 | goto out; | 69 | goto out; |
73 | 70 | ||
74 | tinc = container_of(inc, struct rds_tcp_incoming, ti_inc); | 71 | tinc = container_of(inc, struct rds_tcp_incoming, ti_inc); |
75 | iov = first_iov; | ||
76 | tmp = *iov; | ||
77 | 72 | ||
78 | skb_queue_walk(&tinc->ti_skb_list, skb) { | 73 | skb_queue_walk(&tinc->ti_skb_list, skb) { |
79 | skb_off = 0; | 74 | unsigned long to_copy, skb_off; |
80 | while (skb_off < skb->len) { | 75 | for (skb_off = 0; skb_off < skb->len; skb_off += to_copy) { |
81 | while (tmp.iov_len == 0) { | 76 | to_copy = iov_iter_count(to); |
82 | iov++; | ||
83 | tmp = *iov; | ||
84 | } | ||
85 | |||
86 | to_copy = min(tmp.iov_len, size); | ||
87 | to_copy = min(to_copy, skb->len - skb_off); | 77 | to_copy = min(to_copy, skb->len - skb_off); |
88 | 78 | ||
89 | rdsdebug("ret %d size %zu skb %p skb_off %lu " | 79 | if (skb_copy_datagram_iter(skb, skb_off, to, to_copy)) |
90 | "skblen %d iov_base %p iov_len %zu cpy %lu\n", | 80 | return -EFAULT; |
91 | ret, size, skb, skb_off, skb->len, | ||
92 | tmp.iov_base, tmp.iov_len, to_copy); | ||
93 | |||
94 | /* modifies tmp as it copies */ | ||
95 | if (skb_copy_datagram_iovec(skb, skb_off, &tmp, | ||
96 | to_copy)) { | ||
97 | ret = -EFAULT; | ||
98 | goto out; | ||
99 | } | ||
100 | 81 | ||
101 | rds_stats_add(s_copy_to_user, to_copy); | 82 | rds_stats_add(s_copy_to_user, to_copy); |
102 | size -= to_copy; | ||
103 | ret += to_copy; | 83 | ret += to_copy; |
104 | skb_off += to_copy; | 84 | |
105 | if (size == 0) | 85 | if (!iov_iter_count(to)) |
106 | goto out; | 86 | goto out; |
107 | } | 87 | } |
108 | } | 88 | } |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 9b600c20a7a3..43bac7c4dd9e 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -1121,7 +1121,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1121 | skb_reset_transport_header(skb); | 1121 | skb_reset_transport_header(skb); |
1122 | skb_put(skb, len); | 1122 | skb_put(skb, len); |
1123 | 1123 | ||
1124 | err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); | 1124 | err = memcpy_from_msg(skb_transport_header(skb), msg, len); |
1125 | if (err) { | 1125 | if (err) { |
1126 | kfree_skb(skb); | 1126 | kfree_skb(skb); |
1127 | return err; | 1127 | return err; |
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 158701da2d31..a3380917f197 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
@@ -164,7 +164,7 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu | |||
164 | */ | 164 | */ |
165 | struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | 165 | struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, |
166 | struct sctp_sndrcvinfo *sinfo, | 166 | struct sctp_sndrcvinfo *sinfo, |
167 | struct msghdr *msgh, int msg_len) | 167 | struct iov_iter *from) |
168 | { | 168 | { |
169 | int max, whole, i, offset, over, err; | 169 | int max, whole, i, offset, over, err; |
170 | int len, first_len; | 170 | int len, first_len; |
@@ -172,6 +172,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
172 | struct sctp_chunk *chunk; | 172 | struct sctp_chunk *chunk; |
173 | struct sctp_datamsg *msg; | 173 | struct sctp_datamsg *msg; |
174 | struct list_head *pos, *temp; | 174 | struct list_head *pos, *temp; |
175 | size_t msg_len = iov_iter_count(from); | ||
175 | __u8 frag; | 176 | __u8 frag; |
176 | 177 | ||
177 | msg = sctp_datamsg_new(GFP_KERNEL); | 178 | msg = sctp_datamsg_new(GFP_KERNEL); |
@@ -279,12 +280,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
279 | goto errout; | 280 | goto errout; |
280 | } | 281 | } |
281 | 282 | ||
282 | err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov); | 283 | err = sctp_user_addto_chunk(chunk, len, from); |
283 | if (err < 0) | 284 | if (err < 0) |
284 | goto errout_chunk_free; | 285 | goto errout_chunk_free; |
285 | 286 | ||
286 | offset += len; | ||
287 | |||
288 | /* Put the chunk->skb back into the form expected by send. */ | 287 | /* Put the chunk->skb back into the form expected by send. */ |
289 | __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr | 288 | __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr |
290 | - (__u8 *)chunk->skb->data); | 289 | - (__u8 *)chunk->skb->data); |
@@ -317,7 +316,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
317 | goto errout; | 316 | goto errout; |
318 | } | 317 | } |
319 | 318 | ||
320 | err = sctp_user_addto_chunk(chunk, offset, over, msgh->msg_iov); | 319 | err = sctp_user_addto_chunk(chunk, over, from); |
321 | 320 | ||
322 | /* Put the chunk->skb back into the form expected by send. */ | 321 | /* Put the chunk->skb back into the form expected by send. */ |
323 | __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr | 322 | __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 9f32741abb1c..e49e231cef52 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -1001,7 +1001,7 @@ no_mem: | |||
1001 | 1001 | ||
1002 | /* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */ | 1002 | /* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */ |
1003 | struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, | 1003 | struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, |
1004 | const struct msghdr *msg, | 1004 | struct msghdr *msg, |
1005 | size_t paylen) | 1005 | size_t paylen) |
1006 | { | 1006 | { |
1007 | struct sctp_chunk *retval; | 1007 | struct sctp_chunk *retval; |
@@ -1018,7 +1018,7 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, | |||
1018 | if (!payload) | 1018 | if (!payload) |
1019 | goto err_payload; | 1019 | goto err_payload; |
1020 | 1020 | ||
1021 | err = memcpy_fromiovec(payload, msg->msg_iov, paylen); | 1021 | err = memcpy_from_msg(payload, msg, paylen); |
1022 | if (err < 0) | 1022 | if (err < 0) |
1023 | goto err_copy; | 1023 | goto err_copy; |
1024 | } | 1024 | } |
@@ -1491,26 +1491,26 @@ static void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, | |||
1491 | * chunk is not big enough. | 1491 | * chunk is not big enough. |
1492 | * Returns a kernel err value. | 1492 | * Returns a kernel err value. |
1493 | */ | 1493 | */ |
1494 | int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, | 1494 | int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len, |
1495 | struct iovec *data) | 1495 | struct iov_iter *from) |
1496 | { | 1496 | { |
1497 | __u8 *target; | 1497 | void *target; |
1498 | int err = 0; | 1498 | ssize_t copied; |
1499 | 1499 | ||
1500 | /* Make room in chunk for data. */ | 1500 | /* Make room in chunk for data. */ |
1501 | target = skb_put(chunk->skb, len); | 1501 | target = skb_put(chunk->skb, len); |
1502 | 1502 | ||
1503 | /* Copy data (whole iovec) into chunk */ | 1503 | /* Copy data (whole iovec) into chunk */ |
1504 | if ((err = memcpy_fromiovecend(target, data, off, len))) | 1504 | copied = copy_from_iter(target, len, from); |
1505 | goto out; | 1505 | if (copied != len) |
1506 | return -EFAULT; | ||
1506 | 1507 | ||
1507 | /* Adjust the chunk length field. */ | 1508 | /* Adjust the chunk length field. */ |
1508 | chunk->chunk_hdr->length = | 1509 | chunk->chunk_hdr->length = |
1509 | htons(ntohs(chunk->chunk_hdr->length) + len); | 1510 | htons(ntohs(chunk->chunk_hdr->length) + len); |
1510 | chunk->chunk_end = skb_tail_pointer(chunk->skb); | 1511 | chunk->chunk_end = skb_tail_pointer(chunk->skb); |
1511 | 1512 | ||
1512 | out: | 1513 | return 0; |
1513 | return err; | ||
1514 | } | 1514 | } |
1515 | 1515 | ||
1516 | /* Helper function to assign a TSN if needed. This assumes that both | 1516 | /* Helper function to assign a TSN if needed. This assumes that both |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 85e0b653edd7..0397ac9fd98c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1609,6 +1609,9 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1609 | __u16 sinfo_flags = 0; | 1609 | __u16 sinfo_flags = 0; |
1610 | long timeo; | 1610 | long timeo; |
1611 | int err; | 1611 | int err; |
1612 | struct iov_iter from; | ||
1613 | |||
1614 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, msg_len); | ||
1612 | 1615 | ||
1613 | err = 0; | 1616 | err = 0; |
1614 | sp = sctp_sk(sk); | 1617 | sp = sctp_sk(sk); |
@@ -1947,7 +1950,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1947 | } | 1950 | } |
1948 | 1951 | ||
1949 | /* Break the message into multiple chunks of maximum size. */ | 1952 | /* Break the message into multiple chunks of maximum size. */ |
1950 | datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len); | 1953 | datamsg = sctp_datamsg_from_user(asoc, sinfo, &from); |
1951 | if (IS_ERR(datamsg)) { | 1954 | if (IS_ERR(datamsg)) { |
1952 | err = PTR_ERR(datamsg); | 1955 | err = PTR_ERR(datamsg); |
1953 | goto out_free; | 1956 | goto out_free; |
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index ec18076e81ec..9155496b8a8a 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -162,14 +162,14 @@ err: | |||
162 | /** | 162 | /** |
163 | * tipc_msg_build - create buffer chain containing specified header and data | 163 | * tipc_msg_build - create buffer chain containing specified header and data |
164 | * @mhdr: Message header, to be prepended to data | 164 | * @mhdr: Message header, to be prepended to data |
165 | * @iov: User data | 165 | * @m: User message |
166 | * @offset: Posision in iov to start copying from | 166 | * @offset: Posision in iov to start copying from |
167 | * @dsz: Total length of user data | 167 | * @dsz: Total length of user data |
168 | * @pktmax: Max packet size that can be used | 168 | * @pktmax: Max packet size that can be used |
169 | * @chain: Buffer or chain of buffers to be returned to caller | 169 | * @chain: Buffer or chain of buffers to be returned to caller |
170 | * Returns message data size or errno: -ENOMEM, -EFAULT | 170 | * Returns message data size or errno: -ENOMEM, -EFAULT |
171 | */ | 171 | */ |
172 | int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov, | 172 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, |
173 | int offset, int dsz, int pktmax , struct sk_buff **chain) | 173 | int offset, int dsz, int pktmax , struct sk_buff **chain) |
174 | { | 174 | { |
175 | int mhsz = msg_hdr_sz(mhdr); | 175 | int mhsz = msg_hdr_sz(mhdr); |
@@ -194,7 +194,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov, | |||
194 | skb_copy_to_linear_data(buf, mhdr, mhsz); | 194 | skb_copy_to_linear_data(buf, mhdr, mhsz); |
195 | pktpos = buf->data + mhsz; | 195 | pktpos = buf->data + mhsz; |
196 | TIPC_SKB_CB(buf)->chain_sz = 1; | 196 | TIPC_SKB_CB(buf)->chain_sz = 1; |
197 | if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz)) | 197 | if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, dsz)) |
198 | return dsz; | 198 | return dsz; |
199 | rc = -EFAULT; | 199 | rc = -EFAULT; |
200 | goto error; | 200 | goto error; |
@@ -223,7 +223,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov, | |||
223 | if (drem < pktrem) | 223 | if (drem < pktrem) |
224 | pktrem = drem; | 224 | pktrem = drem; |
225 | 225 | ||
226 | if (memcpy_fromiovecend(pktpos, iov, offset, pktrem)) { | 226 | if (memcpy_fromiovecend(pktpos, m->msg_iov, offset, pktrem)) { |
227 | rc = -EFAULT; | 227 | rc = -EFAULT; |
228 | goto error; | 228 | goto error; |
229 | } | 229 | } |
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 0ea7b695ac4d..d7d2ba2afe6c 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
@@ -743,7 +743,7 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu); | |||
743 | 743 | ||
744 | bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode); | 744 | bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode); |
745 | 745 | ||
746 | int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov, | 746 | int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, |
747 | int offset, int dsz, int mtu , struct sk_buff **chain); | 747 | int offset, int dsz, int mtu , struct sk_buff **chain); |
748 | 748 | ||
749 | struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain); | 749 | struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain); |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 6aa8c6a1ab10..341fbd1b5f74 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -700,7 +700,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
700 | * tipc_sendmcast - send multicast message | 700 | * tipc_sendmcast - send multicast message |
701 | * @sock: socket structure | 701 | * @sock: socket structure |
702 | * @seq: destination address | 702 | * @seq: destination address |
703 | * @iov: message data to send | 703 | * @msg: message to send |
704 | * @dsz: total length of message data | 704 | * @dsz: total length of message data |
705 | * @timeo: timeout to wait for wakeup | 705 | * @timeo: timeout to wait for wakeup |
706 | * | 706 | * |
@@ -708,7 +708,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
708 | * Returns the number of bytes sent on success, or errno | 708 | * Returns the number of bytes sent on success, or errno |
709 | */ | 709 | */ |
710 | static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, | 710 | static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, |
711 | struct iovec *iov, size_t dsz, long timeo) | 711 | struct msghdr *msg, size_t dsz, long timeo) |
712 | { | 712 | { |
713 | struct sock *sk = sock->sk; | 713 | struct sock *sk = sock->sk; |
714 | struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; | 714 | struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; |
@@ -727,7 +727,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, | |||
727 | 727 | ||
728 | new_mtu: | 728 | new_mtu: |
729 | mtu = tipc_bclink_get_mtu(); | 729 | mtu = tipc_bclink_get_mtu(); |
730 | rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf); | 730 | rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &buf); |
731 | if (unlikely(rc < 0)) | 731 | if (unlikely(rc < 0)) |
732 | return rc; | 732 | return rc; |
733 | 733 | ||
@@ -905,7 +905,6 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
905 | struct sock *sk = sock->sk; | 905 | struct sock *sk = sock->sk; |
906 | struct tipc_sock *tsk = tipc_sk(sk); | 906 | struct tipc_sock *tsk = tipc_sk(sk); |
907 | struct tipc_msg *mhdr = &tsk->phdr; | 907 | struct tipc_msg *mhdr = &tsk->phdr; |
908 | struct iovec *iov = m->msg_iov; | ||
909 | u32 dnode, dport; | 908 | u32 dnode, dport; |
910 | struct sk_buff *buf; | 909 | struct sk_buff *buf; |
911 | struct tipc_name_seq *seq = &dest->addr.nameseq; | 910 | struct tipc_name_seq *seq = &dest->addr.nameseq; |
@@ -951,7 +950,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
951 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | 950 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); |
952 | 951 | ||
953 | if (dest->addrtype == TIPC_ADDR_MCAST) { | 952 | if (dest->addrtype == TIPC_ADDR_MCAST) { |
954 | rc = tipc_sendmcast(sock, seq, iov, dsz, timeo); | 953 | rc = tipc_sendmcast(sock, seq, m, dsz, timeo); |
955 | goto exit; | 954 | goto exit; |
956 | } else if (dest->addrtype == TIPC_ADDR_NAME) { | 955 | } else if (dest->addrtype == TIPC_ADDR_NAME) { |
957 | u32 type = dest->addr.name.name.type; | 956 | u32 type = dest->addr.name.name.type; |
@@ -982,7 +981,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
982 | 981 | ||
983 | new_mtu: | 982 | new_mtu: |
984 | mtu = tipc_node_get_mtu(dnode, tsk->ref); | 983 | mtu = tipc_node_get_mtu(dnode, tsk->ref); |
985 | rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf); | 984 | rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &buf); |
986 | if (rc < 0) | 985 | if (rc < 0) |
987 | goto exit; | 986 | goto exit; |
988 | 987 | ||
@@ -1094,7 +1093,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1094 | next: | 1093 | next: |
1095 | mtu = tsk->max_pkt; | 1094 | mtu = tsk->max_pkt; |
1096 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); | 1095 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); |
1097 | rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf); | 1096 | rc = tipc_msg_build(mhdr, m, sent, send, mtu, &buf); |
1098 | if (unlikely(rc < 0)) | 1097 | if (unlikely(rc < 0)) |
1099 | goto exit; | 1098 | goto exit; |
1100 | do { | 1099 | do { |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 5eee625d113f..4450d6226602 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1459,6 +1459,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1459 | struct scm_cookie tmp_scm; | 1459 | struct scm_cookie tmp_scm; |
1460 | int max_level; | 1460 | int max_level; |
1461 | int data_len = 0; | 1461 | int data_len = 0; |
1462 | struct iov_iter from; | ||
1463 | |||
1464 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len); | ||
1462 | 1465 | ||
1463 | if (NULL == siocb->scm) | 1466 | if (NULL == siocb->scm) |
1464 | siocb->scm = &tmp_scm; | 1467 | siocb->scm = &tmp_scm; |
@@ -1516,7 +1519,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1516 | skb_put(skb, len - data_len); | 1519 | skb_put(skb, len - data_len); |
1517 | skb->data_len = data_len; | 1520 | skb->data_len = data_len; |
1518 | skb->len = len; | 1521 | skb->len = len; |
1519 | err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov, 0, len); | 1522 | err = skb_copy_datagram_from_iter(skb, 0, &from, len); |
1520 | if (err) | 1523 | if (err) |
1521 | goto out_free; | 1524 | goto out_free; |
1522 | 1525 | ||
@@ -1638,6 +1641,9 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1638 | bool fds_sent = false; | 1641 | bool fds_sent = false; |
1639 | int max_level; | 1642 | int max_level; |
1640 | int data_len; | 1643 | int data_len; |
1644 | struct iov_iter from; | ||
1645 | |||
1646 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len); | ||
1641 | 1647 | ||
1642 | if (NULL == siocb->scm) | 1648 | if (NULL == siocb->scm) |
1643 | siocb->scm = &tmp_scm; | 1649 | siocb->scm = &tmp_scm; |
@@ -1694,8 +1700,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1694 | skb_put(skb, size - data_len); | 1700 | skb_put(skb, size - data_len); |
1695 | skb->data_len = data_len; | 1701 | skb->data_len = data_len; |
1696 | skb->len = size; | 1702 | skb->len = size; |
1697 | err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov, | 1703 | err = skb_copy_datagram_from_iter(skb, 0, &from, size); |
1698 | sent, size); | ||
1699 | if (err) { | 1704 | if (err) { |
1700 | kfree_skb(skb); | 1705 | kfree_skb(skb); |
1701 | goto out_err; | 1706 | goto out_err; |
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 85d232bed87d..1d0e39c9a3e2 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
@@ -1013,7 +1013,7 @@ static int vsock_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1013 | goto out; | 1013 | goto out; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | err = transport->dgram_enqueue(vsk, remote_addr, msg->msg_iov, len); | 1016 | err = transport->dgram_enqueue(vsk, remote_addr, msg, len); |
1017 | 1017 | ||
1018 | out: | 1018 | out: |
1019 | release_sock(sk); | 1019 | release_sock(sk); |
@@ -1617,7 +1617,7 @@ static int vsock_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1617 | */ | 1617 | */ |
1618 | 1618 | ||
1619 | written = transport->stream_enqueue( | 1619 | written = transport->stream_enqueue( |
1620 | vsk, msg->msg_iov, | 1620 | vsk, msg, |
1621 | len - total_written); | 1621 | len - total_written); |
1622 | if (written < 0) { | 1622 | if (written < 0) { |
1623 | err = -ENOMEM; | 1623 | err = -ENOMEM; |
@@ -1739,7 +1739,7 @@ vsock_stream_recvmsg(struct kiocb *kiocb, | |||
1739 | break; | 1739 | break; |
1740 | 1740 | ||
1741 | read = transport->stream_dequeue( | 1741 | read = transport->stream_dequeue( |
1742 | vsk, msg->msg_iov, | 1742 | vsk, msg, |
1743 | len - copied, flags); | 1743 | len - copied, flags); |
1744 | if (read < 0) { | 1744 | if (read < 0) { |
1745 | err = -ENOMEM; | 1745 | err = -ENOMEM; |
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index a57ddef7d5af..c1c038952973 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c | |||
@@ -1697,7 +1697,7 @@ static int vmci_transport_dgram_bind(struct vsock_sock *vsk, | |||
1697 | static int vmci_transport_dgram_enqueue( | 1697 | static int vmci_transport_dgram_enqueue( |
1698 | struct vsock_sock *vsk, | 1698 | struct vsock_sock *vsk, |
1699 | struct sockaddr_vm *remote_addr, | 1699 | struct sockaddr_vm *remote_addr, |
1700 | struct iovec *iov, | 1700 | struct msghdr *msg, |
1701 | size_t len) | 1701 | size_t len) |
1702 | { | 1702 | { |
1703 | int err; | 1703 | int err; |
@@ -1714,7 +1714,7 @@ static int vmci_transport_dgram_enqueue( | |||
1714 | if (!dg) | 1714 | if (!dg) |
1715 | return -ENOMEM; | 1715 | return -ENOMEM; |
1716 | 1716 | ||
1717 | memcpy_fromiovec(VMCI_DG_PAYLOAD(dg), iov, len); | 1717 | memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len); |
1718 | 1718 | ||
1719 | dg->dst = vmci_make_handle(remote_addr->svm_cid, | 1719 | dg->dst = vmci_make_handle(remote_addr->svm_cid, |
1720 | remote_addr->svm_port); | 1720 | remote_addr->svm_port); |
@@ -1835,22 +1835,22 @@ static int vmci_transport_connect(struct vsock_sock *vsk) | |||
1835 | 1835 | ||
1836 | static ssize_t vmci_transport_stream_dequeue( | 1836 | static ssize_t vmci_transport_stream_dequeue( |
1837 | struct vsock_sock *vsk, | 1837 | struct vsock_sock *vsk, |
1838 | struct iovec *iov, | 1838 | struct msghdr *msg, |
1839 | size_t len, | 1839 | size_t len, |
1840 | int flags) | 1840 | int flags) |
1841 | { | 1841 | { |
1842 | if (flags & MSG_PEEK) | 1842 | if (flags & MSG_PEEK) |
1843 | return vmci_qpair_peekv(vmci_trans(vsk)->qpair, iov, len, 0); | 1843 | return vmci_qpair_peekv(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0); |
1844 | else | 1844 | else |
1845 | return vmci_qpair_dequev(vmci_trans(vsk)->qpair, iov, len, 0); | 1845 | return vmci_qpair_dequev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0); |
1846 | } | 1846 | } |
1847 | 1847 | ||
1848 | static ssize_t vmci_transport_stream_enqueue( | 1848 | static ssize_t vmci_transport_stream_enqueue( |
1849 | struct vsock_sock *vsk, | 1849 | struct vsock_sock *vsk, |
1850 | struct iovec *iov, | 1850 | struct msghdr *msg, |
1851 | size_t len) | 1851 | size_t len) |
1852 | { | 1852 | { |
1853 | return vmci_qpair_enquev(vmci_trans(vsk)->qpair, iov, len, 0); | 1853 | return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0); |
1854 | } | 1854 | } |
1855 | 1855 | ||
1856 | static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk) | 1856 | static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk) |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 59e785bfde65..d9149b68b9bc 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -1170,7 +1170,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1170 | skb_reset_transport_header(skb); | 1170 | skb_reset_transport_header(skb); |
1171 | skb_put(skb, len); | 1171 | skb_put(skb, len); |
1172 | 1172 | ||
1173 | rc = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); | 1173 | rc = memcpy_from_msg(skb_transport_header(skb), msg, len); |
1174 | if (rc) | 1174 | if (rc) |
1175 | goto out_kfree_skb; | 1175 | goto out_kfree_skb; |
1176 | 1176 | ||