On Sat, 2014-11-22 at 04:33 +0000, Al Viro wrote: > allows to switch macvtap and tun from ->aio_write() to ->write_iter() > > Signed-off-by: Al Viro <[email protected]> > --- > drivers/net/macvtap.c | 43 ++++++++++++++++++++----------------------- > drivers/net/tun.c | 43 +++++++++++++++++++++++-------------------- > 2 files changed, 43 insertions(+), 43 deletions(-) > > diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c > index cdd820f..2bf08c6 100644 > --- a/drivers/net/macvtap.c > +++ b/drivers/net/macvtap.c > @@ -640,12 +640,12 @@ static void macvtap_skb_to_vnet_hdr(const struct > sk_buff *skb, > > /* Get packet from user space buffer */ > static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, > - const struct iovec *iv, unsigned long total_len, > - size_t count, int noblock) > + struct iov_iter *from, int noblock) > { > int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN); > struct sk_buff *skb; > struct macvlan_dev *vlan; > + unsigned long total_len = iov_iter_count(from); > unsigned long len = total_len; > int err; > struct virtio_net_hdr vnet_hdr = { 0 }; > @@ -653,6 +653,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, > struct msghdr *m, > int copylen = 0; > bool zerocopy = false; > size_t linear; > + ssize_t n; > > if (q->flags & IFF_VNET_HDR) { > vnet_hdr_len = q->vnet_hdr_sz; > @@ -662,10 +663,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue > *q, struct msghdr *m, > goto err; > len -= vnet_hdr_len; > > - err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, > - sizeof(vnet_hdr)); > - if (err < 0) > + err = -EFAULT; > + n = copy_from_iter(&vnet_hdr, sizeof(vnet_hdr), from); > + if (n != sizeof(vnet_hdr)) > goto err; > + iov_iter_advance(from, vnet_hdr_len - sizeof(vnet_hdr)); > if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && > vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 > > vnet_hdr.hdr_len) > @@ -680,17 +682,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue > *q, struct msghdr *m, > if (unlikely(len < ETH_HLEN)) > goto err; > > - err = -EMSGSIZE; > - if (unlikely(count > UIO_MAXIOV)) > - goto err; > - > if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) { > + struct iov_iter i;
Blank line needed after a declaration.
> copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN;
> if (copylen > good_linear)
> copylen = good_linear;
> linear = copylen;
> - if (iov_pages(iv, vnet_hdr_len + copylen, count)
> - <= MAX_SKB_FRAGS)
> + i = *from;
> + iov_iter_advance(&i, copylen);
> + if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS)
The maxpages argument should be MAX_SKB_FRAGS + 1 as we don't need the
exact number.
> zerocopy = true;
> }
>
> @@ -708,10 +708,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q,
> struct msghdr *m,
> goto err;
>
> if (zerocopy)
> - err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count);
> + err = zerocopy_sg_from_iter(skb, from);
> else {
> - err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len,
> - len);
> + err = skb_copy_datagram_from_iter(skb, 0, from, len);
Does skb_copy_datagram_from_iter() really need a len parameter? Here it
is equal to iov_iter_count(from).
[...]
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -1012,28 +1012,29 @@ static struct sk_buff *tun_alloc_skb(struct tun_file
> *tfile,
>
> /* Get packet from user space buffer */
> static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
> - void *msg_control, const struct iovec *iv,
> - size_t total_len, size_t count, int noblock)
> + void *msg_control, struct iov_iter *from,
> + int noblock)
> {
> struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
> struct sk_buff *skb;
> + size_t total_len = iov_iter_count(from);
> size_t len = total_len, align = NET_SKB_PAD, linear;
> struct virtio_net_hdr gso = { 0 };
> int good_linear;
> - int offset = 0;
> int copylen;
> bool zerocopy = false;
> int err;
> u32 rxhash;
> + ssize_t n;
>
> if (!(tun->flags & TUN_NO_PI)) {
> if (len < sizeof(pi))
> return -EINVAL;
> len -= sizeof(pi);
>
> - if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
> + n = copy_from_iter(&pi, sizeof(pi), from);
> + if (n != sizeof(pi))
> return -EFAULT;
> - offset += sizeof(pi);
> }
>
> if (tun->flags & TUN_VNET_HDR) {
> @@ -1041,7 +1042,8 @@ static ssize_t tun_get_user(struct tun_struct *tun,
> struct tun_file *tfile,
> return -EINVAL;
> len -= tun->vnet_hdr_sz;
>
> - if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
> + n = copy_from_iter(&gso, sizeof(gso), from);
> + if (n != sizeof(gso))
> return -EFAULT;
>
> if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
> @@ -1050,7 +1052,7 @@ static ssize_t tun_get_user(struct tun_struct *tun,
> struct tun_file *tfile,
>
> if (gso.hdr_len > len)
> return -EINVAL;
> - offset += tun->vnet_hdr_sz;
> + iov_iter_advance(from, tun->vnet_hdr_sz);
tun->vnet_hdr_sz - sizeof(gso)
> }
>
> if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
> @@ -1063,6 +1065,7 @@ static ssize_t tun_get_user(struct tun_struct *tun,
> struct tun_file *tfile,
> good_linear = SKB_MAX_HEAD(align);
>
> if (msg_control) {
> + struct iov_iter i = *from;
Blank line needed after a declaration.
> /* There are 256 bytes to be copied in skb, so there is
> * enough room for skb expand head in case it is used.
> * The rest of the buffer is mapped from userspace.
> @@ -1071,7 +1074,8 @@ static ssize_t tun_get_user(struct tun_struct *tun,
> struct tun_file *tfile,
> if (copylen > good_linear)
> copylen = good_linear;
> linear = copylen;
> - if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS)
> + iov_iter_advance(&i, copylen);
> + if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS)
Again, the maxpages argument should be MAX_SKB_FRAGS + 1.
> zerocopy = true;
> }
>
> @@ -1091,9 +1095,9 @@ static ssize_t tun_get_user(struct tun_struct *tun,
> struct tun_file *tfile,
> }
>
> if (zerocopy)
> - err = zerocopy_sg_from_iovec(skb, iv, offset, count);
> + err = zerocopy_sg_from_iter(skb, from);
> else {
> - err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len);
> + err = skb_copy_datagram_from_iter(skb, 0, from, len);
[...]
Again len is equal to iov_iter_count(from), so I think that parameter is
redundant.
Ben.
--
Ben Hutchings
Absolutum obsoletum. (If it works, it's out of date.) - Stafford Beer
signature.asc
Description: This is a digitally signed message part

