switch AF_PACKET and AF_UNIX to skb_copy_datagram_from_iter()
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 6 Nov 2014 06:10:59 +0000 (01:10 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 24 Nov 2014 10:16:39 +0000 (05:16 -0500)
... and kill skb_copy_datagram_iovec()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
include/linux/skbuff.h
net/core/datagram.c
net/packet/af_packet.c
net/unix/af_unix.c

index 178cdbd..7691ad5 100644 (file)
@@ -2656,9 +2656,6 @@ static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen,
 {
        return skb_copy_and_csum_datagram_iovec(skb, hlen, msg->msg_iov);
 }
-int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
-                                const struct iovec *from, int from_offset,
-                                int len);
 int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
                                 struct iov_iter *from, int len);
 int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
index c4d832e..b6e303b 100644 (file)
@@ -480,98 +480,14 @@ short_copy:
 EXPORT_SYMBOL(skb_copy_datagram_iter);
 
 /**
- *     skb_copy_datagram_from_iovec - Copy a datagram from an iovec.
+ *     skb_copy_datagram_from_iter - Copy a datagram from an iov_iter.
  *     @skb: buffer to copy
  *     @offset: offset in the buffer to start copying to
- *     @from: io vector to copy to
- *     @from_offset: offset in the io vector to start copying from
+ *     @from: the copy source
  *     @len: amount of data to copy to buffer from iovec
  *
  *     Returns 0 or -EFAULT.
- *     Note: the iovec is not modified during the copy.
  */
-int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
-                                const struct iovec *from, int from_offset,
-                                int len)
-{
-       int start = skb_headlen(skb);
-       int i, copy = start - offset;
-       struct sk_buff *frag_iter;
-
-       /* Copy header. */
-       if (copy > 0) {
-               if (copy > len)
-                       copy = len;
-               if (memcpy_fromiovecend(skb->data + offset, from, from_offset,
-                                       copy))
-                       goto fault;
-               if ((len -= copy) == 0)
-                       return 0;
-               offset += copy;
-               from_offset += copy;
-       }
-
-       /* Copy paged appendix. Hmm... why does this look so complicated? */
-       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-               int end;
-               const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-
-               WARN_ON(start > offset + len);
-
-               end = start + skb_frag_size(frag);
-               if ((copy = end - offset) > 0) {
-                       int err;
-                       u8  *vaddr;
-                       struct page *page = skb_frag_page(frag);
-
-                       if (copy > len)
-                               copy = len;
-                       vaddr = kmap(page);
-                       err = memcpy_fromiovecend(vaddr + frag->page_offset +
-                                                 offset - start,
-                                                 from, from_offset, copy);
-                       kunmap(page);
-                       if (err)
-                               goto fault;
-
-                       if (!(len -= copy))
-                               return 0;
-                       offset += copy;
-                       from_offset += copy;
-               }
-               start = end;
-       }
-
-       skb_walk_frags(skb, frag_iter) {
-               int end;
-
-               WARN_ON(start > offset + len);
-
-               end = start + frag_iter->len;
-               if ((copy = end - offset) > 0) {
-                       if (copy > len)
-                               copy = len;
-                       if (skb_copy_datagram_from_iovec(frag_iter,
-                                                        offset - start,
-                                                        from,
-                                                        from_offset,
-                                                        copy))
-                               goto fault;
-                       if ((len -= copy) == 0)
-                               return 0;
-                       offset += copy;
-                       from_offset += copy;
-               }
-               start = end;
-       }
-       if (!len)
-               return 0;
-
-fault:
-       return -EFAULT;
-}
-EXPORT_SYMBOL(skb_copy_datagram_from_iovec);
-
 int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
                                 struct iov_iter *from,
                                 int len)
index 108d7f3..dfb148e 100644 (file)
@@ -2408,6 +2408,10 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
        unsigned short gso_type = 0;
        int hlen, tlen;
        int extra_len = 0;
+       struct iov_iter from;
+       ssize_t n;
+
+       iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
 
        /*
         *      Get and verify the address.
@@ -2446,8 +2450,9 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
 
                len -= vnet_hdr_len;
 
-               err = memcpy_from_msg((void *)&vnet_hdr, msg, vnet_hdr_len);
-               if (err < 0)
+               err = -EFAULT;
+               n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from);
+               if (n != vnet_hdr_len)
                        goto out_unlock;
 
                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)
        }
 
        /* Returns -EFAULT on error */
-       err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len);
+       err = skb_copy_datagram_from_iter(skb, offset, &from, len);
        if (err)
                goto out_free;
 
index 5eee625..4450d62 100644 (file)
@@ -1459,6 +1459,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct scm_cookie tmp_scm;
        int max_level;
        int data_len = 0;
+       struct iov_iter from;
+
+       iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
 
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
@@ -1516,7 +1519,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        skb_put(skb, len - data_len);
        skb->data_len = data_len;
        skb->len = len;
-       err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov, 0, len);
+       err = skb_copy_datagram_from_iter(skb, 0, &from, len);
        if (err)
                goto out_free;
 
@@ -1638,6 +1641,9 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        bool fds_sent = false;
        int max_level;
        int data_len;
+       struct iov_iter from;
+
+       iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
 
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
@@ -1694,8 +1700,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                skb_put(skb, size - data_len);
                skb->data_len = data_len;
                skb->len = size;
-               err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov,
-                                                  sent, size);
+               err = skb_copy_datagram_from_iter(skb, 0, &from, size);
                if (err) {
                        kfree_skb(skb);
                        goto out_err;