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 /net | |
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>
Diffstat (limited to 'net')
57 files changed, 222 insertions, 343 deletions
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 | ||