diff options
Diffstat (limited to 'drivers/net/macvtap.c')
-rw-r--r-- | drivers/net/macvtap.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 9093004f9b63..2a89da080317 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -770,7 +770,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
770 | int ret; | 770 | int ret; |
771 | int vnet_hdr_len = 0; | 771 | int vnet_hdr_len = 0; |
772 | int vlan_offset = 0; | 772 | int vlan_offset = 0; |
773 | int copied; | 773 | int copied, total; |
774 | 774 | ||
775 | if (q->flags & IFF_VNET_HDR) { | 775 | if (q->flags & IFF_VNET_HDR) { |
776 | struct virtio_net_hdr vnet_hdr; | 776 | struct virtio_net_hdr vnet_hdr; |
@@ -785,7 +785,8 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
785 | if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) | 785 | if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) |
786 | return -EFAULT; | 786 | return -EFAULT; |
787 | } | 787 | } |
788 | copied = vnet_hdr_len; | 788 | total = copied = vnet_hdr_len; |
789 | total += skb->len; | ||
789 | 790 | ||
790 | if (!vlan_tx_tag_present(skb)) | 791 | if (!vlan_tx_tag_present(skb)) |
791 | len = min_t(int, skb->len, len); | 792 | len = min_t(int, skb->len, len); |
@@ -800,6 +801,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
800 | 801 | ||
801 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); | 802 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); |
802 | len = min_t(int, skb->len + VLAN_HLEN, len); | 803 | len = min_t(int, skb->len + VLAN_HLEN, len); |
804 | total += VLAN_HLEN; | ||
803 | 805 | ||
804 | copy = min_t(int, vlan_offset, len); | 806 | copy = min_t(int, vlan_offset, len); |
805 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); | 807 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); |
@@ -817,10 +819,9 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
817 | } | 819 | } |
818 | 820 | ||
819 | ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); | 821 | ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); |
820 | copied += len; | ||
821 | 822 | ||
822 | done: | 823 | done: |
823 | return ret ? ret : copied; | 824 | return ret ? ret : total; |
824 | } | 825 | } |
825 | 826 | ||
826 | static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, | 827 | static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, |
@@ -875,7 +876,9 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, | |||
875 | } | 876 | } |
876 | 877 | ||
877 | ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK); | 878 | ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK); |
878 | ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */ | 879 | ret = min_t(ssize_t, ret, len); |
880 | if (ret > 0) | ||
881 | iocb->ki_pos = ret; | ||
879 | out: | 882 | out: |
880 | return ret; | 883 | return ret; |
881 | } | 884 | } |