switch sctp_user_addto_chunk() and sctp_datamsg_from_user() to passing iov_iter
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 15 Nov 2014 06:11:23 +0000 (01:11 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 24 Nov 2014 10:16:40 +0000 (05:16 -0500)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
include/net/sctp/structs.h
net/sctp/chunk.c
net/sctp/sm_make_chunk.c
net/sctp/socket.c

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 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 e49bcce..e49e231 100644 (file)
@@ -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;