Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorDavid S. Miller <davem@davemloft.net>
Wed, 26 Nov 2014 01:02:51 +0000 (20:02 -0500)
committerDavid S. Miller <davem@davemloft.net>
Wed, 26 Nov 2014 01:02:51 +0000 (20:02 -0500)
More work from Al Viro to move away from modifying iovecs
by using iov_iter instead.

Signed-off-by: David S. Miller <davem@davemloft.net>
68 files changed:
crypto/algif_hash.c
crypto/algif_skcipher.c
drivers/isdn/mISDN/socket.c
drivers/net/macvtap.c
drivers/net/ppp/pppoe.c
drivers/net/tun.c
include/linux/skbuff.h
include/net/af_vsock.h
include/net/ipx.h
include/net/sctp/sm.h
include/net/sctp/structs.h
net/appletalk/ddp.c
net/atm/common.c
net/ax25/af_ax25.c
net/bluetooth/hci_sock.c
net/bluetooth/mgmt.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/caif/caif_socket.c
net/can/bcm.c
net/can/raw.c
net/core/datagram.c
net/dccp/proto.c
net/decnet/af_decnet.c
net/ieee802154/dgram.c
net/ieee802154/raw.c
net/ipv4/ping.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/udp.c
net/ipv6/raw.c
net/ipv6/udp.c
net/ipx/af_ipx.c
net/ipx/ipx_route.c
net/irda/af_irda.c
net/iucv/af_iucv.c
net/key/af_key.c
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ppp.c
net/llc/af_llc.c
net/netlink/af_netlink.c
net/netrom/af_netrom.c
net/nfc/llcp_commands.c
net/nfc/rawsock.c
net/packet/af_packet.c
net/phonet/datagram.c
net/phonet/pep.c
net/rds/ib.h
net/rds/ib_recv.c
net/rds/iw.h
net/rds/iw_recv.c
net/rds/message.c
net/rds/rds.h
net/rds/recv.c
net/rds/send.c
net/rds/tcp.h
net/rds/tcp_recv.c
net/rose/af_rose.c
net/sctp/chunk.c
net/sctp/sm_make_chunk.c
net/sctp/socket.c
net/tipc/msg.c
net/tipc/msg.h
net/tipc/socket.c
net/unix/af_unix.c
net/vmw_vsock/af_vsock.c
net/vmw_vsock/vmci_transport.c
net/x25/af_x25.c

index 8502462..35c93ff 100644 (file)
@@ -174,7 +174,7 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock,
                        goto unlock;
        }
 
-       err = memcpy_toiovec(msg->msg_iov, ctx->result, len);
+       err = memcpy_to_msg(msg, ctx->result, len);
 
 unlock:
        release_sock(sk);
index 83187f4..c3b482b 100644 (file)
@@ -298,9 +298,9 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock,
                        len = min_t(unsigned long, len,
                                    PAGE_SIZE - sg->offset - sg->length);
 
-                       err = memcpy_fromiovec(page_address(sg_page(sg)) +
-                                              sg->offset + sg->length,
-                                              msg->msg_iov, len);
+                       err = memcpy_from_msg(page_address(sg_page(sg)) +
+                                             sg->offset + sg->length,
+                                             msg, len);
                        if (err)
                                goto unlock;
 
@@ -337,8 +337,8 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock,
                        if (!sg_page(sg + i))
                                goto unlock;
 
-                       err = memcpy_fromiovec(page_address(sg_page(sg + i)),
-                                              msg->msg_iov, plen);
+                       err = memcpy_from_msg(page_address(sg_page(sg + i)),
+                                             msg, plen);
                        if (err) {
                                __free_page(sg_page(sg + i));
                                sg_assign_page(sg + i, NULL);
index dcbd858..84b3592 100644 (file)
@@ -203,7 +203,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        if (!skb)
                goto done;
 
-       if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+       if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
                err = -EFAULT;
                goto done;
        }
index 42a80d3..22b4cf2 100644 (file)
@@ -640,12 +640,12 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
 
 /* Get packet from user space buffer */
 static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
-                               const struct iovec *iv, unsigned long total_len,
-                               size_t count, int noblock)
+                               struct iov_iter *from, int noblock)
 {
        int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN);
        struct sk_buff *skb;
        struct macvlan_dev *vlan;
+       unsigned long total_len = iov_iter_count(from);
        unsigned long len = total_len;
        int err;
        struct virtio_net_hdr vnet_hdr = { 0 };
@@ -653,6 +653,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
        int copylen = 0;
        bool zerocopy = false;
        size_t linear;
+       ssize_t n;
 
        if (q->flags & IFF_VNET_HDR) {
                vnet_hdr_len = q->vnet_hdr_sz;
@@ -662,10 +663,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
                        goto err;
                len -= vnet_hdr_len;
 
-               err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0,
-                                          sizeof(vnet_hdr));
-               if (err < 0)
+               err = -EFAULT;
+               n = copy_from_iter(&vnet_hdr, sizeof(vnet_hdr), from);
+               if (n != sizeof(vnet_hdr))
                        goto err;
+               iov_iter_advance(from, vnet_hdr_len - sizeof(vnet_hdr));
                if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
                     vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 >
                                                        vnet_hdr.hdr_len)
@@ -680,17 +682,16 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
        if (unlikely(len < ETH_HLEN))
                goto err;
 
-       err = -EMSGSIZE;
-       if (unlikely(count > UIO_MAXIOV))
-               goto err;
-
        if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) {
+               struct iov_iter i;
+
                copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN;
                if (copylen > good_linear)
                        copylen = good_linear;
                linear = copylen;
-               if (iov_pages(iv, vnet_hdr_len + copylen, count)
-                   <= MAX_SKB_FRAGS)
+               i = *from;
+               iov_iter_advance(&i, copylen);
+               if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS)
                        zerocopy = true;
        }
 
@@ -708,10 +709,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
                goto err;
 
        if (zerocopy)
-               err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count);
+               err = zerocopy_sg_from_iter(skb, from);
        else {
-               err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len,
-                                                  len);
+               err = skb_copy_datagram_from_iter(skb, 0, from, len);
                if (!err && m && m->msg_control) {
                        struct ubuf_info *uarg = m->msg_control;
                        uarg->callback(uarg, false);
@@ -764,16 +764,12 @@ err:
        return err;
 }
 
-static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv,
-                                unsigned long count, loff_t pos)
+static ssize_t macvtap_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        struct file *file = iocb->ki_filp;
-       ssize_t result = -ENOLINK;
        struct macvtap_queue *q = file->private_data;
 
-       result = macvtap_get_user(q, NULL, iv, iov_length(iv, count), count,
-                                 file->f_flags & O_NONBLOCK);
-       return result;
+       return macvtap_get_user(q, NULL, from, file->f_flags & O_NONBLOCK);
 }
 
 /* Put packet to the user space buffer */
@@ -831,64 +827,55 @@ done:
 }
 
 static ssize_t macvtap_do_read(struct macvtap_queue *q,
-                              const struct iovec *iv, unsigned long segs,
-                              unsigned long len,
+                              struct iov_iter *to,
                               int noblock)
 {
        DEFINE_WAIT(wait);
        struct sk_buff *skb;
        ssize_t ret = 0;
-       struct iov_iter iter;
 
-       while (len) {
+       if (!iov_iter_count(to))
+               return 0;
+
+       while (1) {
                if (!noblock)
                        prepare_to_wait(sk_sleep(&q->sk), &wait,
                                        TASK_INTERRUPTIBLE);
 
                /* Read frames from the queue */
                skb = skb_dequeue(&q->sk.sk_receive_queue);
-               if (!skb) {
-                       if (noblock) {
-                               ret = -EAGAIN;
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               ret = -ERESTARTSYS;
-                               break;
-                       }
-                       /* Nothing to read, let's sleep */
-                       schedule();
-                       continue;
+               if (skb)
+                       break;
+               if (noblock) {
+                       ret = -EAGAIN;
+                       break;
+               }
+               if (signal_pending(current)) {
+                       ret = -ERESTARTSYS;
+                       break;
                }
-               iov_iter_init(&iter, READ, iv, segs, len);
-               ret = macvtap_put_user(q, skb, &iter);
+               /* Nothing to read, let's sleep */
+               schedule();
+       }
+       if (skb) {
+               ret = macvtap_put_user(q, skb, to);
                kfree_skb(skb);
-               break;
        }
-
        if (!noblock)
                finish_wait(sk_sleep(&q->sk), &wait);
        return ret;
 }
 
-static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv,
-                               unsigned long count, loff_t pos)
+static ssize_t macvtap_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
        struct file *file = iocb->ki_filp;
        struct macvtap_queue *q = file->private_data;
-       ssize_t len, ret = 0;
-
-       len = iov_length(iv, count);
-       if (len < 0) {
-               ret = -EINVAL;
-               goto out;
-       }
+       ssize_t len = iov_iter_count(to), ret;
 
-       ret = macvtap_do_read(q, iv, count, len, file->f_flags & O_NONBLOCK);
+       ret = macvtap_do_read(q, to, file->f_flags & O_NONBLOCK);
        ret = min_t(ssize_t, ret, len);
        if (ret > 0)
                iocb->ki_pos = ret;
-out:
        return ret;
 }
 
@@ -1089,8 +1076,10 @@ static const struct file_operations macvtap_fops = {
        .owner          = THIS_MODULE,
        .open           = macvtap_open,
        .release        = macvtap_release,
-       .aio_read       = macvtap_aio_read,
-       .aio_write      = macvtap_aio_write,
+       .read           = new_sync_read,
+       .write          = new_sync_write,
+       .read_iter      = macvtap_read_iter,
+       .write_iter     = macvtap_write_iter,
        .poll           = macvtap_poll,
        .llseek         = no_llseek,
        .unlocked_ioctl = macvtap_ioctl,
@@ -1103,8 +1092,9 @@ 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);
-       return macvtap_get_user(q, m, m->msg_iov, total_len, m->msg_iovlen,
-                           m->msg_flags & MSG_DONTWAIT);
+       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);
 }
 
 static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock,
@@ -1112,11 +1102,12 @@ 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;
-       ret = macvtap_do_read(q, m->msg_iov, m->msg_iovlen, total_len,
-                         flags & MSG_DONTWAIT);
+       iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len);
+       ret = macvtap_do_read(q, &to, flags & MSG_DONTWAIT);
        if (ret > total_len) {
                m->msg_flags |= MSG_TRUNC;
                ret = flags & MSG_TRUNC ? ret : total_len;
index 443cbbf..d2408a5 100644 (file)
@@ -869,7 +869,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
        ph = (struct pppoe_hdr *)skb_put(skb, total_len + sizeof(struct pppoe_hdr));
        start = (char *)&ph->tag[0];
 
-       error = memcpy_fromiovec(start, m->msg_iov, total_len);
+       error = memcpy_from_msg(start, m, total_len);
        if (error < 0) {
                kfree_skb(skb);
                goto end;
index ac53a73..4b743c6 100644 (file)
@@ -1012,28 +1012,29 @@ static struct sk_buff *tun_alloc_skb(struct tun_file *tfile,
 
 /* Get packet from user space buffer */
 static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
-                           void *msg_control, const struct iovec *iv,
-                           size_t total_len, size_t count, int noblock)
+                           void *msg_control, struct iov_iter *from,
+                           int noblock)
 {
        struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
        struct sk_buff *skb;
+       size_t total_len = iov_iter_count(from);
        size_t len = total_len, align = NET_SKB_PAD, linear;
        struct virtio_net_hdr gso = { 0 };
        int good_linear;
-       int offset = 0;
        int copylen;
        bool zerocopy = false;
        int err;
        u32 rxhash;
+       ssize_t n;
 
        if (!(tun->flags & TUN_NO_PI)) {
                if (len < sizeof(pi))
                        return -EINVAL;
                len -= sizeof(pi);
 
-               if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
+               n = copy_from_iter(&pi, sizeof(pi), from);
+               if (n != sizeof(pi))
                        return -EFAULT;
-               offset += sizeof(pi);
        }
 
        if (tun->flags & TUN_VNET_HDR) {
@@ -1041,7 +1042,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
                        return -EINVAL;
                len -= tun->vnet_hdr_sz;
 
-               if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
+               n = copy_from_iter(&gso, sizeof(gso), from);
+               if (n != sizeof(gso))
                        return -EFAULT;
 
                if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
@@ -1050,7 +1052,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 
                if (gso.hdr_len > len)
                        return -EINVAL;
-               offset += tun->vnet_hdr_sz;
+               iov_iter_advance(from, tun->vnet_hdr_sz);
        }
 
        if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
@@ -1063,6 +1065,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
        good_linear = SKB_MAX_HEAD(align);
 
        if (msg_control) {
+               struct iov_iter i = *from;
+
                /* There are 256 bytes to be copied in skb, so there is
                 * enough room for skb expand head in case it is used.
                 * The rest of the buffer is mapped from userspace.
@@ -1071,7 +1075,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
                if (copylen > good_linear)
                        copylen = good_linear;
                linear = copylen;
-               if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS)
+               iov_iter_advance(&i, copylen);
+               if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS)
                        zerocopy = true;
        }
 
@@ -1091,9 +1096,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
        }
 
        if (zerocopy)
-               err = zerocopy_sg_from_iovec(skb, iv, offset, count);
+               err = zerocopy_sg_from_iter(skb, from);
        else {
-               err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len);
+               err = skb_copy_datagram_from_iter(skb, 0, from, len);
                if (!err && msg_control) {
                        struct ubuf_info *uarg = msg_control;
                        uarg->callback(uarg, false);
@@ -1207,8 +1212,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
        return total_len;
 }
 
-static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
-                             unsigned long count, loff_t pos)
+static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        struct file *file = iocb->ki_filp;
        struct tun_struct *tun = tun_get(file);
@@ -1218,10 +1222,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
        if (!tun)
                return -EBADFD;
 
-       tun_debug(KERN_INFO, tun, "tun_chr_write %ld\n", count);
-
-       result = tun_get_user(tun, tfile, NULL, iv, iov_length(iv, count),
-                             count, file->f_flags & O_NONBLOCK);
+       result = tun_get_user(tun, tfile, NULL, from, file->f_flags & O_NONBLOCK);
 
        tun_put(tun);
        return result;
@@ -1339,18 +1340,17 @@ done:
 }
 
 static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
-                          const struct iovec *iv, unsigned long segs,
-                          ssize_t len, int noblock)
+                          struct iov_iter *to,
+                          int noblock)
 {
        struct sk_buff *skb;
-       ssize_t ret = 0;
+       ssize_t ret;
        int peeked, err, off = 0;
-       struct iov_iter iter;
 
        tun_debug(KERN_INFO, tun, "tun_do_read\n");
 
-       if (!len)
-               return ret;
+       if (!iov_iter_count(to))
+               return 0;
 
        if (tun->dev->reg_state != NETREG_REGISTERED)
                return -EIO;
@@ -1359,37 +1359,27 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
        skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0,
                                  &peeked, &off, &err);
        if (!skb)
-               return ret;
+               return 0;
 
-       iov_iter_init(&iter, READ, iv, segs, len);
-       ret = tun_put_user(tun, tfile, skb, &iter);
+       ret = tun_put_user(tun, tfile, skb, to);
        kfree_skb(skb);
 
        return ret;
 }
 
-static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
-                           unsigned long count, loff_t pos)
+static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
        struct file *file = iocb->ki_filp;
        struct tun_file *tfile = file->private_data;
        struct tun_struct *tun = __tun_get(tfile);
-       ssize_t len, ret;
+       ssize_t len = iov_iter_count(to), ret;
 
        if (!tun)
                return -EBADFD;
-       len = iov_length(iv, count);
-       if (len < 0) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ret = tun_do_read(tun, tfile, iv, count, len,
-                         file->f_flags & O_NONBLOCK);
+       ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK);
        ret = min_t(ssize_t, ret, len);
        if (ret > 0)
                iocb->ki_pos = ret;
-out:
        tun_put(tun);
        return ret;
 }
@@ -1456,11 +1446,14 @@ 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;
-       ret = tun_get_user(tun, tfile, m->msg_control, m->msg_iov, total_len,
-                          m->msg_iovlen, m->msg_flags & MSG_DONTWAIT);
+
+       iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len);
+       ret = tun_get_user(tun, tfile, m->msg_control, &from,
+                          m->msg_flags & MSG_DONTWAIT);
        tun_put(tun);
        return ret;
 }
@@ -1471,6 +1464,7 @@ 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)
@@ -1485,8 +1479,8 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
                                         SOL_PACKET, TUN_TX_TIMESTAMP);
                goto out;
        }
-       ret = tun_do_read(tun, tfile, m->msg_iov, m->msg_iovlen, total_len,
-                         flags & MSG_DONTWAIT);
+       iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len);
+       ret = tun_do_read(tun, tfile, &to, flags & MSG_DONTWAIT);
        if (ret > total_len) {
                m->msg_flags |= MSG_TRUNC;
                ret = flags & MSG_TRUNC ? ret : total_len;
@@ -2242,10 +2236,10 @@ static int tun_chr_show_fdinfo(struct seq_file *m, struct file *f)
 static const struct file_operations tun_fops = {
        .owner  = THIS_MODULE,
        .llseek = no_llseek,
-       .read  = do_sync_read,
-       .aio_read  = tun_chr_aio_read,
-       .write = do_sync_write,
-       .aio_write = tun_chr_aio_write,
+       .read  = new_sync_read,
+       .write = new_sync_write,
+       .read_iter  = tun_chr_read_iter,
+       .write_iter = tun_chr_write_iter,
        .poll   = tun_chr_poll,
        .unlocked_ioctl = tun_chr_ioctl,
 #ifdef CONFIG_COMPAT
index 78c299f..7691ad5 100644 (file)
@@ -2651,13 +2651,16 @@ static inline int skb_copy_datagram_msg(const struct sk_buff *from, int offset,
 }
 int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen,
                                     struct iovec *iov);
-int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
-                                const struct iovec *from, int from_offset,
-                                int len);
-int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *frm,
-                          int offset, size_t count);
+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);
+}
+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);
 int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags);
@@ -2682,6 +2685,16 @@ int skb_ensure_writable(struct sk_buff *skb, int write_len);
 int skb_vlan_pop(struct sk_buff *skb);
 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);
+}
+
+static inline int memcpy_to_msg(struct msghdr *msg, void *data, int len)
+{
+       return memcpy_toiovec(msg->msg_iov, data, len);
+}
+
 struct skb_checksum_ops {
        __wsum (*update)(const void *mem, int len, __wsum wsum);
        __wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len);
index 4282778..0d87674 100644 (file)
@@ -103,14 +103,14 @@ struct vsock_transport {
        int (*dgram_dequeue)(struct kiocb *kiocb, struct vsock_sock *vsk,
                             struct msghdr *msg, size_t len, int flags);
        int (*dgram_enqueue)(struct vsock_sock *, struct sockaddr_vm *,
-                            struct iovec *, size_t len);
+                            struct msghdr *, size_t len);
        bool (*dgram_allow)(u32 cid, u32 port);
 
        /* STREAM. */
        /* TODO: stream_bind() */
-       ssize_t (*stream_dequeue)(struct vsock_sock *, struct iovec *,
+       ssize_t (*stream_dequeue)(struct vsock_sock *, struct msghdr *,
                                  size_t len, int flags);
-       ssize_t (*stream_enqueue)(struct vsock_sock *, struct iovec *,
+       ssize_t (*stream_enqueue)(struct vsock_sock *, struct msghdr *,
                                  size_t len);
        s64 (*stream_has_data)(struct vsock_sock *);
        s64 (*stream_has_space)(struct vsock_sock *);
index 320f47b..e5cff68 100644 (file)
@@ -150,7 +150,7 @@ int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc,
                     unsigned char *node);
 void ipxrtr_del_routes(struct ipx_interface *intrfc);
 int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
-                       struct iovec *iov, size_t len, int noblock);
+                       struct msghdr *msg, size_t len, int noblock);
 int ipxrtr_route_skb(struct sk_buff *skb);
 struct ipx_route *ipxrtr_lookup(__be32 net);
 int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
index 72a31db..487ef34 100644 (file)
@@ -219,7 +219,7 @@ struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *,
                                      const struct sctp_chunk *,
                                      __u32 tsn);
 struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
-                                       const struct msghdr *, size_t msg_len);
+                                       struct msghdr *, size_t msg_len);
 struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
                                   const struct sctp_chunk *,
                                   const __u8 *,
index 806e3b5..2bb2fcf 100644 (file)
@@ -531,7 +531,7 @@ struct sctp_datamsg {
 
 struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
                                            struct sctp_sndrcvinfo *,
-                                           struct msghdr *, int len);
+                                           struct iov_iter *);
 void sctp_datamsg_free(struct sctp_datamsg *);
 void sctp_datamsg_put(struct sctp_datamsg *);
 void sctp_chunk_fail(struct sctp_chunk *, int error);
@@ -647,8 +647,8 @@ struct sctp_chunk {
 
 void sctp_chunk_hold(struct sctp_chunk *);
 void sctp_chunk_put(struct sctp_chunk *);
-int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len,
-                         struct iovec *data);
+int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len,
+                         struct iov_iter *from);
 void sctp_chunk_free(struct sctp_chunk *);
 void  *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data);
 struct sctp_chunk *sctp_chunkify(struct sk_buff *,
index 425942d..0d0766e 100644 (file)
@@ -1659,7 +1659,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
 
        SOCK_DEBUG(sk, "SK %p: Copy user data (%Zd bytes).\n", sk, len);
 
-       err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+       err = memcpy_from_msg(skb_put(skb, len), msg, len);
        if (err) {
                kfree_skb(skb);
                err = -EFAULT;
index 9cd1cca..f591129 100644 (file)
@@ -570,15 +570,16 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 }
 
 int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
-               size_t total_len)
+               size_t size)
 {
        struct sock *sk = sock->sk;
        DEFINE_WAIT(wait);
        struct atm_vcc *vcc;
        struct sk_buff *skb;
        int eff, error;
-       const void __user *buff;
-       int size;
+       struct iov_iter from;
+
+       iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, size);
 
        lock_sock(sk);
        if (sock->state != SS_CONNECTED) {
@@ -589,12 +590,6 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
                error = -EISCONN;
                goto out;
        }
-       if (m->msg_iovlen != 1) {
-               error = -ENOSYS; /* fix this later @@@ */
-               goto out;
-       }
-       buff = m->msg_iov->iov_base;
-       size = m->msg_iov->iov_len;
        vcc = ATM_SD(sock);
        if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
            test_bit(ATM_VF_CLOSE, &vcc->flags) ||
@@ -607,7 +602,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
                error = 0;
                goto out;
        }
-       if (size < 0 || size > vcc->qos.txtp.max_sdu) {
+       if (size > vcc->qos.txtp.max_sdu) {
                error = -EMSGSIZE;
                goto out;
        }
@@ -639,7 +634,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_user(skb_put(skb, size), buff, size)) {
+       if (copy_from_iter(skb_put(skb, size), size, &from) != size) {
                kfree_skb(skb);
                error = -EFAULT;
                goto out;
index f4f835e..ca049a7 100644 (file)
@@ -1549,7 +1549,7 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
        skb_reserve(skb, size - len);
 
        /* User data follows immediately after the AX.25 data */
-       if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+       if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
                err = -EFAULT;
                kfree_skb(skb);
                goto out;
index 5e2cd25..2c245fd 100644 (file)
@@ -947,7 +947,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        if (!skb)
                goto done;
 
-       if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+       if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
                err = -EFAULT;
                goto drop;
        }
index cbeef5f..f3e4a16 100644 (file)
@@ -5767,7 +5767,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
        if (!buf)
                return -ENOMEM;
 
-       if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
+       if (memcpy_from_msg(buf, msg, msglen)) {
                err = -EFAULT;
                goto done;
        }
index 8bbbb5e..2348176 100644 (file)
@@ -588,7 +588,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                }
                skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
 
-               err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+               err = memcpy_from_msg(skb_put(skb, size), msg, size);
                if (err) {
                        kfree_skb(skb);
                        if (sent == 0)
index 7ee9e4a..30e5ea3 100644 (file)
@@ -285,7 +285,7 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
        if (!skb)
                return err;
 
-       if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+       if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
                kfree_skb(skb);
                return -EFAULT;
        }
index fbcd156..ac618b0 100644 (file)
@@ -418,7 +418,7 @@ unlock:
                }
                release_sock(sk);
                chunk = min_t(unsigned int, skb->len, size);
-               if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+               if (memcpy_to_msg(msg, skb->data, chunk)) {
                        skb_queue_head(&sk->sk_receive_queue, skb);
                        if (copied == 0)
                                copied = -EFAULT;
@@ -566,7 +566,7 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock,
 
        skb_reserve(skb, cf_sk->headroom);
 
-       ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+       ret = memcpy_from_msg(skb_put(skb, len), msg, len);
 
        if (ret)
                goto err;
@@ -641,7 +641,7 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                 */
                size = min_t(int, size, skb_tailroom(skb));
 
-               err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+               err = memcpy_from_msg(skb_put(skb, size), msg, size);
                if (err) {
                        kfree_skb(skb);
                        goto out_err;
index dcb75c0..0167118 100644 (file)
@@ -858,8 +858,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 
                /* update can_frames content */
                for (i = 0; i < msg_head->nframes; i++) {
-                       err = memcpy_fromiovec((u8 *)&op->frames[i],
-                                              msg->msg_iov, CFSIZ);
+                       err = memcpy_from_msg((u8 *)&op->frames[i], msg, CFSIZ);
 
                        if (op->frames[i].can_dlc > 8)
                                err = -EINVAL;
@@ -894,8 +893,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
                        op->frames = &op->sframe;
 
                for (i = 0; i < msg_head->nframes; i++) {
-                       err = memcpy_fromiovec((u8 *)&op->frames[i],
-                                              msg->msg_iov, CFSIZ);
+                       err = memcpy_from_msg((u8 *)&op->frames[i], msg, CFSIZ);
 
                        if (op->frames[i].can_dlc > 8)
                                err = -EINVAL;
@@ -1024,9 +1022,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 
                if (msg_head->nframes) {
                        /* update can_frames content */
-                       err = memcpy_fromiovec((u8 *)op->frames,
-                                              msg->msg_iov,
-                                              msg_head->nframes * CFSIZ);
+                       err = memcpy_from_msg((u8 *)op->frames, msg,
+                                             msg_head->nframes * CFSIZ);
                        if (err < 0)
                                return err;
 
@@ -1072,8 +1069,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
                }
 
                if (msg_head->nframes) {
-                       err = memcpy_fromiovec((u8 *)op->frames, msg->msg_iov,
-                                              msg_head->nframes * CFSIZ);
+                       err = memcpy_from_msg((u8 *)op->frames, msg,
+                                             msg_head->nframes * CFSIZ);
                        if (err < 0) {
                                if (op->frames != &op->sframe)
                                        kfree(op->frames);
@@ -1209,7 +1206,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
 
        can_skb_reserve(skb);
 
-       err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ);
+       err = memcpy_from_msg(skb_put(skb, CFSIZ), msg, CFSIZ);
        if (err < 0) {
                kfree_skb(skb);
                return err;
@@ -1285,7 +1282,7 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        /* read message head information */
 
-       ret = memcpy_fromiovec((u8 *)&msg_head, msg->msg_iov, MHSIZ);
+       ret = memcpy_from_msg((u8 *)&msg_head, msg, MHSIZ);
        if (ret < 0)
                return ret;
 
@@ -1558,7 +1555,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (skb->len < size)
                size = skb->len;
 
-       err = memcpy_toiovec(msg->msg_iov, skb->data, size);
+       err = memcpy_to_msg(msg, skb->data, size);
        if (err < 0) {
                skb_free_datagram(sk, skb);
                return err;
index 081e81f..dfdcffb 100644 (file)
@@ -703,7 +703,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
        can_skb_reserve(skb);
        can_skb_prv(skb)->ifindex = dev->ifindex;
 
-       err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+       err = memcpy_from_msg(skb_put(skb, size), msg, size);
        if (err < 0)
                goto free_skb;
 
@@ -750,7 +750,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
        else
                size = skb->len;
 
-       err = memcpy_toiovec(msg->msg_iov, skb->data, size);
+       err = memcpy_to_msg(msg, skb->data, size);
        if (err < 0) {
                skb_free_datagram(sk, skb);
                return err;
index 26391a3..b6e303b 100644 (file)
@@ -480,18 +480,16 @@ short_copy:
 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
  *     @offset: offset in the buffer to start copying to
- *     @from: io vector to copy to
- *     @from_offset: offset in the io vector to start copying from
+ *     @from: the copy source
  *     @len: amount of data to copy to buffer from iovec
  *
  *     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 skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
+                                struct iov_iter *from,
                                 int len)
 {
        int start = skb_headlen(skb);
@@ -502,13 +500,11 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
        if (copy > 0) {
                if (copy > len)
                        copy = len;
-               if (memcpy_fromiovecend(skb->data + offset, from, from_offset,
-                                       copy))
+               if (copy_from_iter(skb->data + offset, copy, from) != copy)
                        goto fault;
                if ((len -= copy) == 0)
                        return 0;
                offset += copy;
-               from_offset += copy;
        }
 
        /* Copy paged appendix. Hmm... why does this look so complicated? */
@@ -520,24 +516,19 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
 
                end = start + skb_frag_size(frag);
                if ((copy = end - offset) > 0) {
-                       int err;
-                       u8  *vaddr;
-                       struct page *page = skb_frag_page(frag);
+                       size_t copied;
 
                        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)
+                       copied = copy_page_from_iter(skb_frag_page(frag),
+                                         frag->page_offset + offset - start,
+                                         copy, from);
+                       if (copied != copy)
                                goto fault;
 
                        if (!(len -= copy))
                                return 0;
                        offset += copy;
-                       from_offset += copy;
                }
                start = end;
        }
@@ -551,16 +542,13 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
                if ((copy = end - offset) > 0) {
                        if (copy > len)
                                copy = len;
-                       if (skb_copy_datagram_from_iovec(frag_iter,
-                                                        offset - start,
-                                                        from,
-                                                        from_offset,
-                                                        copy))
+                       if (skb_copy_datagram_from_iter(frag_iter,
+                                                       offset - start,
+                                                       from, copy))
                                goto fault;
                        if ((len -= copy) == 0)
                                return 0;
                        offset += copy;
-                       from_offset += copy;
                }
                start = end;
        }
@@ -570,78 +558,61 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
 fault:
        return -EFAULT;
 }
-EXPORT_SYMBOL(skb_copy_datagram_from_iovec);
+EXPORT_SYMBOL(skb_copy_datagram_from_iter);
 
 /**
- *     zerocopy_sg_from_iovec - Build a zerocopy datagram from an iovec
+ *     zerocopy_sg_from_iter - Build a zerocopy datagram from an iov_iter
  *     @skb: buffer to copy
- *     @from: io vector to copy from
- *     @offset: offset in the io vector to start copying from
- *     @count: amount of vectors to copy to buffer from
+ *     @from: the source to copy from
  *
  *     The function will first copy up to headlen, and then pin the userspace
  *     pages and build frags through them.
  *
  *     Returns 0, -EFAULT or -EMSGSIZE.
- *     Note: the iovec is not modified during the copy
  */
-int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
-                                 int offset, size_t count)
+int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from)
 {
-       int len = iov_length(from, count) - offset;
+       int len = iov_iter_count(from);
        int copy = min_t(int, skb_headlen(skb), len);
-       int size;
-       int i = 0;
+       int frag = 0;
 
        /* copy up to skb headlen */
-       if (skb_copy_datagram_from_iovec(skb, 0, from, offset, copy))
+       if (skb_copy_datagram_from_iter(skb, 0, from, copy))
                return -EFAULT;
 
-       if (len == copy)
-               return 0;
-
-       offset += copy;
-       while (count--) {
-               struct page *page[MAX_SKB_FRAGS];
-               int num_pages;
-               unsigned long base;
+       while (iov_iter_count(from)) {
+               struct page *pages[MAX_SKB_FRAGS];
+               size_t start;
+               ssize_t copied;
                unsigned long truesize;
+               int n = 0;
 
-               /* Skip over from offset and copied */
-               if (offset >= from->iov_len) {
-                       offset -= from->iov_len;
-                       ++from;
-                       continue;
-               }
-               len = from->iov_len - offset;
-               base = (unsigned long)from->iov_base + offset;
-               size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
-               if (i + size > MAX_SKB_FRAGS)
+               if (frag == MAX_SKB_FRAGS)
                        return -EMSGSIZE;
-               num_pages = get_user_pages_fast(base, size, 0, &page[i]);
-               if (num_pages != size) {
-                       release_pages(&page[i], num_pages, 0);
+
+               copied = iov_iter_get_pages(from, pages, ~0U,
+                                           MAX_SKB_FRAGS - frag, &start);
+               if (copied < 0)
                        return -EFAULT;
-               }
-               truesize = size * PAGE_SIZE;
-               skb->data_len += len;
-               skb->len += len;
+
+               iov_iter_advance(from, copied);
+
+               truesize = PAGE_ALIGN(copied + start);
+               skb->data_len += copied;
+               skb->len += copied;
                skb->truesize += truesize;
                atomic_add(truesize, &skb->sk->sk_wmem_alloc);
-               while (len) {
-                       int off = base & ~PAGE_MASK;
-                       int size = min_t(int, len, PAGE_SIZE - off);
-                       skb_fill_page_desc(skb, i, page[i], off, size);
-                       base += size;
-                       len -= size;
-                       i++;
+               while (copied) {
+                       int size = min_t(int, copied, PAGE_SIZE - start);
+                       skb_fill_page_desc(skb, frag++, pages[n], start, size);
+                       start = 0;
+                       copied -= size;
+                       n++;
                }
-               offset = 0;
-               ++from;
        }
        return 0;
 }
-EXPORT_SYMBOL(zerocopy_sg_from_iovec);
+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,
index 8e6ae94..19f0387 100644 (file)
@@ -781,7 +781,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                goto out_release;
 
        skb_reserve(skb, sk->sk_prot->max_header);
-       rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+       rc = memcpy_from_msg(skb_put(skb, len), msg, len);
        if (rc != 0)
                goto out_discard;
 
index 25733d5..8102286 100644 (file)
@@ -1760,7 +1760,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
                if ((chunk + copied) > size)
                        chunk = size - copied;
 
-               if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+               if (memcpy_to_msg(msg, skb->data, chunk)) {
                        rv = -EFAULT;
                        break;
                }
@@ -2032,7 +2032,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
 
                skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER);
 
-               if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+               if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
                        err = -EFAULT;
                        goto out;
                }
index b8555ec..2c7a93e 100644 (file)
@@ -276,7 +276,7 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
        if (err < 0)
                goto out_skb;
 
-       err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+       err = memcpy_from_msg(skb_put(skb, size), msg, size);
        if (err < 0)
                goto out_skb;
 
index 21c3894..61e9d29 100644 (file)
@@ -150,7 +150,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk,
        skb_reset_mac_header(skb);
        skb_reset_network_header(skb);
 
-       err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+       err = memcpy_from_msg(skb_put(skb, size), msg, size);
        if (err < 0)
                goto out_skb;
 
index ce2920f..ef8f6ee 100644 (file)
@@ -660,7 +660,7 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
         *      Fetch the ICMP header provided by the userland.
         *      iovec is modified! The ICMP header is consumed.
         */
-       if (memcpy_fromiovec(user_icmph, msg->msg_iov, icmph_len))
+       if (memcpy_from_msg(user_icmph, msg, icmph_len))
                return -EFAULT;
 
        if (family == AF_INET) {
index c239f47..435443b 100644 (file)
@@ -1349,7 +1349,7 @@ static int tcp_recv_urg(struct sock *sk, struct msghdr *msg, int len, int flags)
 
                if (len > 0) {
                        if (!(flags & MSG_TRUNC))
-                               err = memcpy_toiovec(msg->msg_iov, &c, 1);
+                               err = memcpy_to_msg(msg, &c, 1);
                        len = 1;
                } else
                        msg->msg_flags |= MSG_TRUNC;
index d22a31f..69de1a1 100644 (file)
@@ -4368,7 +4368,7 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
        if (tcp_try_rmem_schedule(sk, skb, skb->truesize))
                goto err_free;
 
-       if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size))
+       if (memcpy_from_msg(skb_put(skb, size), msg, size))
                goto err_free;
 
        TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt;
index 4a16b91..b2d6068 100644 (file)
@@ -1284,9 +1284,8 @@ try_again:
                err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
                                            msg, copied);
        else {
-               err = skb_copy_and_csum_datagram_iovec(skb,
-                                                      sizeof(struct udphdr),
-                                                      msg->msg_iov);
+               err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr),
+                                                    msg);
 
                if (err == -EINVAL)
                        goto csum_copy_err;
index 0cbcf98..8baa53e 100644 (file)
@@ -492,7 +492,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
                        goto csum_copy_err;
                err = skb_copy_datagram_msg(skb, 0, msg, copied);
        } else {
-               err = skb_copy_and_csum_datagram_iovec(skb, 0, msg->msg_iov);
+               err = skb_copy_and_csum_datagram_msg(skb, 0, msg);
                if (err == -EINVAL)
                        goto csum_copy_err;
        }
index dbc0b04..7cfb5d7 100644 (file)
@@ -428,7 +428,7 @@ try_again:
                err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
                                            msg, copied);
        else {
-               err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
+               err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), msg);
                if (err == -EINVAL)
                        goto csum_copy_err;
        }
index 97dc432..f11ad1d 100644 (file)
@@ -1745,8 +1745,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
                memcpy(usipx->sipx_node, ipxs->dest_addr.node, IPX_NODE_LEN);
        }
 
-       rc = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len,
-                                flags & MSG_DONTWAIT);
+       rc = ipxrtr_route_packet(sk, usipx, msg, len, flags & MSG_DONTWAIT);
        if (rc >= 0)
                rc = len;
 out:
index 67e7ad3..3e2a32a 100644 (file)
@@ -165,7 +165,7 @@ int ipxrtr_route_skb(struct sk_buff *skb)
  * Route an outgoing frame from a socket.
  */
 int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
-                       struct iovec *iov, size_t len, int noblock)
+                       struct msghdr *msg, size_t len, int noblock)
 {
        struct sk_buff *skb;
        struct ipx_sock *ipxs = ipx_sk(sk);
@@ -229,7 +229,7 @@ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
        memcpy(ipx->ipx_dest.node, usipx->sipx_node, IPX_NODE_LEN);
        ipx->ipx_dest.sock              = usipx->sipx_port;
 
-       rc = memcpy_fromiovec(skb_put(skb, len), iov, len);
+       rc = memcpy_from_msg(skb_put(skb, len), msg, len);
        if (rc) {
                kfree_skb(skb);
                goto out_put;
index e8c4090..568edc7 100644 (file)
@@ -1319,7 +1319,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
        skb_reserve(skb, self->max_header_size + 16);
        skb_reset_transport_header(skb);
        skb_put(skb, len);
-       err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+       err = memcpy_from_msg(skb_transport_header(skb), msg, len);
        if (err) {
                kfree_skb(skb);
                goto out_err;
@@ -1466,7 +1466,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
                }
 
                chunk = min_t(unsigned int, skb->len, size);
-               if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+               if (memcpy_to_msg(msg, skb->data, chunk)) {
                        skb_queue_head(&sk->sk_receive_queue, skb);
                        if (copied == 0)
                                copied = -EFAULT;
@@ -1569,7 +1569,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
 
        pr_debug("%s(), appending user data\n", __func__);
        skb_put(skb, len);
-       err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+       err = memcpy_from_msg(skb_transport_header(skb), msg, len);
        if (err) {
                kfree_skb(skb);
                goto out;
@@ -1678,7 +1678,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
 
        pr_debug("%s(), appending user data\n", __func__);
        skb_put(skb, len);
-       err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+       err = memcpy_from_msg(skb_transport_header(skb), msg, len);
        if (err) {
                kfree_skb(skb);
                goto out;
index 057b564..1cd3f81 100644 (file)
@@ -1122,7 +1122,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        }
        if (iucv->transport == AF_IUCV_TRANS_HIPER)
                skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN);
-       if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+       if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
                err = -EFAULT;
                goto fail;
        }
index e588309..f8ac939 100644 (file)
@@ -3611,7 +3611,7 @@ static int pfkey_sendmsg(struct kiocb *kiocb,
                goto out;
 
        err = -EFAULT;
-       if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len))
+       if (memcpy_from_msg(skb_put(skb,len), msg, len))
                goto out;
 
        hdr = pfkey_get_base_msg(skb, &err);
index a6cc1fe..05dfc8a 100644 (file)
@@ -441,7 +441,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
        *((__be32 *) skb_put(skb, 4)) = 0;
 
        /* Copy user data into skb */
-       rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+       rc = memcpy_from_msg(skb_put(skb, len), msg, len);
        if (rc < 0) {
                kfree_skb(skb);
                goto error;
index c559bcd..cc7a828 100644 (file)
@@ -346,8 +346,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
        skb_put(skb, 2);
 
        /* Copy user data into skb */
-       error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov,
-                                total_len);
+       error = memcpy_from_msg(skb_put(skb, total_len), m, total_len);
        if (error < 0) {
                kfree_skb(skb);
                goto error_put_sess_tun;
index af66266..2c0b83c 100644 (file)
@@ -921,7 +921,7 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
        skb->dev      = llc->dev;
        skb->protocol = llc_proto_type(addr->sllc_arphrd);
        skb_reserve(skb, hdrlen);
-       rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied);
+       rc = memcpy_from_msg(skb_put(skb, copied), msg, copied);
        if (rc)
                goto out;
        if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
index e1aad6e..63aa5c8 100644 (file)
@@ -2325,7 +2325,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
        NETLINK_CB(skb).flags   = netlink_skb_flags;
 
        err = -EFAULT;
-       if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+       if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
                kfree_skb(skb);
                goto out;
        }
index 7e13f6a..69f1d5e 100644 (file)
@@ -1113,7 +1113,7 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
        skb_put(skb, len);
 
        /* User data follows immediately after the NET/ROM transport header */
-       if (memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len)) {
+       if (memcpy_from_msg(skb_transport_header(skb), msg, len)) {
                kfree_skb(skb);
                err = -EFAULT;
                goto out;
index a3ad69a..c4da0c2 100644 (file)
@@ -665,7 +665,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
        if (msg_data == NULL)
                return -ENOMEM;
 
-       if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) {
+       if (memcpy_from_msg(msg_data, msg, len)) {
                kfree(msg_data);
                return -EFAULT;
        }
@@ -731,7 +731,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
        if (msg_data == NULL)
                return -ENOMEM;
 
-       if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) {
+       if (memcpy_from_msg(msg_data, msg, len)) {
                kfree(msg_data);
                return -EFAULT;
        }
index 9d7d2b7..373e138 100644 (file)
@@ -231,7 +231,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
        if (skb == NULL)
                return rc;
 
-       rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+       rc = memcpy_from_msg(skb_put(skb, len), msg, len);
        if (rc < 0) {
                kfree_skb(skb);
                return rc;
index 58af580..dfb148e 100644 (file)
@@ -1676,7 +1676,7 @@ retry:
                        if (len < hhlen)
                                skb_reset_network_header(skb);
                }
-               err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+               err = memcpy_from_msg(skb_put(skb, len), msg, len);
                if (err)
                        goto out_free;
                goto retry;
@@ -2408,6 +2408,10 @@ 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.
@@ -2446,9 +2450,9 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
 
                len -= vnet_hdr_len;
 
-               err = memcpy_fromiovec((void *)&vnet_hdr, msg->msg_iov,
-                                      vnet_hdr_len);
-               if (err < 0)
+               err = -EFAULT;
+               n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from);
+               if (n != vnet_hdr_len)
                        goto out_unlock;
 
                if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
@@ -2518,7 +2522,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
        }
 
        /* 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)
                goto out_free;
 
@@ -2950,8 +2954,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
                        vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID;
                } /* else everything is zero */
 
-               err = memcpy_toiovec(msg->msg_iov, (void *)&vnet_hdr,
-                                    vnet_hdr_len);
+               err = memcpy_to_msg(msg, (void *)&vnet_hdr, vnet_hdr_len);
                if (err < 0)
                        goto out_free;
        }
index 0918bc2..26054b4 100644 (file)
@@ -109,7 +109,7 @@ static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,
                return err;
        skb_reserve(skb, MAX_PHONET_HEADER);
 
-       err = memcpy_fromiovec((void *)skb_put(skb, len), msg->msg_iov, len);
+       err = memcpy_from_msg((void *)skb_put(skb, len), msg, len);
        if (err < 0) {
                kfree_skb(skb);
                return err;
index 9cd069d..5d3f2b7 100644 (file)
@@ -1141,7 +1141,7 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
                return err;
 
        skb_reserve(skb, MAX_PHONET_HEADER + 3 + pn->aligned);
-       err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+       err = memcpy_from_msg(skb_put(skb, len), msg, len);
        if (err < 0)
                goto outfree;
 
index 7280ab8..c36d713 100644 (file)
@@ -316,8 +316,7 @@ int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic);
 void rds_ib_recv_free_caches(struct rds_ib_connection *ic);
 void rds_ib_recv_refill(struct rds_connection *conn, int prefill);
 void rds_ib_inc_free(struct rds_incoming *inc);
-int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
-                            size_t size);
+int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
 void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context);
 void rds_ib_recv_tasklet_fn(unsigned long data);
 void rds_ib_recv_init_ring(struct rds_ib_connection *ic);
index d67de45..1b981a4 100644 (file)
@@ -472,15 +472,12 @@ static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache
        return head;
 }
 
-int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
-                           size_t size)
+int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
 {
        struct rds_ib_incoming *ibinc;
        struct rds_page_frag *frag;
-       struct iovec *iov = first_iov;
        unsigned long to_copy;
        unsigned long frag_off = 0;
-       unsigned long iov_off = 0;
        int copied = 0;
        int ret;
        u32 len;
@@ -489,37 +486,25 @@ int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
        frag = list_entry(ibinc->ii_frags.next, struct rds_page_frag, f_item);
        len = be32_to_cpu(inc->i_hdr.h_len);
 
-       while (copied < size && copied < len) {
+       while (iov_iter_count(to) && copied < len) {
                if (frag_off == RDS_FRAG_SIZE) {
                        frag = list_entry(frag->f_item.next,
                                          struct rds_page_frag, f_item);
                        frag_off = 0;
                }
-               while (iov_off == iov->iov_len) {
-                       iov_off = 0;
-                       iov++;
-               }
-
-               to_copy = min(iov->iov_len - iov_off, RDS_FRAG_SIZE - frag_off);
-               to_copy = min_t(size_t, to_copy, size - copied);
+               to_copy = min_t(unsigned long, iov_iter_count(to),
+                               RDS_FRAG_SIZE - frag_off);
                to_copy = min_t(unsigned long, to_copy, len - copied);
 
-               rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag "
-                        "[%p, %u] + %lu\n",
-                        to_copy, iov->iov_base, iov->iov_len, iov_off,
-                        sg_page(&frag->f_sg), frag->f_sg.offset, frag_off);
-
                /* XXX needs + offset for multiple recvs per page */
-               ret = rds_page_copy_to_user(sg_page(&frag->f_sg),
-                                           frag->f_sg.offset + frag_off,
-                                           iov->iov_base + iov_off,
-                                           to_copy);
-               if (ret) {
-                       copied = ret;
-                       break;
-               }
+               rds_stats_add(s_copy_to_user, to_copy);
+               ret = copy_page_to_iter(sg_page(&frag->f_sg),
+                                       frag->f_sg.offset + frag_off,
+                                       to_copy,
+                                       to);
+               if (ret != to_copy)
+                       return -EFAULT;
 
-               iov_off += to_copy;
                frag_off += to_copy;
                copied += to_copy;
        }
index 04ce3b1..cbe6674 100644 (file)
@@ -325,8 +325,7 @@ int rds_iw_recv(struct rds_connection *conn);
 int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp,
                       gfp_t page_gfp, int prefill);
 void rds_iw_inc_free(struct rds_incoming *inc);
-int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
-                            size_t size);
+int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
 void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context);
 void rds_iw_recv_tasklet_fn(unsigned long data);
 void rds_iw_recv_init_ring(struct rds_iw_connection *ic);
index aa8bf67..a66d179 100644 (file)
@@ -303,15 +303,12 @@ void rds_iw_inc_free(struct rds_incoming *inc)
        BUG_ON(atomic_read(&rds_iw_allocation) < 0);
 }
 
-int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
-                           size_t size)
+int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
 {
        struct rds_iw_incoming *iwinc;
        struct rds_page_frag *frag;
-       struct iovec *iov = first_iov;
        unsigned long to_copy;
        unsigned long frag_off = 0;
-       unsigned long iov_off = 0;
        int copied = 0;
        int ret;
        u32 len;
@@ -320,37 +317,25 @@ int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
        frag = list_entry(iwinc->ii_frags.next, struct rds_page_frag, f_item);
        len = be32_to_cpu(inc->i_hdr.h_len);
 
-       while (copied < size && copied < len) {
+       while (iov_iter_count(to) && copied < len) {
                if (frag_off == RDS_FRAG_SIZE) {
                        frag = list_entry(frag->f_item.next,
                                          struct rds_page_frag, f_item);
                        frag_off = 0;
                }
-               while (iov_off == iov->iov_len) {
-                       iov_off = 0;
-                       iov++;
-               }
-
-               to_copy = min(iov->iov_len - iov_off, RDS_FRAG_SIZE - frag_off);
-               to_copy = min_t(size_t, to_copy, size - copied);
+               to_copy = min_t(unsigned long, iov_iter_count(to),
+                               RDS_FRAG_SIZE - frag_off);
                to_copy = min_t(unsigned long, to_copy, len - copied);
 
-               rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag "
-                        "[%p, %lu] + %lu\n",
-                        to_copy, iov->iov_base, iov->iov_len, iov_off,
-                        frag->f_page, frag->f_offset, frag_off);
-
                /* XXX needs + offset for multiple recvs per page */
-               ret = rds_page_copy_to_user(frag->f_page,
-                                           frag->f_offset + frag_off,
-                                           iov->iov_base + iov_off,
-                                           to_copy);
-               if (ret) {
-                       copied = ret;
-                       break;
-               }
+               rds_stats_add(s_copy_to_user, to_copy);
+               ret = copy_page_to_iter(frag->f_page,
+                                       frag->f_offset + frag_off,
+                                       to_copy,
+                                       to);
+               if (ret != to_copy)
+                       return -EFAULT;
 
-               iov_off += to_copy;
                frag_off += to_copy;
                copied += to_copy;
        }
index aba232f..ff22022 100644 (file)
@@ -264,75 +264,54 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
        return rm;
 }
 
-int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov,
-                                              size_t total_len)
+int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from)
 {
        unsigned long to_copy;
-       unsigned long iov_off;
        unsigned long sg_off;
-       struct iovec *iov;
        struct scatterlist *sg;
        int ret = 0;
 
-       rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len);
+       rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from));
 
        /*
         * now allocate and copy in the data payload.
         */
        sg = rm->data.op_sg;
-       iov = first_iov;
-       iov_off = 0;
        sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */
 
-       while (total_len) {
+       while (iov_iter_count(from)) {
                if (!sg_page(sg)) {
-                       ret = rds_page_remainder_alloc(sg, total_len,
+                       ret = rds_page_remainder_alloc(sg, iov_iter_count(from),
                                                       GFP_HIGHUSER);
                        if (ret)
-                               goto out;
+                               return ret;
                        rm->data.op_nents++;
                        sg_off = 0;
                }
 
-               while (iov_off == iov->iov_len) {
-                       iov_off = 0;
-                       iov++;
-               }
-
-               to_copy = min(iov->iov_len - iov_off, sg->length - sg_off);
-               to_copy = min_t(size_t, to_copy, total_len);
-
-               rdsdebug("copying %lu bytes from user iov [%p, %zu] + %lu to "
-                        "sg [%p, %u, %u] + %lu\n",
-                        to_copy, iov->iov_base, iov->iov_len, iov_off,
-                        (void *)sg_page(sg), sg->offset, sg->length, sg_off);
+               to_copy = min_t(unsigned long, iov_iter_count(from),
+                               sg->length - sg_off);
 
-               ret = rds_page_copy_from_user(sg_page(sg), sg->offset + sg_off,
-                                             iov->iov_base + iov_off,
-                                             to_copy);
-               if (ret)
-                       goto out;
+               rds_stats_add(s_copy_from_user, to_copy);
+               ret = copy_page_from_iter(sg_page(sg), sg->offset + sg_off,
+                                         to_copy, from);
+               if (ret != to_copy)
+                       return -EFAULT;
 
-               iov_off += to_copy;
-               total_len -= to_copy;
                sg_off += to_copy;
 
                if (sg_off == sg->length)
                        sg++;
        }
 
-out:
        return ret;
 }
 
-int rds_message_inc_copy_to_user(struct rds_incoming *inc,
-                                struct iovec *first_iov, size_t size)
+int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
 {
        struct rds_message *rm;
-       struct iovec *iov;
        struct scatterlist *sg;
        unsigned long to_copy;
-       unsigned long iov_off;
        unsigned long vec_off;
        int copied;
        int ret;
@@ -341,36 +320,20 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc,
        rm = container_of(inc, struct rds_message, m_inc);
        len = be32_to_cpu(rm->m_inc.i_hdr.h_len);
 
-       iov = first_iov;
-       iov_off = 0;
        sg = rm->data.op_sg;
        vec_off = 0;
        copied = 0;
 
-       while (copied < size && copied < len) {
-               while (iov_off == iov->iov_len) {
-                       iov_off = 0;
-                       iov++;
-               }
-
-               to_copy = min(iov->iov_len - iov_off, sg->length - vec_off);
-               to_copy = min_t(size_t, to_copy, size - copied);
+       while (iov_iter_count(to) && copied < len) {
+               to_copy = min(iov_iter_count(to), sg->length - vec_off);
                to_copy = min_t(unsigned long, to_copy, len - copied);
 
-               rdsdebug("copying %lu bytes to user iov [%p, %zu] + %lu to "
-                        "sg [%p, %u, %u] + %lu\n",
-                        to_copy, iov->iov_base, iov->iov_len, iov_off,
-                        sg_page(sg), sg->offset, sg->length, vec_off);
-
-               ret = rds_page_copy_to_user(sg_page(sg), sg->offset + vec_off,
-                                           iov->iov_base + iov_off,
-                                           to_copy);
-               if (ret) {
-                       copied = ret;
-                       break;
-               }
+               rds_stats_add(s_copy_to_user, to_copy);
+               ret = copy_page_to_iter(sg_page(sg), sg->offset + vec_off,
+                                       to_copy, to);
+               if (ret != to_copy)
+                       return -EFAULT;
 
-               iov_off += to_copy;
                vec_off += to_copy;
                copied += to_copy;
 
index 48f8ffc..c2a5eef 100644 (file)
@@ -431,8 +431,7 @@ struct rds_transport {
        int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op);
        int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op);
        int (*recv)(struct rds_connection *conn);
-       int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov,
-                               size_t size);
+       int (*inc_copy_to_user)(struct rds_incoming *inc, struct iov_iter *to);
        void (*inc_free)(struct rds_incoming *inc);
 
        int (*cm_handle_connect)(struct rdma_cm_id *cm_id,
@@ -657,8 +656,7 @@ rds_conn_connecting(struct rds_connection *conn)
 /* message.c */
 struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp);
 struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents);
-int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov,
-                                              size_t total_len);
+int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from);
 struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len);
 void rds_message_populate_header(struct rds_header *hdr, __be16 sport,
                                 __be16 dport, u64 seq);
@@ -667,8 +665,7 @@ int rds_message_add_extension(struct rds_header *hdr,
 int rds_message_next_extension(struct rds_header *hdr,
                               unsigned int *pos, void *buf, unsigned int *buflen);
 int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset);
-int rds_message_inc_copy_to_user(struct rds_incoming *inc,
-                                struct iovec *first_iov, size_t size);
+int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
 void rds_message_inc_free(struct rds_incoming *inc);
 void rds_message_addref(struct rds_message *rm);
 void rds_message_put(struct rds_message *rm);
index bd82522..47d7b10 100644 (file)
@@ -404,6 +404,7 @@ 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);
@@ -449,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));
-               ret = inc->i_conn->c_trans->inc_copy_to_user(inc, msg->msg_iov,
-                                                            size);
+               iov_iter_init(&to, READ, msg->msg_iov, msg->msg_iovlen, size);
+               ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &to);
                if (ret < 0)
                        break;
 
index 0a64541..4de62ea 100644 (file)
@@ -934,7 +934,9 @@ 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)) {
@@ -982,7 +984,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
                        ret = -ENOMEM;
                        goto out;
                }
-               ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len);
+               ret = rds_message_copy_from_user(rm, &from);
                if (ret)
                        goto out;
        }
index 6563749..0dbdd37 100644 (file)
@@ -69,8 +69,7 @@ void rds_tcp_recv_exit(void);
 void rds_tcp_data_ready(struct sock *sk);
 int rds_tcp_recv(struct rds_connection *conn);
 void rds_tcp_inc_free(struct rds_incoming *inc);
-int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
-                            size_t size);
+int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
 
 /* tcp_send.c */
 void rds_tcp_xmit_prepare(struct rds_connection *conn);
index 9ae6e0a..fbc5ef8 100644 (file)
@@ -59,50 +59,30 @@ void rds_tcp_inc_free(struct rds_incoming *inc)
 /*
  * this is pretty lame, but, whatever.
  */
-int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
-                            size_t size)
+int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
 {
        struct rds_tcp_incoming *tinc;
-       struct iovec *iov, tmp;
        struct sk_buff *skb;
-       unsigned long to_copy, skb_off;
        int ret = 0;
 
-       if (size == 0)
+       if (!iov_iter_count(to))
                goto out;
 
        tinc = container_of(inc, struct rds_tcp_incoming, ti_inc);
-       iov = first_iov;
-       tmp = *iov;
 
        skb_queue_walk(&tinc->ti_skb_list, skb) {
-               skb_off = 0;
-               while (skb_off < skb->len) {
-                       while (tmp.iov_len == 0) {
-                               iov++;
-                               tmp = *iov;
-                       }
-
-                       to_copy = min(tmp.iov_len, size);
+               unsigned long to_copy, skb_off;
+               for (skb_off = 0; skb_off < skb->len; skb_off += to_copy) {
+                       to_copy = iov_iter_count(to);
                        to_copy = min(to_copy, skb->len - skb_off);
 
-                       rdsdebug("ret %d size %zu skb %p skb_off %lu "
-                                "skblen %d iov_base %p iov_len %zu cpy %lu\n",
-                                ret, size, skb, skb_off, skb->len,
-                                tmp.iov_base, tmp.iov_len, to_copy);
-
-                       /* modifies tmp as it copies */
-                       if (skb_copy_datagram_iovec(skb, skb_off, &tmp,
-                                                   to_copy)) {
-                               ret = -EFAULT;
-                               goto out;
-                       }
+                       if (skb_copy_datagram_iter(skb, skb_off, to, to_copy))
+                               return -EFAULT;
 
                        rds_stats_add(s_copy_to_user, to_copy);
-                       size -= to_copy;
                        ret += to_copy;
-                       skb_off += to_copy;
-                       if (size == 0)
+
+                       if (!iov_iter_count(to))
                                goto out;
                }
        }
index 9b600c2..43bac7c 100644 (file)
@@ -1121,7 +1121,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,
        skb_reset_transport_header(skb);
        skb_put(skb, len);
 
-       err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+       err = memcpy_from_msg(skb_transport_header(skb), msg, len);
        if (err) {
                kfree_skb(skb);
                return err;
index 158701d..a338091 100644 (file)
@@ -164,7 +164,7 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu
  */
 struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                                            struct sctp_sndrcvinfo *sinfo,
-                                           struct msghdr *msgh, int msg_len)
+                                           struct iov_iter *from)
 {
        int max, whole, i, offset, over, err;
        int len, first_len;
@@ -172,6 +172,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
        struct sctp_chunk *chunk;
        struct sctp_datamsg *msg;
        struct list_head *pos, *temp;
+       size_t msg_len = iov_iter_count(from);
        __u8 frag;
 
        msg = sctp_datamsg_new(GFP_KERNEL);
@@ -279,12 +280,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                        goto errout;
                }
 
-               err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov);
+               err = sctp_user_addto_chunk(chunk, len, from);
                if (err < 0)
                        goto errout_chunk_free;
 
-               offset += len;
-
                /* Put the chunk->skb back into the form expected by send.  */
                __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr
                           - (__u8 *)chunk->skb->data);
@@ -317,7 +316,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                        goto errout;
                }
 
-               err = sctp_user_addto_chunk(chunk, offset, over, msgh->msg_iov);
+               err = sctp_user_addto_chunk(chunk, over, from);
 
                /* Put the chunk->skb back into the form expected by send.  */
                __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr
index 9f32741..e49e231 100644 (file)
@@ -1001,7 +1001,7 @@ no_mem:
 
 /* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error.  */
 struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
-                                       const struct msghdr *msg,
+                                       struct msghdr *msg,
                                        size_t paylen)
 {
        struct sctp_chunk *retval;
@@ -1018,7 +1018,7 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
                if (!payload)
                        goto err_payload;
 
-               err = memcpy_fromiovec(payload, msg->msg_iov, paylen);
+               err = memcpy_from_msg(payload, msg, paylen);
                if (err < 0)
                        goto err_copy;
        }
@@ -1491,26 +1491,26 @@ static void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk,
  * chunk is not big enough.
  * Returns a kernel err value.
  */
-int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len,
-                         struct iovec *data)
+int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len,
+                         struct iov_iter *from)
 {
-       __u8 *target;
-       int err = 0;
+       void *target;
+       ssize_t copied;
 
        /* Make room in chunk for data.  */
        target = skb_put(chunk->skb, len);
 
        /* Copy data (whole iovec) into chunk */
-       if ((err = memcpy_fromiovecend(target, data, off, len)))
-               goto out;
+       copied = copy_from_iter(target, len, from);
+       if (copied != len)
+               return -EFAULT;
 
        /* Adjust the chunk length field.  */
        chunk->chunk_hdr->length =
                htons(ntohs(chunk->chunk_hdr->length) + len);
        chunk->chunk_end = skb_tail_pointer(chunk->skb);
 
-out:
-       return err;
+       return 0;
 }
 
 /* Helper function to assign a TSN if needed.  This assumes that both
index 85e0b65..0397ac9 100644 (file)
@@ -1609,6 +1609,9 @@ 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);
@@ -1947,7 +1950,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, msg, msg_len);
+       datamsg = sctp_datamsg_from_user(asoc, sinfo, &from);
        if (IS_ERR(datamsg)) {
                err = PTR_ERR(datamsg);
                goto out_free;
index ec18076..9155496 100644 (file)
@@ -162,14 +162,14 @@ err:
 /**
  * tipc_msg_build - create buffer chain containing specified header and data
  * @mhdr: Message header, to be prepended to data
- * @iov: User data
+ * @m: User message
  * @offset: Posision in iov to start copying from
  * @dsz: Total length of user data
  * @pktmax: Max packet size that can be used
  * @chain: Buffer or chain of buffers to be returned to caller
  * Returns message data size or errno: -ENOMEM, -EFAULT
  */
-int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
+int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
                   int offset, int dsz, int pktmax , struct sk_buff **chain)
 {
        int mhsz = msg_hdr_sz(mhdr);
@@ -194,7 +194,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
                skb_copy_to_linear_data(buf, mhdr, mhsz);
                pktpos = buf->data + mhsz;
                TIPC_SKB_CB(buf)->chain_sz = 1;
-               if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz))
+               if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, dsz))
                        return dsz;
                rc = -EFAULT;
                goto error;
@@ -223,7 +223,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
                if (drem < pktrem)
                        pktrem = drem;
 
-               if (memcpy_fromiovecend(pktpos, iov, offset, pktrem)) {
+               if (memcpy_fromiovecend(pktpos, m->msg_iov, offset, pktrem)) {
                        rc = -EFAULT;
                        goto error;
                }
index 0ea7b69..d7d2ba2 100644 (file)
@@ -743,7 +743,7 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu);
 
 bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode);
 
-int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
+int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
                   int offset, int dsz, int mtu , struct sk_buff **chain);
 
 struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain);
index 6aa8c6a..341fbd1 100644 (file)
@@ -700,7 +700,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
  * tipc_sendmcast - send multicast message
  * @sock: socket structure
  * @seq: destination address
- * @iov: message data to send
+ * @msg: message to send
  * @dsz: total length of message data
  * @timeo: timeout to wait for wakeup
  *
@@ -708,7 +708,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
  * Returns the number of bytes sent on success, or errno
  */
 static int tipc_sendmcast(struct  socket *sock, struct tipc_name_seq *seq,
-                         struct iovec *iov, size_t dsz, long timeo)
+                         struct msghdr *msg, size_t dsz, long timeo)
 {
        struct sock *sk = sock->sk;
        struct tipc_msg *mhdr = &tipc_sk(sk)->phdr;
@@ -727,7 +727,7 @@ static int tipc_sendmcast(struct  socket *sock, struct tipc_name_seq *seq,
 
 new_mtu:
        mtu = tipc_bclink_get_mtu();
-       rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf);
+       rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &buf);
        if (unlikely(rc < 0))
                return rc;
 
@@ -905,7 +905,6 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct tipc_sock *tsk = tipc_sk(sk);
        struct tipc_msg *mhdr = &tsk->phdr;
-       struct iovec *iov = m->msg_iov;
        u32 dnode, dport;
        struct sk_buff *buf;
        struct tipc_name_seq *seq = &dest->addr.nameseq;
@@ -951,7 +950,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
        timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
 
        if (dest->addrtype == TIPC_ADDR_MCAST) {
-               rc = tipc_sendmcast(sock, seq, iov, dsz, timeo);
+               rc = tipc_sendmcast(sock, seq, m, dsz, timeo);
                goto exit;
        } else if (dest->addrtype == TIPC_ADDR_NAME) {
                u32 type = dest->addr.name.name.type;
@@ -982,7 +981,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
 
 new_mtu:
        mtu = tipc_node_get_mtu(dnode, tsk->ref);
-       rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf);
+       rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &buf);
        if (rc < 0)
                goto exit;
 
@@ -1094,7 +1093,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
 next:
        mtu = tsk->max_pkt;
        send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
-       rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf);
+       rc = tipc_msg_build(mhdr, m, sent, send, mtu, &buf);
        if (unlikely(rc < 0))
                goto exit;
        do {
index 5eee625..4450d62 100644 (file)
@@ -1459,6 +1459,9 @@ 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;
@@ -1516,7 +1519,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_iovec(skb, 0, msg->msg_iov, 0, len);
+       err = skb_copy_datagram_from_iter(skb, 0, &from, len);
        if (err)
                goto out_free;
 
@@ -1638,6 +1641,9 @@ 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;
@@ -1694,8 +1700,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_iovec(skb, 0, msg->msg_iov,
-                                                  sent, size);
+               err = skb_copy_datagram_from_iter(skb, 0, &from, size);
                if (err) {
                        kfree_skb(skb);
                        goto out_err;
index 85d232b..1d0e39c 100644 (file)
@@ -1013,7 +1013,7 @@ static int vsock_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
                goto out;
        }
 
-       err = transport->dgram_enqueue(vsk, remote_addr, msg->msg_iov, len);
+       err = transport->dgram_enqueue(vsk, remote_addr, msg, len);
 
 out:
        release_sock(sk);
@@ -1617,7 +1617,7 @@ static int vsock_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                 */
 
                written = transport->stream_enqueue(
-                               vsk, msg->msg_iov,
+                               vsk, msg,
                                len - total_written);
                if (written < 0) {
                        err = -ENOMEM;
@@ -1739,7 +1739,7 @@ vsock_stream_recvmsg(struct kiocb *kiocb,
                                break;
 
                        read = transport->stream_dequeue(
-                                       vsk, msg->msg_iov,
+                                       vsk, msg,
                                        len - copied, flags);
                        if (read < 0) {
                                err = -ENOMEM;
index a57ddef..c1c0389 100644 (file)
@@ -1697,7 +1697,7 @@ static int vmci_transport_dgram_bind(struct vsock_sock *vsk,
 static int vmci_transport_dgram_enqueue(
        struct vsock_sock *vsk,
        struct sockaddr_vm *remote_addr,
-       struct iovec *iov,
+       struct msghdr *msg,
        size_t len)
 {
        int err;
@@ -1714,7 +1714,7 @@ static int vmci_transport_dgram_enqueue(
        if (!dg)
                return -ENOMEM;
 
-       memcpy_fromiovec(VMCI_DG_PAYLOAD(dg), iov, len);
+       memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len);
 
        dg->dst = vmci_make_handle(remote_addr->svm_cid,
                                   remote_addr->svm_port);
@@ -1835,22 +1835,22 @@ static int vmci_transport_connect(struct vsock_sock *vsk)
 
 static ssize_t vmci_transport_stream_dequeue(
        struct vsock_sock *vsk,
-       struct iovec *iov,
+       struct msghdr *msg,
        size_t len,
        int flags)
 {
        if (flags & MSG_PEEK)
-               return vmci_qpair_peekv(vmci_trans(vsk)->qpair, iov, len, 0);
+               return vmci_qpair_peekv(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0);
        else
-               return vmci_qpair_dequev(vmci_trans(vsk)->qpair, iov, len, 0);
+               return vmci_qpair_dequev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0);
 }
 
 static ssize_t vmci_transport_stream_enqueue(
        struct vsock_sock *vsk,
-       struct iovec *iov,
+       struct msghdr *msg,
        size_t len)
 {
-       return vmci_qpair_enquev(vmci_trans(vsk)->qpair, iov, len, 0);
+       return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0);
 }
 
 static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk)
index 59e785b..d9149b6 100644 (file)
@@ -1170,7 +1170,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
        skb_reset_transport_header(skb);
        skb_put(skb, len);
 
-       rc = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len);
+       rc = memcpy_from_msg(skb_transport_header(skb), msg, len);
        if (rc)
                goto out_kfree_skb;