io_uring/net: add IORING_ACCEPT_DONTWAIT flag
This allows the caller to perform a non-blocking attempt, similarly to how recvmsg has MSG_DONTWAIT. If set, and we get -EAGAIN on a connection attempt, propagate the result to userspace rather than arm poll and wait for a retry. Suggested-by: Norman Maurer <norman_maurer@apple.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
340f634aa4
commit
7dcc758cca
@ -379,6 +379,7 @@ enum io_uring_op {
|
||||
* accept flags stored in sqe->ioprio
|
||||
*/
|
||||
#define IORING_ACCEPT_MULTISHOT (1U << 0)
|
||||
#define IORING_ACCEPT_DONTWAIT (1U << 1)
|
||||
|
||||
/*
|
||||
* IORING_OP_MSG_RING command types, stored in sqe->addr
|
||||
|
@ -28,6 +28,7 @@ struct io_accept {
|
||||
struct sockaddr __user *addr;
|
||||
int __user *addr_len;
|
||||
int flags;
|
||||
int iou_flags;
|
||||
u32 file_slot;
|
||||
unsigned long nofile;
|
||||
};
|
||||
@ -1489,7 +1490,6 @@ void io_sendrecv_fail(struct io_kiocb *req)
|
||||
int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
{
|
||||
struct io_accept *accept = io_kiocb_to_cmd(req, struct io_accept);
|
||||
unsigned flags;
|
||||
|
||||
if (sqe->len || sqe->buf_index)
|
||||
return -EINVAL;
|
||||
@ -1498,15 +1498,15 @@ int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2));
|
||||
accept->flags = READ_ONCE(sqe->accept_flags);
|
||||
accept->nofile = rlimit(RLIMIT_NOFILE);
|
||||
flags = READ_ONCE(sqe->ioprio);
|
||||
if (flags & ~IORING_ACCEPT_MULTISHOT)
|
||||
accept->iou_flags = READ_ONCE(sqe->ioprio);
|
||||
if (accept->iou_flags & ~(IORING_ACCEPT_MULTISHOT | IORING_ACCEPT_DONTWAIT))
|
||||
return -EINVAL;
|
||||
|
||||
accept->file_slot = READ_ONCE(sqe->file_index);
|
||||
if (accept->file_slot) {
|
||||
if (accept->flags & SOCK_CLOEXEC)
|
||||
return -EINVAL;
|
||||
if (flags & IORING_ACCEPT_MULTISHOT &&
|
||||
if (accept->iou_flags & IORING_ACCEPT_MULTISHOT &&
|
||||
accept->file_slot != IORING_FILE_INDEX_ALLOC)
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1514,8 +1514,10 @@ int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
return -EINVAL;
|
||||
if (SOCK_NONBLOCK != O_NONBLOCK && (accept->flags & SOCK_NONBLOCK))
|
||||
accept->flags = (accept->flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
|
||||
if (flags & IORING_ACCEPT_MULTISHOT)
|
||||
if (accept->iou_flags & IORING_ACCEPT_MULTISHOT)
|
||||
req->flags |= REQ_F_APOLL_MULTISHOT;
|
||||
if (accept->iou_flags & IORING_ACCEPT_DONTWAIT)
|
||||
req->flags |= REQ_F_NOWAIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1540,7 +1542,8 @@ retry:
|
||||
if (!fixed)
|
||||
put_unused_fd(fd);
|
||||
ret = PTR_ERR(file);
|
||||
if (ret == -EAGAIN && force_nonblock) {
|
||||
if (ret == -EAGAIN && force_nonblock &&
|
||||
!(accept->iou_flags & IORING_ACCEPT_DONTWAIT)) {
|
||||
/*
|
||||
* if it's multishot and polled, we don't need to
|
||||
* return EAGAIN to arm the poll infra since it
|
||||
|
Loading…
Reference in New Issue
Block a user