]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/core/datagram.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[mirror_ubuntu-artful-kernel.git] / net / core / datagram.c
index 4608aa245410ccdbcb3510c8e8c6dec2beac8a8d..15ef99469cfe2b86032abfbbbcaf51b96a229044 100644 (file)
@@ -402,7 +402,7 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
                           struct iov_iter *to, int len)
 {
        int start = skb_headlen(skb);
-       int i, copy = start - offset;
+       int i, copy = start - offset, start_off = offset, n;
        struct sk_buff *frag_iter;
 
        trace_skb_copy_datagram_iovec(skb, len);
@@ -411,11 +411,12 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
        if (copy > 0) {
                if (copy > len)
                        copy = len;
-               if (copy_to_iter(skb->data + offset, copy, to) != copy)
+               n = copy_to_iter(skb->data + offset, copy, to);
+               offset += n;
+               if (n != copy)
                        goto short_copy;
                if ((len -= copy) == 0)
                        return 0;
-               offset += copy;
        }
 
        /* Copy paged appendix. Hmm... why does this look so complicated? */
@@ -429,13 +430,14 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
                if ((copy = end - offset) > 0) {
                        if (copy > len)
                                copy = len;
-                       if (copy_page_to_iter(skb_frag_page(frag),
+                       n = copy_page_to_iter(skb_frag_page(frag),
                                              frag->page_offset + offset -
-                                             start, copy, to) != copy)
+                                             start, copy, to);
+                       offset += n;
+                       if (n != copy)
                                goto short_copy;
                        if (!(len -= copy))
                                return 0;
-                       offset += copy;
                }
                start = end;
        }
@@ -467,6 +469,7 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
         */
 
 fault:
+       iov_iter_revert(to, offset - start_off);
        return -EFAULT;
 
 short_copy:
@@ -617,7 +620,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
                                      __wsum *csump)
 {
        int start = skb_headlen(skb);
-       int i, copy = start - offset;
+       int i, copy = start - offset, start_off = offset;
        struct sk_buff *frag_iter;
        int pos = 0;
        int n;
@@ -627,11 +630,11 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
                if (copy > len)
                        copy = len;
                n = csum_and_copy_to_iter(skb->data + offset, copy, csump, to);
+               offset += n;
                if (n != copy)
                        goto fault;
                if ((len -= copy) == 0)
                        return 0;
-               offset += copy;
                pos = copy;
        }
 
@@ -653,12 +656,12 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
                                                  offset - start, copy,
                                                  &csum2, to);
                        kunmap(page);
+                       offset += n;
                        if (n != copy)
                                goto fault;
                        *csump = csum_block_add(*csump, csum2, pos);
                        if (!(len -= copy))
                                return 0;
-                       offset += copy;
                        pos += copy;
                }
                start = end;
@@ -691,6 +694,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
                return 0;
 
 fault:
+       iov_iter_revert(to, offset - start_off);
        return -EFAULT;
 }
 
@@ -775,6 +779,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb,
        }
        return 0;
 csum_error:
+       iov_iter_revert(&msg->msg_iter, chunk);
        return -EINVAL;
 fault:
        return -EFAULT;