Loading fs/io_uring.c +37 −0 Original line number Diff line number Diff line Loading @@ -1686,6 +1686,40 @@ static int io_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe, #endif } static int io_accept(struct io_kiocb *req, const struct io_uring_sqe *sqe, struct io_kiocb **nxt, bool force_nonblock) { #if defined(CONFIG_NET) struct sockaddr __user *addr; int __user *addr_len; unsigned file_flags; int flags, ret; if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL))) return -EINVAL; if (sqe->ioprio || sqe->off || sqe->len || sqe->buf_index) return -EINVAL; addr = (struct sockaddr __user *) (unsigned long) READ_ONCE(sqe->addr); addr_len = (int __user *) (unsigned long) READ_ONCE(sqe->addr2); flags = READ_ONCE(sqe->accept_flags); file_flags = force_nonblock ? O_NONBLOCK : 0; ret = __sys_accept4_file(req->file, file_flags, addr, addr_len, flags); if (ret == -EAGAIN && force_nonblock) { req->work.flags |= IO_WQ_WORK_NEEDS_FILES; return -EAGAIN; } if (ret < 0 && (req->flags & REQ_F_LINK)) req->flags |= REQ_F_FAIL_LINK; io_cqring_add_event(req->ctx, sqe->user_data, ret); io_put_req(req, nxt); return 0; #else return -EOPNOTSUPP; #endif } static void io_poll_remove_one(struct io_kiocb *req) { struct io_poll_iocb *poll = &req->poll; Loading Loading @@ -2173,6 +2207,9 @@ static int __io_submit_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, case IORING_OP_TIMEOUT_REMOVE: ret = io_timeout_remove(req, s->sqe); break; case IORING_OP_ACCEPT: ret = io_accept(req, s->sqe, nxt, force_nonblock); break; default: ret = -EINVAL; break; Loading include/uapi/linux/io_uring.h +6 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,10 @@ struct io_uring_sqe { __u8 flags; /* IOSQE_ flags */ __u16 ioprio; /* ioprio for the request */ __s32 fd; /* file descriptor to do IO on */ union { __u64 off; /* offset into file */ __u64 addr2; }; __u64 addr; /* pointer to buffer or iovecs */ __u32 len; /* buffer size or number of iovecs */ union { Loading @@ -29,6 +32,7 @@ struct io_uring_sqe { __u32 sync_range_flags; __u32 msg_flags; __u32 timeout_flags; __u32 accept_flags; }; __u64 user_data; /* data to be passed back at completion time */ union { Loading Loading @@ -65,6 +69,7 @@ struct io_uring_sqe { #define IORING_OP_RECVMSG 10 #define IORING_OP_TIMEOUT 11 #define IORING_OP_TIMEOUT_REMOVE 12 #define IORING_OP_ACCEPT 13 /* * sqe->fsync_flags Loading Loading
fs/io_uring.c +37 −0 Original line number Diff line number Diff line Loading @@ -1686,6 +1686,40 @@ static int io_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe, #endif } static int io_accept(struct io_kiocb *req, const struct io_uring_sqe *sqe, struct io_kiocb **nxt, bool force_nonblock) { #if defined(CONFIG_NET) struct sockaddr __user *addr; int __user *addr_len; unsigned file_flags; int flags, ret; if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL))) return -EINVAL; if (sqe->ioprio || sqe->off || sqe->len || sqe->buf_index) return -EINVAL; addr = (struct sockaddr __user *) (unsigned long) READ_ONCE(sqe->addr); addr_len = (int __user *) (unsigned long) READ_ONCE(sqe->addr2); flags = READ_ONCE(sqe->accept_flags); file_flags = force_nonblock ? O_NONBLOCK : 0; ret = __sys_accept4_file(req->file, file_flags, addr, addr_len, flags); if (ret == -EAGAIN && force_nonblock) { req->work.flags |= IO_WQ_WORK_NEEDS_FILES; return -EAGAIN; } if (ret < 0 && (req->flags & REQ_F_LINK)) req->flags |= REQ_F_FAIL_LINK; io_cqring_add_event(req->ctx, sqe->user_data, ret); io_put_req(req, nxt); return 0; #else return -EOPNOTSUPP; #endif } static void io_poll_remove_one(struct io_kiocb *req) { struct io_poll_iocb *poll = &req->poll; Loading Loading @@ -2173,6 +2207,9 @@ static int __io_submit_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, case IORING_OP_TIMEOUT_REMOVE: ret = io_timeout_remove(req, s->sqe); break; case IORING_OP_ACCEPT: ret = io_accept(req, s->sqe, nxt, force_nonblock); break; default: ret = -EINVAL; break; Loading
include/uapi/linux/io_uring.h +6 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,10 @@ struct io_uring_sqe { __u8 flags; /* IOSQE_ flags */ __u16 ioprio; /* ioprio for the request */ __s32 fd; /* file descriptor to do IO on */ union { __u64 off; /* offset into file */ __u64 addr2; }; __u64 addr; /* pointer to buffer or iovecs */ __u32 len; /* buffer size or number of iovecs */ union { Loading @@ -29,6 +32,7 @@ struct io_uring_sqe { __u32 sync_range_flags; __u32 msg_flags; __u32 timeout_flags; __u32 accept_flags; }; __u64 user_data; /* data to be passed back at completion time */ union { Loading Loading @@ -65,6 +69,7 @@ struct io_uring_sqe { #define IORING_OP_RECVMSG 10 #define IORING_OP_TIMEOUT 11 #define IORING_OP_TIMEOUT_REMOVE 12 #define IORING_OP_ACCEPT 13 /* * sqe->fsync_flags Loading