put iov_iter into msghdr
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 24 Nov 2014 15:42:55 +0000 (10:42 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 9 Dec 2014 21:29:03 +0000 (16:29 -0500)
Note that the code _using_ ->msg_iter at that point will be very
unhappy with anything other than unshifted iovec-backed iov_iter.
We still need to convert users to proper primitives.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
33 files changed:
crypto/algif_hash.c
crypto/algif_skcipher.c
drivers/net/macvtap.c
drivers/net/tun.c
drivers/vhost/net.c
fs/afs/rxrpc.c
include/linux/skbuff.h
include/linux/socket.h
include/net/bluetooth/l2cap.h
include/net/udplite.h
net/atm/common.c
net/bluetooth/6lowpan.c
net/bluetooth/a2mp.c
net/bluetooth/smp.c
net/caif/caif_socket.c
net/compat.c
net/ipv4/ip_output.c
net/ipv4/ping.c
net/ipv4/raw.c
net/ipv4/tcp.c
net/ipv4/tcp_output.c
net/ipv6/ping.c
net/ipv6/raw.c
net/netlink/af_netlink.c
net/packet/af_packet.c
net/rds/recv.c
net/rds/send.c
net/rxrpc/ar-output.c
net/sctp/socket.c
net/socket.c
net/tipc/msg.c
net/unix/af_unix.c
net/vmw_vsock/vmci_transport.c

index 35c93ff..83cd2cc 100644 (file)
@@ -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;
 
@@ -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;
index c3b482b..4f45dab 100644 (file)
@@ -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;
index ba1e5db..2c157cc 100644 (file)
@@ -1095,9 +1095,7 @@ 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,
@@ -1105,12 +1103,10 @@ static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock,
                           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;
index 9c58286..f3e992e 100644 (file)
@@ -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;
@@ -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)
@@ -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;
index 8dae2f7..9f06e70 100644 (file)
@@ -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;
@@ -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: "
@@ -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 = {
@@ -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);
@@ -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:
index 03a3beb..06e14bf 100644 (file)
@@ -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
@@ -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);
@@ -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;
@@ -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;
index ef64cec..52cf1bd 100644 (file)
@@ -2646,22 +2646,24 @@ 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);
+       /* XXX: stripping const */
+       return skb_copy_datagram_iovec(from, offset, (struct iovec *)msg->msg_iter.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);
+       /* XXX: stripping const */
+       return skb_copy_and_csum_datagram_iovec(skb, hlen, (struct iovec *)msg->msg_iter.iov);
 }
 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);
@@ -2689,12 +2691,14 @@ 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);
+       /* XXX: stripping const */
+       return memcpy_toiovec((struct iovec *)msg->msg_iter.iov, data, len);
 }
 
 struct skb_checksum_ops {
index de52228..048d6d6 100644 (file)
@@ -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 */
index 4e23674..bca6fc0 100644 (file)
@@ -911,7 +911,7 @@ static inline int l2cap_chan_no_memcpy_fromiovec(struct l2cap_chan *chan,
        /* Following is safe since for compiler definitions of kvec and
         * iovec are identical, yielding the same in-core layout and alignment
         */
-       struct kvec *vec = (struct kvec *)msg->msg_iov;
+       struct kvec *vec = (struct kvec *)msg->msg_iter.iov;
 
        while (len > 0) {
                if (vec->iov_len) {
index d5baaba..ae7c8d1 100644 (file)
@@ -20,7 +20,8 @@ static __inline__ int udplite_getfrag(void *from, char *to, int  offset,
                                      int len, int odd, struct sk_buff *skb)
 {
        struct msghdr *msg = from;
-       return memcpy_fromiovecend(to, msg->msg_iov, offset, len);
+       /* XXX: stripping const */
+       return memcpy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len);
 }
 
 /* Designate sk as UDP-Lite socket */
index f591129..b84057e 100644 (file)
@@ -577,9 +577,6 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
        struct atm_vcc *vcc;
        struct sk_buff *skb;
        int eff, error;
-       struct iov_iter from;
-
-       iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, size);
 
        lock_sock(sk);
        if (sock->state != SS_CONNECTED) {
@@ -634,7 +631,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
                goto out;
        skb->dev = NULL; /* for paths shared with net_device interfaces */
        ATM_SKB(skb)->atm_options = vcc->atm_options;
-       if (copy_from_iter(skb_put(skb, size), size, &from) != size) {
+       if (copy_from_iter(skb_put(skb, size), size, &m->msg_iter) != size) {
                kfree_skb(skb);
                error = -EFAULT;
                goto out;
index bdcaefd..d8c67a5 100644 (file)
@@ -537,12 +537,12 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb,
         */
        chan->data = skb;
 
-       memset(&msg, 0, sizeof(msg));
-       msg.msg_iov = (struct iovec *) &iv;
-       msg.msg_iovlen = 1;
        iv.iov_base = skb->data;
        iv.iov_len = skb->len;
 
+       memset(&msg, 0, sizeof(msg));
+       iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *) &iv, 1, skb->len);
+
        err = l2cap_chan_send(chan, &msg, skb->len);
        if (err > 0) {
                netdev->stats.tx_bytes += err;
index 5dcade5..716d2a3 100644 (file)
@@ -60,8 +60,7 @@ void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data)
 
        memset(&msg, 0, sizeof(msg));
 
-       msg.msg_iov = (struct iovec *) &iv;
-       msg.msg_iovlen = 1;
+       iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *)&iv, 1, total_len);
 
        l2cap_chan_send(chan, &msg, total_len);
 
index 069b76e..21f555b 100644 (file)
@@ -268,8 +268,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
 
        memset(&msg, 0, sizeof(msg));
 
-       msg.msg_iov = (struct iovec *) &iv;
-       msg.msg_iovlen = 2;
+       iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *)iv, 2, 1 + len);
 
        l2cap_chan_send(chan, &msg, 1 + len);
 
index ac618b0..769b185 100644 (file)
@@ -535,7 +535,7 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock,
                goto err;
 
        ret = -EINVAL;
-       if (unlikely(msg->msg_iov->iov_base == NULL))
+       if (unlikely(msg->msg_iter.iov->iov_base == NULL))
                goto err;
        noblock = msg->msg_flags & MSG_DONTWAIT;
 
index 062f157..3236b41 100644 (file)
@@ -37,13 +37,14 @@ ssize_t get_compat_msghdr(struct msghdr *kmsg,
                          struct iovec **iov)
 {
        compat_uptr_t uaddr, uiov, tmp3;
+       compat_size_t nr_segs;
        ssize_t err;
 
        if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
            __get_user(uaddr, &umsg->msg_name) ||
            __get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
            __get_user(uiov, &umsg->msg_iov) ||
-           __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) ||
+           __get_user(nr_segs, &umsg->msg_iovlen) ||
            __get_user(tmp3, &umsg->msg_control) ||
            __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
            __get_user(kmsg->msg_flags, &umsg->msg_flags))
@@ -68,14 +69,15 @@ ssize_t get_compat_msghdr(struct msghdr *kmsg,
                kmsg->msg_namelen = 0;
        }
 
-       if (kmsg->msg_iovlen > UIO_MAXIOV)
+       if (nr_segs > UIO_MAXIOV)
                return -EMSGSIZE;
 
        err = compat_rw_copy_check_uvector(save_addr ? READ : WRITE,
-                                          compat_ptr(uiov), kmsg->msg_iovlen,
+                                          compat_ptr(uiov), nr_segs,
                                           UIO_FASTIOV, *iov, iov);
        if (err >= 0)
-               kmsg->msg_iov = *iov;
+               iov_iter_init(&kmsg->msg_iter, save_addr ? READ : WRITE,
+                             *iov, nr_segs, err);
        return err;
 }
 
index cdedcf1..b50861b 100644 (file)
@@ -755,11 +755,13 @@ ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk
        struct msghdr *msg = from;
 
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
-               if (memcpy_fromiovecend(to, msg->msg_iov, offset, len) < 0)
+               /* XXX: stripping const */
+               if (memcpy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len) < 0)
                        return -EFAULT;
        } else {
                __wsum csum = 0;
-               if (csum_partial_copy_fromiovecend(to, msg->msg_iov, offset, len, &csum) < 0)
+               /* XXX: stripping const */
+               if (csum_partial_copy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len, &csum) < 0)
                        return -EFAULT;
                skb->csum = csum_block_add(skb->csum, csum, odd);
        }
index 8dd4ae0..c0d82f7 100644 (file)
@@ -811,7 +811,8 @@ back_from_confirm:
        pfh.icmph.checksum = 0;
        pfh.icmph.un.echo.id = inet->inet_sport;
        pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
-       pfh.iov = msg->msg_iov;
+       /* XXX: stripping const */
+       pfh.iov = (struct iovec *)msg->msg_iter.iov;
        pfh.wcheck = 0;
        pfh.family = AF_INET;
 
index 5d83bd2..0bb68df 100644 (file)
@@ -625,7 +625,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 back_from_confirm:
 
        if (inet->hdrincl)
-               err = raw_send_hdrinc(sk, &fl4, msg->msg_iov, len,
+               /* XXX: stripping const */
+               err = raw_send_hdrinc(sk, &fl4, (struct iovec *)msg->msg_iter.iov, len,
                                      &rt, msg->msg_flags);
 
         else {
index 4a96f37..54ba620 100644 (file)
@@ -1085,7 +1085,7 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
 int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                size_t size)
 {
-       struct iovec *iov;
+       const struct iovec *iov;
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *skb;
        int iovlen, flags, err, copied = 0;
@@ -1136,8 +1136,8 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        mss_now = tcp_send_mss(sk, &size_goal, flags);
 
        /* Ok commence sending. */
-       iovlen = msg->msg_iovlen;
-       iov = msg->msg_iov;
+       iovlen = msg->msg_iter.nr_segs;
+       iov = msg->msg_iter.iov;
        copied = 0;
 
        err = -EPIPE;
index f5bd4bd..3e225b0 100644 (file)
@@ -3050,7 +3050,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
        syn_data->ip_summed = CHECKSUM_PARTIAL;
        memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
        if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space),
-                                        fo->data->msg_iov, 0, space))) {
+                                        fo->data->msg_iter.iov, 0, space))) {
                kfree_skb(syn_data);
                goto fallback;
        }
index 5b7a1ed..2d31483 100644 (file)
@@ -163,7 +163,8 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        pfh.icmph.checksum = 0;
        pfh.icmph.un.echo.id = inet->inet_sport;
        pfh.icmph.un.echo.sequence = user_icmph.icmp6_sequence;
-       pfh.iov = msg->msg_iov;
+       /* XXX: stripping const */
+       pfh.iov = (struct iovec *)msg->msg_iter.iov;
        pfh.wcheck = 0;
        pfh.family = AF_INET6;
 
index 11a9283..ee25631 100644 (file)
@@ -886,7 +886,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 
 back_from_confirm:
        if (inet->hdrincl)
-               err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl6, &dst, msg->msg_flags);
+               /* XXX: stripping const */
+               err = rawv6_send_hdrinc(sk, (struct iovec *)msg->msg_iter.iov, len, &fl6, &dst, msg->msg_flags);
        else {
                lock_sock(sk);
                err = ip6_append_data(sk, raw6_getfrag, &rfv,
index 63aa5c8..cc9bcf0 100644 (file)
@@ -2305,7 +2305,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
        }
 
        if (netlink_tx_is_mmaped(sk) &&
-           msg->msg_iov->iov_base == NULL) {
+           msg->msg_iter.iov->iov_base == NULL) {
                err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group,
                                           siocb);
                goto out;
index efa8445..ed2e620 100644 (file)
@@ -2408,11 +2408,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
        unsigned short gso_type = 0;
        int hlen, tlen;
        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.
         */
@@ -2451,7 +2448,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
                len -= vnet_hdr_len;
 
                err = -EFAULT;
-               n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from);
+               n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &msg->msg_iter);
                if (n != vnet_hdr_len)
                        goto out_unlock;
 
@@ -2522,7 +2519,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
        }
 
        /* Returns -EFAULT on error */
-       err = skb_copy_datagram_from_iter(skb, offset, &from, len);
+       err = skb_copy_datagram_from_iter(skb, offset, &msg->msg_iter, len);
        if (err)
                goto out_free;
 
index 47d7b10..f9ec1ac 100644 (file)
@@ -404,7 +404,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
        int ret = 0, nonblock = msg_flags & MSG_DONTWAIT;
        DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
        struct rds_incoming *inc = NULL;
-       struct iov_iter to;
 
        /* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */
        timeo = sock_rcvtimeo(sk, nonblock);
@@ -415,6 +414,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
                goto out;
 
        while (1) {
+               struct iov_iter save;
                /* If there are pending notifications, do those - and nothing else */
                if (!list_empty(&rs->rs_notify_queue)) {
                        ret = rds_notify_queue_get(rs, msg);
@@ -450,8 +450,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
                rdsdebug("copying inc %p from %pI4:%u to user\n", inc,
                         &inc->i_conn->c_faddr,
                         ntohs(inc->i_hdr.h_sport));
-               iov_iter_init(&to, READ, msg->msg_iov, msg->msg_iovlen, size);
-               ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &to);
+               save = msg->msg_iter;
+               ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &msg->msg_iter);
                if (ret < 0)
                        break;
 
@@ -464,6 +464,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
                        rds_inc_put(inc);
                        inc = NULL;
                        rds_stats_inc(s_recv_deliver_raced);
+                       msg->msg_iter = save;
                        continue;
                }
 
index 4de62ea..40a5629 100644 (file)
@@ -934,9 +934,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
        int queued = 0, allocated_mr = 0;
        int nonblock = msg->msg_flags & MSG_DONTWAIT;
        long timeo = sock_sndtimeo(sk, nonblock);
-       struct iov_iter from;
 
-       iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, payload_len);
        /* Mirror Linux UDP mirror of BSD error message compatibility */
        /* XXX: Perhaps MSG_MORE someday */
        if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_CMSG_COMPAT)) {
@@ -984,7 +982,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
                        ret = -ENOMEM;
                        goto out;
                }
-               ret = rds_message_copy_from_user(rm, &from);
+               ret = rds_message_copy_from_user(rm, &msg->msg_iter);
                if (ret)
                        goto out;
        }
index 0b4b9a7..86e0f10 100644 (file)
@@ -531,14 +531,12 @@ static int rxrpc_send_data(struct kiocb *iocb,
        struct rxrpc_skb_priv *sp;
        unsigned char __user *from;
        struct sk_buff *skb;
-       struct iovec *iov;
+       const struct iovec *iov;
        struct sock *sk = &rx->sk;
        long timeo;
        bool more;
        int ret, ioc, segment, copied;
 
-       _enter(",,,{%zu},%zu", msg->msg_iovlen, len);
-
        timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
 
        /* this should be in poll */
@@ -547,8 +545,8 @@ static int rxrpc_send_data(struct kiocb *iocb,
        if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
                return -EPIPE;
 
-       iov = msg->msg_iov;
-       ioc = msg->msg_iovlen - 1;
+       iov = msg->msg_iter.iov;
+       ioc = msg->msg_iter.nr_segs - 1;
        from = iov->iov_base;
        segment = iov->iov_len;
        iov++;
index 0397ac9..c92f96c 100644 (file)
@@ -1609,9 +1609,6 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
        __u16 sinfo_flags = 0;
        long timeo;
        int err;
-       struct iov_iter from;
-
-       iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, msg_len);
 
        err = 0;
        sp = sctp_sk(sk);
@@ -1950,7 +1947,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
        }
 
        /* Break the message into multiple chunks of maximum size. */
-       datamsg = sctp_datamsg_from_user(asoc, sinfo, &from);
+       datamsg = sctp_datamsg_from_user(asoc, sinfo, &msg->msg_iter);
        if (IS_ERR(datamsg)) {
                err = PTR_ERR(datamsg);
                goto out_free;
index f676ac4..8809afc 100644 (file)
@@ -689,8 +689,7 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
         * the following is safe, since for compiler definitions of kvec and
         * iovec are identical, yielding the same in-core layout and alignment
         */
-       msg->msg_iov = (struct iovec *)vec;
-       msg->msg_iovlen = num;
+       iov_iter_init(&msg->msg_iter, WRITE, (struct iovec *)vec, num, size);
        result = sock_sendmsg(sock, msg, size);
        set_fs(oldfs);
        return result;
@@ -853,7 +852,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
         * the following is safe, since for compiler definitions of kvec and
         * iovec are identical, yielding the same in-core layout and alignment
         */
-       msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num;
+       iov_iter_init(&msg->msg_iter, READ, (struct iovec *)vec, num, size);
        result = sock_recvmsg(sock, msg, size, flags);
        set_fs(oldfs);
        return result;
@@ -913,8 +912,7 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
        msg->msg_namelen = 0;
        msg->msg_control = NULL;
        msg->msg_controllen = 0;
-       msg->msg_iov = (struct iovec *)iov;
-       msg->msg_iovlen = nr_segs;
+       iov_iter_init(&msg->msg_iter, READ, iov, nr_segs, size);
        msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
 
        return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
@@ -953,8 +951,7 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
        msg->msg_namelen = 0;
        msg->msg_control = NULL;
        msg->msg_controllen = 0;
-       msg->msg_iov = (struct iovec *)iov;
-       msg->msg_iovlen = nr_segs;
+       iov_iter_init(&msg->msg_iter, WRITE, iov, nr_segs, size);
        msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
        if (sock->type == SOCK_SEQPACKET)
                msg->msg_flags |= MSG_EOR;
@@ -1798,8 +1795,7 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
        iov.iov_base = buff;
        iov.iov_len = len;
        msg.msg_name = NULL;
-       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_namelen = 0;
@@ -1856,10 +1852,9 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
 
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
-       msg.msg_iovlen = 1;
-       msg.msg_iov = &iov;
        iov.iov_len = size;
        iov.iov_base = ubuf;
+       iov_iter_init(&msg.msg_iter, READ, &iov, 1, size);
        /* Save some cycles and don't copy the address if not needed */
        msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
        /* We assume all kernel code knows the size of sockaddr_storage */
@@ -1993,13 +1988,14 @@ static ssize_t copy_msghdr_from_user(struct msghdr *kmsg,
 {
        struct sockaddr __user *uaddr;
        struct iovec __user *uiov;
+       size_t nr_segs;
        ssize_t err;
 
        if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
            __get_user(uaddr, &umsg->msg_name) ||
            __get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
            __get_user(uiov, &umsg->msg_iov) ||
-           __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) ||
+           __get_user(nr_segs, &umsg->msg_iovlen) ||
            __get_user(kmsg->msg_control, &umsg->msg_control) ||
            __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
            __get_user(kmsg->msg_flags, &umsg->msg_flags))
@@ -2029,14 +2025,15 @@ static ssize_t copy_msghdr_from_user(struct msghdr *kmsg,
                kmsg->msg_namelen = 0;
        }
 
-       if (kmsg->msg_iovlen > UIO_MAXIOV)
+       if (nr_segs > UIO_MAXIOV)
                return -EMSGSIZE;
 
        err = rw_copy_check_uvector(save_addr ? READ : WRITE,
-                                   uiov, kmsg->msg_iovlen,
+                                   uiov, nr_segs,
                                    UIO_FASTIOV, *iov, iov);
        if (err >= 0)
-               kmsg->msg_iov = *iov;
+               iov_iter_init(&kmsg->msg_iter, save_addr ? READ : WRITE,
+                             *iov, nr_segs, err);
        return err;
 }
 
index 5b06597..a687b30 100644 (file)
@@ -194,7 +194,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
                __skb_queue_tail(list, skb);
                skb_copy_to_linear_data(skb, mhdr, mhsz);
                pktpos = skb->data + mhsz;
-               if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset,
+               if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset,
                                                 dsz))
                        return dsz;
                rc = -EFAULT;
@@ -224,7 +224,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
                if (drem < pktrem)
                        pktrem = drem;
 
-               if (memcpy_fromiovecend(pktpos, m->msg_iov, offset, pktrem)) {
+               if (memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset, pktrem)) {
                        rc = -EFAULT;
                        goto error;
                }
index 4450d62..8e1b102 100644 (file)
@@ -1459,9 +1459,6 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct scm_cookie tmp_scm;
        int max_level;
        int data_len = 0;
-       struct iov_iter from;
-
-       iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
 
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
@@ -1519,7 +1516,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        skb_put(skb, len - data_len);
        skb->data_len = data_len;
        skb->len = len;
-       err = skb_copy_datagram_from_iter(skb, 0, &from, len);
+       err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
        if (err)
                goto out_free;
 
@@ -1641,9 +1638,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        bool fds_sent = false;
        int max_level;
        int data_len;
-       struct iov_iter from;
-
-       iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
 
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
@@ -1700,7 +1694,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                skb_put(skb, size - data_len);
                skb->data_len = data_len;
                skb->len = size;
-               err = skb_copy_datagram_from_iter(skb, 0, &from, size);
+               err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
                if (err) {
                        kfree_skb(skb);
                        goto out_err;
index 20a0ba3..02d2e52 100644 (file)
@@ -1850,7 +1850,8 @@ static ssize_t vmci_transport_stream_enqueue(
        struct msghdr *msg,
        size_t len)
 {
-       return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0);
+       /* XXX: stripping const */
+       return vmci_qpair_enquev(vmci_trans(vsk)->qpair, (struct iovec *)msg->msg_iter.iov, len, 0);
 }
 
 static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk)