diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-11-06 01:10:59 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-11-24 05:16:39 -0500 |
commit | 8feb2fb2bb986c533e18037d3c45a5f779421992 (patch) | |
tree | 7c10e24137e82d54aaa533aeadc21a2d2dae922c | |
parent | 195e952d03a797aa953f62ffe24ec58693e17ed8 (diff) |
switch AF_PACKET and AF_UNIX to skb_copy_datagram_from_iter()
... and kill skb_copy_datagram_iovec()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | include/linux/skbuff.h | 3 | ||||
-rw-r--r-- | net/core/datagram.c | 88 | ||||
-rw-r--r-- | net/packet/af_packet.c | 11 | ||||
-rw-r--r-- | net/unix/af_unix.c | 11 |
4 files changed, 18 insertions, 95 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 178cdbde82f0..7691ad5b4771 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -2656,9 +2656,6 @@ static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen, | |||
2656 | { | 2656 | { |
2657 | return skb_copy_and_csum_datagram_iovec(skb, hlen, msg->msg_iov); | 2657 | return skb_copy_and_csum_datagram_iovec(skb, hlen, msg->msg_iov); |
2658 | } | 2658 | } |
2659 | int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | ||
2660 | const struct iovec *from, int from_offset, | ||
2661 | int len); | ||
2662 | int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, | 2659 | int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, |
2663 | struct iov_iter *from, int len); | 2660 | struct iov_iter *from, int len); |
2664 | 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, |
diff --git a/net/core/datagram.c b/net/core/datagram.c index c4d832efebb8..b6e303b0f01f 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -480,98 +480,14 @@ 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, | ||
494 | const struct iovec *from, int from_offset, | ||
495 | int len) | ||
496 | { | ||
497 | int start = skb_headlen(skb); | ||
498 | int i, copy = start - offset; | ||
499 | struct sk_buff *frag_iter; | ||
500 | |||
501 | /* Copy header. */ | ||
502 | if (copy > 0) { | ||
503 | if (copy > len) | ||
504 | copy = len; | ||
505 | if (memcpy_fromiovecend(skb->data + offset, from, from_offset, | ||
506 | copy)) | ||
507 | goto fault; | ||
508 | if ((len -= copy) == 0) | ||
509 | return 0; | ||
510 | offset += copy; | ||
511 | from_offset += copy; | ||
512 | } | ||
513 | |||
514 | /* Copy paged appendix. Hmm... why does this look so complicated? */ | ||
515 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | ||
516 | int end; | ||
517 | const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | ||
518 | |||
519 | WARN_ON(start > offset + len); | ||
520 | |||
521 | end = start + skb_frag_size(frag); | ||
522 | if ((copy = end - offset) > 0) { | ||
523 | int err; | ||
524 | u8 *vaddr; | ||
525 | struct page *page = skb_frag_page(frag); | ||
526 | |||
527 | if (copy > len) | ||
528 | copy = len; | ||
529 | vaddr = kmap(page); | ||
530 | err = memcpy_fromiovecend(vaddr + frag->page_offset + | ||
531 | offset - start, | ||
532 | from, from_offset, copy); | ||
533 | kunmap(page); | ||
534 | if (err) | ||
535 | goto fault; | ||
536 | |||
537 | if (!(len -= copy)) | ||
538 | return 0; | ||
539 | offset += copy; | ||
540 | from_offset += copy; | ||
541 | } | ||
542 | start = end; | ||
543 | } | ||
544 | |||
545 | skb_walk_frags(skb, frag_iter) { | ||
546 | int end; | ||
547 | |||
548 | WARN_ON(start > offset + len); | ||
549 | |||
550 | end = start + frag_iter->len; | ||
551 | if ((copy = end - offset) > 0) { | ||
552 | if (copy > len) | ||
553 | copy = len; | ||
554 | if (skb_copy_datagram_from_iovec(frag_iter, | ||
555 | offset - start, | ||
556 | from, | ||
557 | from_offset, | ||
558 | copy)) | ||
559 | goto fault; | ||
560 | if ((len -= copy) == 0) | ||
561 | return 0; | ||
562 | offset += copy; | ||
563 | from_offset += copy; | ||
564 | } | ||
565 | start = end; | ||
566 | } | ||
567 | if (!len) | ||
568 | return 0; | ||
569 | |||
570 | fault: | ||
571 | return -EFAULT; | ||
572 | } | ||
573 | EXPORT_SYMBOL(skb_copy_datagram_from_iovec); | ||
574 | |||
575 | int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, | 491 | int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, |
576 | struct iov_iter *from, | 492 | struct iov_iter *from, |
577 | int len) | 493 | int len) |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 108d7f381b87..dfb148e9fdaa 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -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,8 +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_from_msg((void *)&vnet_hdr, msg, vnet_hdr_len); | 2453 | err = -EFAULT; |
2450 | if (err < 0) | 2454 | n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from); |
2455 | if (n != vnet_hdr_len) | ||
2451 | goto out_unlock; | 2456 | goto out_unlock; |
2452 | 2457 | ||
2453 | if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && | 2458 | if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && |
@@ -2517,7 +2522,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2517 | } | 2522 | } |
2518 | 2523 | ||
2519 | /* Returns -EFAULT on error */ | 2524 | /* Returns -EFAULT on error */ |
2520 | err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len); | 2525 | err = skb_copy_datagram_from_iter(skb, offset, &from, len); |
2521 | if (err) | 2526 | if (err) |
2522 | goto out_free; | 2527 | goto out_free; |
2523 | 2528 | ||
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; |