aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-11-06 01:10:59 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-11-24 05:16:39 -0500
commit8feb2fb2bb986c533e18037d3c45a5f779421992 (patch)
tree7c10e24137e82d54aaa533aeadc21a2d2dae922c
parent195e952d03a797aa953f62ffe24ec58693e17ed8 (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.h3
-rw-r--r--net/core/datagram.c88
-rw-r--r--net/packet/af_packet.c11
-rw-r--r--net/unix/af_unix.c11
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}
2659int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
2660 const struct iovec *from, int from_offset,
2661 int len);
2662int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, 2659int 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);
2664int skb_copy_datagram_iter(const struct sk_buff *from, int offset, 2661int 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:
480EXPORT_SYMBOL(skb_copy_datagram_iter); 480EXPORT_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 */
493int 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
570fault:
571 return -EFAULT;
572}
573EXPORT_SYMBOL(skb_copy_datagram_from_iovec);
574
575int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, 491int 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;