aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2020-03-04 08:09:07 -0700
committerJens Axboe <axboe@kernel.dk>2020-03-04 13:11:27 -0700
commit815e0a20fc997d3c29be16f10c5b6c7a7ff55e1b (patch)
tree814e4273d8e318418cae355535a774a05f475b51
parent6a91ef5209d770ec01c5e9005182e66ff5f333d5 (diff)
downloadlinux-block-io_uring-fd-select.tar.gz
io_uring: allow specific fd for IORING_OP_ACCEPTio_uring-fd-select
sqe->len can be set to a specific fd we want to use for accept4(), so it uses that one instead of just assigning a free unused one. Reviewed-by: Josh Triplett <josh@joshtriplett.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--fs/io_uring.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 14e779f1a292b9..5c9b97c06fdf86 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -354,6 +354,7 @@ struct io_accept {
struct sockaddr __user *addr;
int __user *addr_len;
int flags;
+ int open_fd;
};
struct io_sync {
@@ -3917,12 +3918,15 @@ static int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL)))
return -EINVAL;
- if (sqe->ioprio || sqe->len || sqe->buf_index)
+ if (sqe->ioprio || sqe->buf_index)
return -EINVAL;
accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));
accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2));
accept->flags = READ_ONCE(sqe->accept_flags);
+ accept->open_fd = READ_ONCE(sqe->len);
+ if (!(accept->flags & SOCK_SPECIFIC_FD) && accept->open_fd)
+ return -EINVAL;
return 0;
}
@@ -3934,7 +3938,8 @@ static int __io_accept(struct io_kiocb *req, bool force_nonblock)
file_flags = force_nonblock ? O_NONBLOCK : 0;
ret = __sys_accept4_file(req->file, file_flags, accept->addr,
- accept->addr_len, accept->flags, -1);
+ accept->addr_len, accept->flags,
+ accept->open_fd);
if (ret == -EAGAIN && force_nonblock)
return -EAGAIN;
if (ret == -ERESTARTSYS)