switch AF_PACKET and AF_UNIX to skb_copy_datagram_from_iter()
... and kill skb_copy_datagram_iovec() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
195e952d03
commit
8feb2fb2bb
|
@ -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);
|
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,
|
int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
|
||||||
struct iov_iter *from, int len);
|
struct iov_iter *from, int len);
|
||||||
int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
|
int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
|
||||||
|
|
|
@ -480,98 +480,14 @@ short_copy:
|
||||||
EXPORT_SYMBOL(skb_copy_datagram_iter);
|
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
|
* @skb: buffer to copy
|
||||||
* @offset: offset in the buffer to start copying to
|
* @offset: offset in the buffer to start copying to
|
||||||
* @from: io vector to copy to
|
* @from: the copy source
|
||||||
* @from_offset: offset in the io vector to start copying from
|
|
||||||
* @len: amount of data to copy to buffer from iovec
|
* @len: amount of data to copy to buffer from iovec
|
||||||
*
|
*
|
||||||
* Returns 0 or -EFAULT.
|
* 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,
|
int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
|
||||||
struct iov_iter *from,
|
struct iov_iter *from,
|
||||||
int len)
|
int len)
|
||||||
|
|
|
@ -2408,6 +2408,10 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
|
||||||
unsigned short gso_type = 0;
|
unsigned short gso_type = 0;
|
||||||
int hlen, tlen;
|
int hlen, tlen;
|
||||||
int extra_len = 0;
|
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.
|
* 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;
|
len -= vnet_hdr_len;
|
||||||
|
|
||||||
err = memcpy_from_msg((void *)&vnet_hdr, msg, vnet_hdr_len);
|
err = -EFAULT;
|
||||||
if (err < 0)
|
n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from);
|
||||||
|
if (n != vnet_hdr_len)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
|
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 */
|
/* 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)
|
if (err)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
|
|
@ -1459,6 +1459,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||||
struct scm_cookie tmp_scm;
|
struct scm_cookie tmp_scm;
|
||||||
int max_level;
|
int max_level;
|
||||||
int data_len = 0;
|
int data_len = 0;
|
||||||
|
struct iov_iter from;
|
||||||
|
|
||||||
|
iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
|
||||||
|
|
||||||
if (NULL == siocb->scm)
|
if (NULL == siocb->scm)
|
||||||
siocb->scm = &tmp_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_put(skb, len - data_len);
|
||||||
skb->data_len = data_len;
|
skb->data_len = data_len;
|
||||||
skb->len = 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)
|
if (err)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
@ -1638,6 +1641,9 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||||
bool fds_sent = false;
|
bool fds_sent = false;
|
||||||
int max_level;
|
int max_level;
|
||||||
int data_len;
|
int data_len;
|
||||||
|
struct iov_iter from;
|
||||||
|
|
||||||
|
iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
|
||||||
|
|
||||||
if (NULL == siocb->scm)
|
if (NULL == siocb->scm)
|
||||||
siocb->scm = &tmp_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_put(skb, size - data_len);
|
||||||
skb->data_len = data_len;
|
skb->data_len = data_len;
|
||||||
skb->len = size;
|
skb->len = size;
|
||||||
err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov,
|
err = skb_copy_datagram_from_iter(skb, 0, &from, size);
|
||||||
sent, size);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
Loading…
Reference in New Issue