net: use skb_copy_datagram_from_iovec() in zerocopy_sg_from_iovec()
authorJason Wang <jasowang@redhat.com>
Tue, 6 Aug 2013 09:45:08 +0000 (17:45 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 7 Aug 2013 23:52:38 +0000 (16:52 -0700)
Use skb_copy_datagram_from_iovec() to avoid code duplication and make it easy to
be read. Also we can do the skipping inside the zero-copy loop.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/datagram.c

index badcd93..af814e7 100644 (file)
@@ -591,48 +591,31 @@ int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
                                  int offset, size_t count)
 {
        int len = iov_length(from, count) - offset;
-       int copy = skb_headlen(skb);
-       int size, offset1 = 0;
+       int copy = min_t(int, skb_headlen(skb), len);
+       int size;
        int i = 0;
 
-       /* Skip over from offset */
-       while (count && (offset >= from->iov_len)) {
-               offset -= from->iov_len;
-               ++from;
-               --count;
-       }
-
        /* copy up to skb headlen */
-       while (count && (copy > 0)) {
-               size = min_t(unsigned int, copy, from->iov_len - offset);
-               if (copy_from_user(skb->data + offset1, from->iov_base + offset,
-                                  size))
-                       return -EFAULT;
-               if (copy > size) {
-                       ++from;
-                       --count;
-                       offset = 0;
-               } else
-                       offset += size;
-               copy -= size;
-               offset1 += size;
-       }
+       if (skb_copy_datagram_from_iovec(skb, 0, from, offset, copy))
+               return -EFAULT;
 
-       if (len == offset1)
+       if (len == copy)
                return 0;
 
+       offset += copy;
        while (count--) {
                struct page *page[MAX_SKB_FRAGS];
                int num_pages;
                unsigned long base;
                unsigned long truesize;
 
-               len = from->iov_len - offset;
-               if (!len) {
-                       offset = 0;
+               /* Skip over from offset and copied */
+               if (offset >= from->iov_len) {
+                       offset -= from->iov_len;
                        ++from;
                        continue;
                }
+               len = from->iov_len - offset;
                base = (unsigned long)from->iov_base + offset;
                size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
                if (i + size > MAX_SKB_FRAGS)