Commit e0eb093e794452791b0f932a0120f410f614ad82
1 parent
8feb2fb2bb
switch sctp_user_addto_chunk() and sctp_datamsg_from_user() to passing iov_iter
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 4 changed files with 19 additions and 17 deletions Side-by-side Diff
include/net/sctp/structs.h
... | ... | @@ -531,7 +531,7 @@ |
531 | 531 | |
532 | 532 | struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, |
533 | 533 | struct sctp_sndrcvinfo *, |
534 | - struct msghdr *, int len); | |
534 | + struct iov_iter *); | |
535 | 535 | void sctp_datamsg_free(struct sctp_datamsg *); |
536 | 536 | void sctp_datamsg_put(struct sctp_datamsg *); |
537 | 537 | void sctp_chunk_fail(struct sctp_chunk *, int error); |
... | ... | @@ -647,8 +647,8 @@ |
647 | 647 | |
648 | 648 | void sctp_chunk_hold(struct sctp_chunk *); |
649 | 649 | void sctp_chunk_put(struct sctp_chunk *); |
650 | -int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, | |
651 | - struct iovec *data); | |
650 | +int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len, | |
651 | + struct iov_iter *from); | |
652 | 652 | void sctp_chunk_free(struct sctp_chunk *); |
653 | 653 | void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); |
654 | 654 | struct sctp_chunk *sctp_chunkify(struct sk_buff *, |
net/sctp/chunk.c
... | ... | @@ -164,7 +164,7 @@ |
164 | 164 | */ |
165 | 165 | struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, |
166 | 166 | struct sctp_sndrcvinfo *sinfo, |
167 | - struct msghdr *msgh, int msg_len) | |
167 | + struct iov_iter *from) | |
168 | 168 | { |
169 | 169 | int max, whole, i, offset, over, err; |
170 | 170 | int len, first_len; |
... | ... | @@ -172,6 +172,7 @@ |
172 | 172 | struct sctp_chunk *chunk; |
173 | 173 | struct sctp_datamsg *msg; |
174 | 174 | struct list_head *pos, *temp; |
175 | + size_t msg_len = iov_iter_count(from); | |
175 | 176 | __u8 frag; |
176 | 177 | |
177 | 178 | msg = sctp_datamsg_new(GFP_KERNEL); |
178 | 179 | |
... | ... | @@ -279,12 +280,10 @@ |
279 | 280 | goto errout; |
280 | 281 | } |
281 | 282 | |
282 | - err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov); | |
283 | + err = sctp_user_addto_chunk(chunk, len, from); | |
283 | 284 | if (err < 0) |
284 | 285 | goto errout_chunk_free; |
285 | 286 | |
286 | - offset += len; | |
287 | - | |
288 | 287 | /* Put the chunk->skb back into the form expected by send. */ |
289 | 288 | __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr |
290 | 289 | - (__u8 *)chunk->skb->data); |
... | ... | @@ -317,7 +316,7 @@ |
317 | 316 | goto errout; |
318 | 317 | } |
319 | 318 | |
320 | - err = sctp_user_addto_chunk(chunk, offset, over, msgh->msg_iov); | |
319 | + err = sctp_user_addto_chunk(chunk, over, from); | |
321 | 320 | |
322 | 321 | /* Put the chunk->skb back into the form expected by send. */ |
323 | 322 | __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr |
net/sctp/sm_make_chunk.c
... | ... | @@ -1491,26 +1491,26 @@ |
1491 | 1491 | * chunk is not big enough. |
1492 | 1492 | * Returns a kernel err value. |
1493 | 1493 | */ |
1494 | -int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, | |
1495 | - struct iovec *data) | |
1494 | +int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len, | |
1495 | + struct iov_iter *from) | |
1496 | 1496 | { |
1497 | - __u8 *target; | |
1498 | - int err = 0; | |
1497 | + void *target; | |
1498 | + ssize_t copied; | |
1499 | 1499 | |
1500 | 1500 | /* Make room in chunk for data. */ |
1501 | 1501 | target = skb_put(chunk->skb, len); |
1502 | 1502 | |
1503 | 1503 | /* Copy data (whole iovec) into chunk */ |
1504 | - if ((err = memcpy_fromiovecend(target, data, off, len))) | |
1505 | - goto out; | |
1504 | + copied = copy_from_iter(target, len, from); | |
1505 | + if (copied != len) | |
1506 | + return -EFAULT; | |
1506 | 1507 | |
1507 | 1508 | /* Adjust the chunk length field. */ |
1508 | 1509 | chunk->chunk_hdr->length = |
1509 | 1510 | htons(ntohs(chunk->chunk_hdr->length) + len); |
1510 | 1511 | chunk->chunk_end = skb_tail_pointer(chunk->skb); |
1511 | 1512 | |
1512 | -out: | |
1513 | - return err; | |
1513 | + return 0; | |
1514 | 1514 | } |
1515 | 1515 | |
1516 | 1516 | /* Helper function to assign a TSN if needed. This assumes that both |
net/sctp/socket.c
... | ... | @@ -1609,7 +1609,10 @@ |
1609 | 1609 | __u16 sinfo_flags = 0; |
1610 | 1610 | long timeo; |
1611 | 1611 | int err; |
1612 | + struct iov_iter from; | |
1612 | 1613 | |
1614 | + iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, msg_len); | |
1615 | + | |
1613 | 1616 | err = 0; |
1614 | 1617 | sp = sctp_sk(sk); |
1615 | 1618 | ep = sp->ep; |
... | ... | @@ -1947,7 +1950,7 @@ |
1947 | 1950 | } |
1948 | 1951 | |
1949 | 1952 | /* Break the message into multiple chunks of maximum size. */ |
1950 | - datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len); | |
1953 | + datamsg = sctp_datamsg_from_user(asoc, sinfo, &from); | |
1951 | 1954 | if (IS_ERR(datamsg)) { |
1952 | 1955 | err = PTR_ERR(datamsg); |
1953 | 1956 | goto out_free; |