Skip to content

Commit

Permalink
io_uring: never call io_buffer_select() for a buffer re-select
Browse files Browse the repository at this point in the history
Callers already have room to store the addr and length information,
clean it up by having the caller just assign the previously provided
data.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Jens Axboe committed May 9, 2022
1 parent 9cfc7e9 commit b66e65f
Showing 1 changed file with 17 additions and 12 deletions.
29 changes: 17 additions & 12 deletions fs/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -3455,9 +3455,6 @@ static void __user *io_buffer_select(struct io_kiocb *req, size_t *len,
struct io_ring_ctx *ctx = req->ctx;
struct io_buffer_list *bl;

if (req->flags & REQ_F_BUFFER_SELECTED)
return u64_to_user_ptr(kbuf->addr);

io_ring_submit_lock(req->ctx, issue_flags);

bl = io_buffer_get_list(ctx, req->buf_index);
Expand Down Expand Up @@ -3497,8 +3494,9 @@ static ssize_t io_compat_import(struct io_kiocb *req, struct iovec *iov,
buf = io_buffer_select(req, &len, issue_flags);
if (IS_ERR(buf))
return PTR_ERR(buf);
req->rw.addr = (unsigned long) buf;
iov[0].iov_base = buf;
iov[0].iov_len = (compat_size_t) len;
req->rw.len = iov[0].iov_len = (compat_size_t) len;
return 0;
}
#endif
Expand All @@ -3519,19 +3517,18 @@ static ssize_t __io_iov_buffer_select(struct io_kiocb *req, struct iovec *iov,
buf = io_buffer_select(req, &len, issue_flags);
if (IS_ERR(buf))
return PTR_ERR(buf);
req->rw.addr = (unsigned long) buf;
iov[0].iov_base = buf;
iov[0].iov_len = len;
req->rw.len = iov[0].iov_len = len;
return 0;
}

static ssize_t io_iov_buffer_select(struct io_kiocb *req, struct iovec *iov,
unsigned int issue_flags)
{
if (req->flags & REQ_F_BUFFER_SELECTED) {
struct io_buffer *kbuf = req->kbuf;

iov[0].iov_base = u64_to_user_ptr(kbuf->addr);
iov[0].iov_len = kbuf->len;
iov[0].iov_base = u64_to_user_ptr(req->rw.addr);
iov[0].iov_len = req->rw.len;
return 0;
}
if (req->rw.len != 1)
Expand All @@ -3545,6 +3542,13 @@ static ssize_t io_iov_buffer_select(struct io_kiocb *req, struct iovec *iov,
return __io_iov_buffer_select(req, iov, issue_flags);
}

static inline bool io_do_buffer_select(struct io_kiocb *req)
{
if (!(req->flags & REQ_F_BUFFER_SELECT))
return false;
return !(req->flags & REQ_F_BUFFER_SELECTED);
}

static struct iovec *__io_import_iovec(int rw, struct io_kiocb *req,
struct io_rw_state *s,
unsigned int issue_flags)
Expand All @@ -3567,10 +3571,11 @@ static struct iovec *__io_import_iovec(int rw, struct io_kiocb *req,
sqe_len = req->rw.len;

if (opcode == IORING_OP_READ || opcode == IORING_OP_WRITE) {
if (req->flags & REQ_F_BUFFER_SELECT) {
if (io_do_buffer_select(req)) {
buf = io_buffer_select(req, &sqe_len, issue_flags);
if (IS_ERR(buf))
return ERR_CAST(buf);
req->rw.addr = (unsigned long) buf;
req->rw.len = sqe_len;
}

Expand Down Expand Up @@ -5555,7 +5560,7 @@ static int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)
(sr->flags & IORING_RECVSEND_POLL_FIRST))
return io_setup_async_msg(req, kmsg);

if (req->flags & REQ_F_BUFFER_SELECT) {
if (io_do_buffer_select(req)) {
void __user *buf;

buf = io_buffer_select(req, &sr->len, issue_flags);
Expand Down Expand Up @@ -5619,7 +5624,7 @@ static int io_recv(struct io_kiocb *req, unsigned int issue_flags)
if (unlikely(!sock))
return -ENOTSOCK;

if (req->flags & REQ_F_BUFFER_SELECT) {
if (io_do_buffer_select(req)) {
void __user *buf;

buf = io_buffer_select(req, &sr->len, issue_flags);
Expand Down

0 comments on commit b66e65f

Please sign in to comment.