diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2014-11-07 08:22:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-07 12:13:34 -0500 |
commit | 6c36d2e26cda1ad3e2c4b90dd843825fc62fe5b4 (patch) | |
tree | 1d98b6d2753df810746d49d0a62dfbb547087cb6 /drivers/net/macvtap.c | |
parent | e0b46d0ee9c240c7430a47e9b0365674d4a04522 (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.c | 46 |
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 */ |
779 | static ssize_t macvtap_put_user(struct macvtap_queue *q, | 780 | static 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 | ||
834 | done: | 827 | done: |
835 | return ret ? ret : total; | 828 | return ret ? ret : total; |
836 | } | 829 | } |
837 | 830 | ||
838 | static ssize_t macvtap_do_read(struct macvtap_queue *q, | 831 | static 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; |