Skip to content

Commit

Permalink
Merge branch 'for-davem-2' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/viro/vfs

More iov_iter work for the networking from Al Viro.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
davem330 committed Dec 10, 2014
2 parents 6c702fa + 218321e commit 6e5f59a
Show file tree
Hide file tree
Showing 48 changed files with 628 additions and 1,038 deletions.
4 changes: 2 additions & 2 deletions crypto/algif_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static int hash_sendmsg(struct kiocb *unused, struct socket *sock,
struct alg_sock *ask = alg_sk(sk);
struct hash_ctx *ctx = ask->private;
unsigned long iovlen;
struct iovec *iov;
const struct iovec *iov;
long copied = 0;
int err;

Expand All @@ -58,7 +58,7 @@ static int hash_sendmsg(struct kiocb *unused, struct socket *sock,

ctx->more = 0;

for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
for (iov = msg->msg_iter.iov, iovlen = msg->msg_iter.nr_segs; iovlen > 0;
iovlen--, iov++) {
unsigned long seglen = iov->iov_len;
char __user *from = iov->iov_base;
Expand Down
4 changes: 2 additions & 2 deletions crypto/algif_skcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,13 +429,13 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
struct skcipher_sg_list *sgl;
struct scatterlist *sg;
unsigned long iovlen;
struct iovec *iov;
const struct iovec *iov;
int err = -EAGAIN;
int used;
long copied = 0;

lock_sock(sk);
for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
for (iov = msg->msg_iter.iov, iovlen = msg->msg_iter.nr_segs; iovlen > 0;
iovlen--, iov++) {
unsigned long seglen = iov->iov_len;
char __user *from = iov->iov_base;
Expand Down
17 changes: 9 additions & 8 deletions drivers/misc/vmw_vmci/vmci_queue_pair.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/uio.h>
#include <linux/wait.h>
#include <linux/vmalloc.h>
#include <linux/skbuff.h>

#include "vmci_handle_array.h"
#include "vmci_queue_pair.h"
Expand Down Expand Up @@ -429,11 +430,11 @@ static int __qp_memcpy_from_queue(void *dest,
to_copy = size - bytes_copied;

if (is_iovec) {
struct iovec *iov = (struct iovec *)dest;
struct msghdr *msg = dest;
int err;

/* The iovec will track bytes_copied internally. */
err = memcpy_toiovec(iov, (u8 *)va + page_offset,
err = memcpy_to_msg(msg, (u8 *)va + page_offset,
to_copy);
if (err != 0) {
if (kernel_if->host)
Expand Down Expand Up @@ -3264,13 +3265,13 @@ EXPORT_SYMBOL_GPL(vmci_qpair_enquev);
* of bytes dequeued or < 0 on error.
*/
ssize_t vmci_qpair_dequev(struct vmci_qp *qpair,
void *iov,
struct msghdr *msg,
size_t iov_size,
int buf_type)
{
ssize_t result;

if (!qpair || !iov)
if (!qpair)
return VMCI_ERROR_INVALID_ARGS;

qp_lock(qpair);
Expand All @@ -3279,7 +3280,7 @@ ssize_t vmci_qpair_dequev(struct vmci_qp *qpair,
result = qp_dequeue_locked(qpair->produce_q,
qpair->consume_q,
qpair->consume_q_size,
iov, iov_size,
msg, iov_size,
qp_memcpy_from_queue_iov,
true);

Expand Down Expand Up @@ -3308,13 +3309,13 @@ EXPORT_SYMBOL_GPL(vmci_qpair_dequev);
* of bytes peeked or < 0 on error.
*/
ssize_t vmci_qpair_peekv(struct vmci_qp *qpair,
void *iov,
struct msghdr *msg,
size_t iov_size,
int buf_type)
{
ssize_t result;

if (!qpair || !iov)
if (!qpair)
return VMCI_ERROR_INVALID_ARGS;

qp_lock(qpair);
Expand All @@ -3323,7 +3324,7 @@ ssize_t vmci_qpair_peekv(struct vmci_qp *qpair,
result = qp_dequeue_locked(qpair->produce_q,
qpair->consume_q,
qpair->consume_q_size,
iov, iov_size,
msg, iov_size,
qp_memcpy_from_queue_iov,
false);

Expand Down
8 changes: 2 additions & 6 deletions drivers/net/macvtap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1095,22 +1095,18 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len)
{
struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
struct iov_iter from;
iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len);
return macvtap_get_user(q, m, &from, m->msg_flags & MSG_DONTWAIT);
return macvtap_get_user(q, m, &m->msg_iter, m->msg_flags & MSG_DONTWAIT);
}

static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len,
int flags)
{
struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
struct iov_iter to;
int ret;
if (flags & ~(MSG_DONTWAIT|MSG_TRUNC))
return -EINVAL;
iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len);
ret = macvtap_do_read(q, &to, flags & MSG_DONTWAIT);
ret = macvtap_do_read(q, &m->msg_iter, flags & MSG_DONTWAIT);
if (ret > total_len) {
m->msg_flags |= MSG_TRUNC;
ret = flags & MSG_TRUNC ? ret : total_len;
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/ppp/ppp_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
ssize_t ret;
struct sk_buff *skb = NULL;
struct iovec iov;
struct iov_iter to;

ret = count;

Expand Down Expand Up @@ -462,7 +463,8 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
ret = -EFAULT;
iov.iov_base = buf;
iov.iov_len = count;
if (skb_copy_datagram_iovec(skb, 0, &iov, skb->len))
iov_iter_init(&to, READ, &iov, 1, count);
if (skb_copy_datagram_iter(skb, 0, &to, skb->len))
goto outf;
ret = skb->len;

Expand Down
8 changes: 2 additions & 6 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -1449,13 +1449,11 @@ static int tun_sendmsg(struct kiocb *iocb, struct socket *sock,
int ret;
struct tun_file *tfile = container_of(sock, struct tun_file, socket);
struct tun_struct *tun = __tun_get(tfile);
struct iov_iter from;

if (!tun)
return -EBADFD;

iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len);
ret = tun_get_user(tun, tfile, m->msg_control, &from,
ret = tun_get_user(tun, tfile, m->msg_control, &m->msg_iter,
m->msg_flags & MSG_DONTWAIT);
tun_put(tun);
return ret;
Expand All @@ -1467,7 +1465,6 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
{
struct tun_file *tfile = container_of(sock, struct tun_file, socket);
struct tun_struct *tun = __tun_get(tfile);
struct iov_iter to;
int ret;

if (!tun)
Expand All @@ -1482,8 +1479,7 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
SOL_PACKET, TUN_TX_TIMESTAMP);
goto out;
}
iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len);
ret = tun_do_read(tun, tfile, &to, flags & MSG_DONTWAIT);
ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT);
if (ret > total_len) {
m->msg_flags |= MSG_TRUNC;
ret = flags & MSG_TRUNC ? ret : total_len;
Expand Down
12 changes: 5 additions & 7 deletions drivers/target/iscsi/iscsi_target_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1326,21 +1326,19 @@ static int iscsit_do_rx_data(
struct iscsi_conn *conn,
struct iscsi_data_count *count)
{
int data = count->data_length, rx_loop = 0, total_rx = 0, iov_len;
struct kvec *iov_p;
int data = count->data_length, rx_loop = 0, total_rx = 0;
struct msghdr msg;

if (!conn || !conn->sock || !conn->conn_ops)
return -1;

memset(&msg, 0, sizeof(struct msghdr));

iov_p = count->iov;
iov_len = count->iov_count;
iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC,
count->iov, count->iov_count, data);

while (total_rx < data) {
rx_loop = kernel_recvmsg(conn->sock, &msg, iov_p, iov_len,
(data - total_rx), MSG_WAITALL);
rx_loop = sock_recvmsg(conn->sock, &msg,
(data - total_rx), MSG_WAITALL);
if (rx_loop <= 0) {
pr_debug("rx_loop: %d total_rx: %d\n",
rx_loop, total_rx);
Expand Down
8 changes: 3 additions & 5 deletions drivers/vhost/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@ static void handle_tx(struct vhost_net *net)
.msg_namelen = 0,
.msg_control = NULL,
.msg_controllen = 0,
.msg_iov = vq->iov,
.msg_flags = MSG_DONTWAIT,
};
size_t len, total_len = 0;
Expand Down Expand Up @@ -396,8 +395,8 @@ static void handle_tx(struct vhost_net *net)
}
/* Skip header. TODO: support TSO. */
s = move_iovec_hdr(vq->iov, nvq->hdr, hdr_size, out);
msg.msg_iovlen = out;
len = iov_length(vq->iov, out);
iov_iter_init(&msg.msg_iter, WRITE, vq->iov, out, len);
/* Sanity check */
if (!len) {
vq_err(vq, "Unexpected header len for TX: "
Expand Down Expand Up @@ -562,7 +561,6 @@ static void handle_rx(struct vhost_net *net)
.msg_namelen = 0,
.msg_control = NULL, /* FIXME: get and handle RX aux data. */
.msg_controllen = 0,
.msg_iov = vq->iov,
.msg_flags = MSG_DONTWAIT,
};
struct virtio_net_hdr_mrg_rxbuf hdr = {
Expand Down Expand Up @@ -600,7 +598,7 @@ static void handle_rx(struct vhost_net *net)
break;
/* On overrun, truncate and discard */
if (unlikely(headcount > UIO_MAXIOV)) {
msg.msg_iovlen = 1;
iov_iter_init(&msg.msg_iter, READ, vq->iov, 1, 1);
err = sock->ops->recvmsg(NULL, sock, &msg,
1, MSG_DONTWAIT | MSG_TRUNC);
pr_debug("Discarded rx packet: len %zd\n", sock_len);
Expand All @@ -626,7 +624,7 @@ static void handle_rx(struct vhost_net *net)
/* Copy the header for use in VIRTIO_NET_F_MRG_RXBUF:
* needed because recvmsg can modify msg_iov. */
copy_iovec_hdr(vq->iov, nvq->hdr, sock_hlen, in);
msg.msg_iovlen = in;
iov_iter_init(&msg.msg_iter, READ, vq->iov, in, sock_len);
err = sock->ops->recvmsg(NULL, sock, &msg,
sock_len, MSG_DONTWAIT | MSG_TRUNC);
/* Userspace might have consumed the packet meanwhile:
Expand Down
14 changes: 6 additions & 8 deletions fs/afs/rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ static int afs_send_pages(struct afs_call *call, struct msghdr *msg,

_debug("- range %u-%u%s",
offset, to, msg->msg_flags ? " [more]" : "");
msg->msg_iov = (struct iovec *) iov;
msg->msg_iovlen = 1;
iov_iter_init(&msg->msg_iter, WRITE,
(struct iovec *) iov, 1, to - offset);

/* have to change the state *before* sending the last
* packet as RxRPC might give us the reply before it
Expand Down Expand Up @@ -384,8 +384,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,

msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = (struct iovec *) iov;
msg.msg_iovlen = 1;
iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *)iov, 1,
call->request_size);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = (call->send_pages ? MSG_MORE : 0);
Expand Down Expand Up @@ -778,8 +778,7 @@ void afs_send_empty_reply(struct afs_call *call)
iov[0].iov_len = 0;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = 0;
iov_iter_init(&msg.msg_iter, WRITE, iov, 0, 0); /* WTF? */
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
Expand Down Expand Up @@ -815,8 +814,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)
iov[0].iov_len = len;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov_iter_init(&msg.msg_iter, WRITE, iov, 1, len);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
Expand Down
22 changes: 8 additions & 14 deletions include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -2644,24 +2644,17 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock,
int *err);
unsigned int datagram_poll(struct file *file, struct socket *sock,
struct poll_table_struct *wait);
int skb_copy_datagram_iovec(const struct sk_buff *from, int offset,
struct iovec *to, int size);
int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
struct iov_iter *to, int size);
static inline int skb_copy_datagram_msg(const struct sk_buff *from, int offset,
struct msghdr *msg, int size)
{
return skb_copy_datagram_iovec(from, offset, msg->msg_iov, size);
}
int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen,
struct iovec *iov);
static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen,
struct msghdr *msg)
{
return skb_copy_and_csum_datagram_iovec(skb, hlen, msg->msg_iov);
return skb_copy_datagram_iter(from, offset, &msg->msg_iter, size);
}
int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen,
struct msghdr *msg);
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,
struct iov_iter *to, int size);
int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *frm);
void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb);
Expand Down Expand Up @@ -2689,12 +2682,13 @@ int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci);

static inline int memcpy_from_msg(void *data, struct msghdr *msg, int len)
{
return memcpy_fromiovec(data, msg->msg_iov, len);
/* XXX: stripping const */
return memcpy_fromiovec(data, (struct iovec *)msg->msg_iter.iov, len);
}

static inline int memcpy_to_msg(struct msghdr *msg, void *data, int len)
{
return memcpy_toiovec(msg->msg_iov, data, len);
return copy_to_iter(data, len, &msg->msg_iter) == len ? 0 : -EFAULT;
}

struct skb_checksum_ops {
Expand Down
3 changes: 1 addition & 2 deletions include/linux/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ struct linger {
struct msghdr {
void *msg_name; /* ptr to socket address structure */
int msg_namelen; /* size of socket address structure */
struct iovec *msg_iov; /* scatter/gather array */
__kernel_size_t msg_iovlen; /* # elements in msg_iov */
struct iov_iter msg_iter; /* data */
void *msg_control; /* ancillary data */
__kernel_size_t msg_controllen; /* ancillary data buffer length */
unsigned int msg_flags; /* flags on received message */
Expand Down
2 changes: 1 addition & 1 deletion include/linux/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ struct tcp_sock {
struct {
struct sk_buff_head prequeue;
struct task_struct *task;
struct iovec *iov;
struct msghdr *msg;
int memory;
int len;
} ucopy;
Expand Down
7 changes: 6 additions & 1 deletion include/linux/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct iov_iter {
size_t count;
union {
const struct iovec *iov;
const struct kvec *kvec;
const struct bio_vec *bvec;
};
unsigned long nr_segs;
Expand Down Expand Up @@ -82,10 +83,13 @@ size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes,
struct iov_iter *i);
size_t copy_to_iter(void *addr, size_t bytes, struct iov_iter *i);
size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i);
size_t copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i);
size_t iov_iter_zero(size_t bytes, struct iov_iter *);
unsigned long iov_iter_alignment(const struct iov_iter *i);
void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov,
unsigned long nr_segs, size_t count);
void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *iov,
unsigned long nr_segs, size_t count);
ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
size_t maxsize, unsigned maxpages, size_t *start);
ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages,
Expand Down Expand Up @@ -123,9 +127,10 @@ static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
{
i->count = count;
}
size_t csum_and_copy_to_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);

int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len);
int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
int offset, int len);
int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
Expand Down
Loading

0 comments on commit 6e5f59a

Please sign in to comment.