diff options
-rw-r--r-- | io_uring/net.c | 25 | ||||
-rw-r--r-- | io_uring/opdef.c | 1 |
2 files changed, 21 insertions, 5 deletions
diff --git a/io_uring/net.c b/io_uring/net.c index dc310f0bfe4c..13685d133582 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -364,10 +364,12 @@ static int io_send_setup(struct io_kiocb *req) kmsg->msg.msg_name = &kmsg->addr; kmsg->msg.msg_namelen = sr->addr_len; } - ret = import_ubuf(ITER_SOURCE, sr->buf, sr->len, &kmsg->msg.msg_iter); - if (unlikely(ret < 0)) - return ret; - + if (!io_do_buffer_select(req)) { + ret = import_ubuf(ITER_SOURCE, sr->buf, sr->len, + &kmsg->msg.msg_iter); + if (unlikely(ret < 0)) + return ret; + } return 0; } @@ -480,6 +482,7 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags) struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); struct io_async_msghdr *kmsg = req->async_data; struct socket *sock; + unsigned int cflags; unsigned flags; int min_ret = 0; int ret; @@ -492,6 +495,17 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags) (sr->flags & IORING_RECVSEND_POLL_FIRST)) return -EAGAIN; + if (io_do_buffer_select(req)) { + size_t len = sr->len; + void __user *buf; + + buf = io_buffer_select(req, &len, issue_flags); + if (unlikely(!buf)) + return -ENOBUFS; + sr->buf = buf; + sr->len = len; + } + flags = sr->msg_flags; if (issue_flags & IO_URING_F_NONBLOCK) flags |= MSG_DONTWAIT; @@ -521,7 +535,8 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags) else if (sr->done_io) ret = sr->done_io; io_req_msg_cleanup(req, issue_flags); - io_req_set_res(req, ret, 0); + cflags = io_put_kbuf(req, issue_flags); + io_req_set_res(req, ret, cflags); return IOU_OK; } diff --git a/io_uring/opdef.c b/io_uring/opdef.c index a16f73938ebb..2de5cca9504e 100644 --- a/io_uring/opdef.c +++ b/io_uring/opdef.c @@ -281,6 +281,7 @@ const struct io_issue_def io_issue_defs[] = { .pollout = 1, .audit_skip = 1, .ioprio = 1, + .buffer_select = 1, #if defined(CONFIG_NET) .async_size = sizeof(struct io_async_msghdr), .prep = io_sendmsg_prep, |