aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/macvtap.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2014-11-07 08:22:25 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-07 12:13:34 -0500
commit6c36d2e26cda1ad3e2c4b90dd843825fc62fe5b4 (patch)
tree1d98b6d2753df810746d49d0a62dfbb547087cb6 /drivers/net/macvtap.c
parente0b46d0ee9c240c7430a47e9b0365674d4a04522 (diff)
macvtap: Use iovec iterators
This patch removes the use of skb_copy_datagram_const_iovec in favour of the iovec iterator-based skb_copy_datagram_iter. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/macvtap.c')
-rw-r--r--drivers/net/macvtap.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 880cc090dc44..cea99d4a8263 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -15,6 +15,7 @@
15#include <linux/cdev.h> 15#include <linux/cdev.h>
16#include <linux/idr.h> 16#include <linux/idr.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/uio.h>
18 19
19#include <net/ipv6.h> 20#include <net/ipv6.h>
20#include <net/net_namespace.h> 21#include <net/net_namespace.h>
@@ -778,31 +779,29 @@ static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv,
778/* Put packet to the user space buffer */ 779/* Put packet to the user space buffer */
779static ssize_t macvtap_put_user(struct macvtap_queue *q, 780static ssize_t macvtap_put_user(struct macvtap_queue *q,
780 const struct sk_buff *skb, 781 const struct sk_buff *skb,
781 const struct iovec *iv, int len) 782 struct iov_iter *iter)
782{ 783{
783 int ret; 784 int ret;
784 int vnet_hdr_len = 0; 785 int vnet_hdr_len = 0;
785 int vlan_offset = 0; 786 int vlan_offset = 0;
786 int copied, total; 787 int total;
787 788
788 if (q->flags & IFF_VNET_HDR) { 789 if (q->flags & IFF_VNET_HDR) {
789 struct virtio_net_hdr vnet_hdr; 790 struct virtio_net_hdr vnet_hdr;
790 vnet_hdr_len = q->vnet_hdr_sz; 791 vnet_hdr_len = q->vnet_hdr_sz;
791 if ((len -= vnet_hdr_len) < 0) 792 if (iov_iter_count(iter) < vnet_hdr_len)
792 return -EINVAL; 793 return -EINVAL;
793 794
794 macvtap_skb_to_vnet_hdr(skb, &vnet_hdr); 795 macvtap_skb_to_vnet_hdr(skb, &vnet_hdr);
795 796
796 if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) 797 if (copy_to_iter(&vnet_hdr, sizeof(vnet_hdr), iter) !=
798 sizeof(vnet_hdr))
797 return -EFAULT; 799 return -EFAULT;
798 } 800 }
799 total = copied = vnet_hdr_len; 801 total = vnet_hdr_len;
800 total += skb->len; 802 total += skb->len;
801 803
802 if (!vlan_tx_tag_present(skb)) 804 if (vlan_tx_tag_present(skb)) {
803 len = min_t(int, skb->len, len);
804 else {
805 int copy;
806 struct { 805 struct {
807 __be16 h_vlan_proto; 806 __be16 h_vlan_proto;
808 __be16 h_vlan_TCI; 807 __be16 h_vlan_TCI;
@@ -811,37 +810,33 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
811 veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); 810 veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb));
812 811
813 vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); 812 vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
814 len = min_t(int, skb->len + VLAN_HLEN, len);
815 total += VLAN_HLEN; 813 total += VLAN_HLEN;
816 814
817 copy = min_t(int, vlan_offset, len); 815 ret = skb_copy_datagram_iter(skb, 0, iter, vlan_offset);
818 ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); 816 if (ret || !iov_iter_count(iter))
819 len -= copy;
820 copied += copy;
821 if (ret || !len)
822 goto done; 817 goto done;
823 818
824 copy = min_t(int, sizeof(veth), len); 819 ret = copy_to_iter(&veth, sizeof(veth), iter);
825 ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); 820 if (ret != sizeof(veth) || !iov_iter_count(iter))
826 len -= copy;
827 copied += copy;
828 if (ret || !len)
829 goto done; 821 goto done;
830 } 822 }
831 823
832 ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); 824 ret = skb_copy_datagram_iter(skb, vlan_offset, iter,
825 skb->len - vlan_offset);
833 826
834done: 827done:
835 return ret ? ret : total; 828 return ret ? ret : total;
836} 829}
837 830
838static ssize_t macvtap_do_read(struct macvtap_queue *q, 831static ssize_t macvtap_do_read(struct macvtap_queue *q,
839 const struct iovec *iv, unsigned long len, 832 const struct iovec *iv, unsigned long segs,
833 unsigned long len,
840 int noblock) 834 int noblock)
841{ 835{
842 DEFINE_WAIT(wait); 836 DEFINE_WAIT(wait);
843 struct sk_buff *skb; 837 struct sk_buff *skb;
844 ssize_t ret = 0; 838 ssize_t ret = 0;
839 struct iov_iter iter;
845 840
846 while (len) { 841 while (len) {
847 if (!noblock) 842 if (!noblock)
@@ -863,7 +858,8 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q,
863 schedule(); 858 schedule();
864 continue; 859 continue;
865 } 860 }
866 ret = macvtap_put_user(q, skb, iv, len); 861 iov_iter_init(&iter, READ, iv, segs, len);
862 ret = macvtap_put_user(q, skb, &iter);
867 kfree_skb(skb); 863 kfree_skb(skb);
868 break; 864 break;
869 } 865 }
@@ -886,7 +882,7 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv,
886 goto out; 882 goto out;
887 } 883 }
888 884
889 ret = macvtap_do_read(q, iv, len, file->f_flags & O_NONBLOCK); 885 ret = macvtap_do_read(q, iv, count, len, file->f_flags & O_NONBLOCK);
890 ret = min_t(ssize_t, ret, len); 886 ret = min_t(ssize_t, ret, len);
891 if (ret > 0) 887 if (ret > 0)
892 iocb->ki_pos = ret; 888 iocb->ki_pos = ret;
@@ -1117,7 +1113,7 @@ static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock,
1117 int ret; 1113 int ret;
1118 if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) 1114 if (flags & ~(MSG_DONTWAIT|MSG_TRUNC))
1119 return -EINVAL; 1115 return -EINVAL;
1120 ret = macvtap_do_read(q, m->msg_iov, total_len, 1116 ret = macvtap_do_read(q, m->msg_iov, m->msg_iovlen, total_len,
1121 flags & MSG_DONTWAIT); 1117 flags & MSG_DONTWAIT);
1122 if (ret > total_len) { 1118 if (ret > total_len) {
1123 m->msg_flags |= MSG_TRUNC; 1119 m->msg_flags |= MSG_TRUNC;