|
@@ -615,27 +615,25 @@ int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from)
|
|
|
EXPORT_SYMBOL(zerocopy_sg_from_iter);
|
|
|
|
|
|
static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
|
|
|
- u8 __user *to, int len,
|
|
|
+ struct iov_iter *to, int len,
|
|
|
__wsum *csump)
|
|
|
{
|
|
|
int start = skb_headlen(skb);
|
|
|
int i, copy = start - offset;
|
|
|
struct sk_buff *frag_iter;
|
|
|
int pos = 0;
|
|
|
+ int n;
|
|
|
|
|
|
/* Copy header. */
|
|
|
if (copy > 0) {
|
|
|
- int err = 0;
|
|
|
if (copy > len)
|
|
|
copy = len;
|
|
|
- *csump = csum_and_copy_to_user(skb->data + offset, to, copy,
|
|
|
- *csump, &err);
|
|
|
- if (err)
|
|
|
+ n = csum_and_copy_to_iter(skb->data + offset, copy, csump, to);
|
|
|
+ if (n != copy)
|
|
|
goto fault;
|
|
|
if ((len -= copy) == 0)
|
|
|
return 0;
|
|
|
offset += copy;
|
|
|
- to += copy;
|
|
|
pos = copy;
|
|
|
}
|
|
|
|
|
@@ -647,26 +645,22 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
|
|
|
|
|
|
end = start + skb_frag_size(frag);
|
|
|
if ((copy = end - offset) > 0) {
|
|
|
- __wsum csum2;
|
|
|
- int err = 0;
|
|
|
- u8 *vaddr;
|
|
|
+ __wsum csum2 = 0;
|
|
|
struct page *page = skb_frag_page(frag);
|
|
|
+ u8 *vaddr = kmap(page);
|
|
|
|
|
|
if (copy > len)
|
|
|
copy = len;
|
|
|
- vaddr = kmap(page);
|
|
|
- csum2 = csum_and_copy_to_user(vaddr +
|
|
|
- frag->page_offset +
|
|
|
- offset - start,
|
|
|
- to, copy, 0, &err);
|
|
|
+ n = csum_and_copy_to_iter(vaddr + frag->page_offset +
|
|
|
+ offset - start, copy,
|
|
|
+ &csum2, to);
|
|
|
kunmap(page);
|
|
|
- if (err)
|
|
|
+ if (n != copy)
|
|
|
goto fault;
|
|
|
*csump = csum_block_add(*csump, csum2, pos);
|
|
|
if (!(len -= copy))
|
|
|
return 0;
|
|
|
offset += copy;
|
|
|
- to += copy;
|
|
|
pos += copy;
|
|
|
}
|
|
|
start = end;
|
|
@@ -691,7 +685,6 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
|
|
|
if ((len -= copy) == 0)
|
|
|
return 0;
|
|
|
offset += copy;
|
|
|
- to += copy;
|
|
|
pos += copy;
|
|
|
}
|
|
|
start = end;
|
|
@@ -744,20 +737,19 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb)
|
|
|
EXPORT_SYMBOL(__skb_checksum_complete);
|
|
|
|
|
|
/**
|
|
|
- * skb_copy_and_csum_datagram_iovec - Copy and checksum skb to user iovec.
|
|
|
+ * skb_copy_and_csum_datagram_msg - Copy and checksum skb to user iovec.
|
|
|
* @skb: skbuff
|
|
|
* @hlen: hardware length
|
|
|
- * @iov: io vector
|
|
|
+ * @msg: destination
|
|
|
*
|
|
|
* Caller _must_ check that skb will fit to this iovec.
|
|
|
*
|
|
|
* Returns: 0 - success.
|
|
|
* -EINVAL - checksum failure.
|
|
|
- * -EFAULT - fault during copy. Beware, in this case iovec
|
|
|
- * can be modified!
|
|
|
+ * -EFAULT - fault during copy.
|
|
|
*/
|
|
|
-int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
|
|
|
- int hlen, struct iovec *iov)
|
|
|
+int skb_copy_and_csum_datagram_msg(struct sk_buff *skb,
|
|
|
+ int hlen, struct msghdr *msg)
|
|
|
{
|
|
|
__wsum csum;
|
|
|
int chunk = skb->len - hlen;
|
|
@@ -765,28 +757,20 @@ int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
|
|
|
if (!chunk)
|
|
|
return 0;
|
|
|
|
|
|
- /* Skip filled elements.
|
|
|
- * Pretty silly, look at memcpy_toiovec, though 8)
|
|
|
- */
|
|
|
- while (!iov->iov_len)
|
|
|
- iov++;
|
|
|
-
|
|
|
- if (iov->iov_len < chunk) {
|
|
|
+ if (iov_iter_count(&msg->msg_iter) < chunk) {
|
|
|
if (__skb_checksum_complete(skb))
|
|
|
goto csum_error;
|
|
|
- if (skb_copy_datagram_iovec(skb, hlen, iov, chunk))
|
|
|
+ if (skb_copy_datagram_msg(skb, hlen, msg, chunk))
|
|
|
goto fault;
|
|
|
} else {
|
|
|
csum = csum_partial(skb->data, hlen, skb->csum);
|
|
|
- if (skb_copy_and_csum_datagram(skb, hlen, iov->iov_base,
|
|
|
+ if (skb_copy_and_csum_datagram(skb, hlen, &msg->msg_iter,
|
|
|
chunk, &csum))
|
|
|
goto fault;
|
|
|
if (csum_fold(csum))
|
|
|
goto csum_error;
|
|
|
if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE))
|
|
|
netdev_rx_csum_fault(skb->dev);
|
|
|
- iov->iov_len -= chunk;
|
|
|
- iov->iov_base += chunk;
|
|
|
}
|
|
|
return 0;
|
|
|
csum_error:
|
|
@@ -794,7 +778,7 @@ csum_error:
|
|
|
fault:
|
|
|
return -EFAULT;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec);
|
|
|
+EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg);
|
|
|
|
|
|
/**
|
|
|
* datagram_poll - generic datagram poll
|