Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0eb093e authored by Al Viro's avatar Al Viro
Browse files

switch sctp_user_addto_chunk() and sctp_datamsg_from_user() to passing iov_iter



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 8feb2fb2
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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 *,
+4 −5
Original line number Diff line number Diff line
@@ -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
+8 −8
Original line number Diff line number Diff line
@@ -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
+4 −1
Original line number Diff line number Diff line
@@ -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;