Commit 9a709b7e authored by Jens Axboe's avatar Jens Axboe
Browse files

io_uring/net: mark iov as dynamically allocated even for single segments



A bigger array of vecs could've been allocated, but
io_ring_buffers_peek() still decided to cap the mapped range depending
on how much data was available. Hence don't rely on the segment count
to know if the request should be marked as needing cleanup, always
check upfront if the iov array is different than the fast_iov array.

Fixes: 26ec15e4 ("io_uring/kbuf: don't truncate end buffer for multiple buffer peeks")
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 7cac633a
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -1077,6 +1077,12 @@ static int io_recv_buf_select(struct io_kiocb *req, struct io_async_msghdr *kmsg
		if (unlikely(ret < 0))
			return ret;

		if (arg.iovs != &kmsg->fast_iov && arg.iovs != kmsg->vec.iovec) {
			kmsg->vec.nr = ret;
			kmsg->vec.iovec = arg.iovs;
			req->flags |= REQ_F_NEED_CLEANUP;
		}

		/* special case 1 vec, can be a fast path */
		if (ret == 1) {
			sr->buf = arg.iovs[0].iov_base;
@@ -1085,11 +1091,6 @@ static int io_recv_buf_select(struct io_kiocb *req, struct io_async_msghdr *kmsg
		}
		iov_iter_init(&kmsg->msg.msg_iter, ITER_DEST, arg.iovs, ret,
				arg.out_len);
		if (arg.iovs != &kmsg->fast_iov && arg.iovs != kmsg->vec.iovec) {
			kmsg->vec.nr = ret;
			kmsg->vec.iovec = arg.iovs;
			req->flags |= REQ_F_NEED_CLEANUP;
		}
	} else {
		void __user *buf;