| @@ -308,6 +308,10 @@ struct io_timeout { · 307 unmodified lines |
| 308 | struct io_timeout_data *data; | 308 | struct io_timeout_data *data; |
| 309 | }; | 309 | }; |
| 310 | | 310 | |
| | 311 | struct io_async_connect { |
| | 312 | struct sockaddr_storage address; |
| | 313 | }; |
| | 314 | |
| 311 | struct io_async_msghdr { | 315 | struct io_async_msghdr { |
| 312 | struct iovec fast_iov[UIO_FASTIOV]; | 316 | struct iovec fast_iov[UIO_FASTIOV]; |
| 313 | struct iovec *iov; | 317 | struct iovec *iov; |
| @@ -327,6 +331,7 @@ struct io_async_ctx { · 13 unmodified lines |
| 327 | union { | 331 | union { |
| 328 | struct io_async_rw rw; | 332 | struct io_async_rw rw; |
| 329 | struct io_async_msghdr msg; | 333 | struct io_async_msghdr msg; |
| | 334 | struct io_async_connect connect; |
| 330 | }; | 335 | }; |
| 331 | }; | 336 | }; |
| 332 | | 337 | |
| @@ -2195,11 +2200,26 @@ static int io_accept(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 1862 unmodified lines |
| 2195 | #endif | 2200 | #endif |
| 2196 | } | 2201 | } |
| 2197 | | 2202 | |
| | 2203 | static int io_connect_prep(struct io_kiocb *req, struct io_async_ctx *io) |
| | 2204 | { |
| | 2205 | #if defined(CONFIG_NET) |
| | 2206 | const struct io_uring_sqe *sqe = req->sqe; |
| | 2207 | struct sockaddr __user *addr; |
| | 2208 | int addr_len; |
| | 2209 | |
| | 2210 | addr = (struct sockaddr __user *) (unsigned long) READ_ONCE(sqe->addr); |
| | 2211 | addr_len = READ_ONCE(sqe->addr2); |
| | 2212 | return move_addr_to_kernel(addr, addr_len, &io->connect.address); |
| | 2213 | #else |
| | 2214 | return 0; |
| | 2215 | #endif |
| | 2216 | } |
| | 2217 | |
| 2198 | static int io_connect(struct io_kiocb *req, const struct io_uring_sqe *sqe, | 2218 | static int io_connect(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| 2199 | struct io_kiocb **nxt, bool force_nonblock) | 2219 | struct io_kiocb **nxt, bool force_nonblock) |
| 2200 | { | 2220 | { |
| 2201 | #if defined(CONFIG_NET) | 2221 | #if defined(CONFIG_NET) |
| 2202 | struct sockaddr __user *addr; | 2222 | struct io_async_ctx __io, *io; |
| 2203 | unsigned file_flags; | 2223 | unsigned file_flags; |
| 2204 | int addr_len, ret; | 2224 | int addr_len, ret; |
| 2205 | | 2225 | |
| @@ -2208,15 +2228,35 @@ static int io_connect(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 2 unmodified lines |
| 2208 | if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->rw_flags) | 2228 | if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->rw_flags) |
| 2209 | return -EINVAL; | 2229 | return -EINVAL; |
| 2210 | | 2230 | |
| 2211 | addr = (struct sockaddr __user *) (unsigned long) READ_ONCE(sqe->addr); | | |
| 2212 | addr_len = READ_ONCE(sqe->addr2); | 2231 | addr_len = READ_ONCE(sqe->addr2); |
| 2213 | file_flags = force_nonblock ? O_NONBLOCK : 0; | 2232 | file_flags = force_nonblock ? O_NONBLOCK : 0; |
| 2214 | | 2233 | |
| 2215 | ret = __sys_connect_file(req->file, addr, addr_len, file_flags); | 2234 | if (req->io) { |
| 2216 | if (ret == -EAGAIN && force_nonblock) | 2235 | io = req->io; |
| | 2236 | } else { |
| | 2237 | ret = io_connect_prep(req, &__io); |
| | 2238 | if (ret) |
| | 2239 | goto out; |
| | 2240 | io = &__io; |
| | 2241 | } |
| | 2242 | |
| | 2243 | ret = __sys_connect_file(req->file, &io->connect.address, addr_len, |
| | 2244 | file_flags); |
| | 2245 | if (ret == -EAGAIN && force_nonblock) { |
| | 2246 | io = kmalloc(sizeof(*io), GFP_KERNEL); |
| | 2247 | if (!io) { |
| | 2248 | ret = -ENOMEM; |
| | 2249 | goto out; |
| | 2250 | } |
| | 2251 | memcpy(&io->connect, &__io.connect, sizeof(io->connect)); |
| | 2252 | req->io = io; |
| | 2253 | memcpy(&io->sqe, req->sqe, sizeof(*req->sqe)); |
| | 2254 | req->sqe = &io->sqe; |
| 2217 | return -EAGAIN; | 2255 | return -EAGAIN; |
| | 2256 | } |
| 2218 | if (ret == -ERESTARTSYS) | 2257 | if (ret == -ERESTARTSYS) |
| 2219 | ret = -EINTR; | 2258 | ret = -EINTR; |
| | 2259 | out: |
| 2220 | if (ret < 0 && (req->flags & REQ_F_LINK)) | 2260 | if (ret < 0 && (req->flags & REQ_F_LINK)) |
| 2221 | req->flags |= REQ_F_FAIL_LINK; | 2261 | req->flags |= REQ_F_FAIL_LINK; |
| 2222 | io_cqring_add_event(req, ret); | 2262 | io_cqring_add_event(req, ret); |
| @@ -2832,6 +2872,9 @@ static int io_req_defer_prep(struct io_kiocb *req, struct io_async_ctx *io) · 609 unmodified lines |
| 2832 | case IORING_OP_RECVMSG: | 2872 | case IORING_OP_RECVMSG: |
| 2833 | ret = io_recvmsg_prep(req, io); | 2873 | ret = io_recvmsg_prep(req, io); |
| 2834 | break; | 2874 | break; |
| | 2875 | case IORING_OP_CONNECT: |
| | 2876 | ret = io_connect_prep(req, io); |
| | 2877 | break; |
| 2835 | default: | 2878 | default: |
| 2836 | req->io = io; | 2879 | req->io = io; |
| 2837 | return 0; | 2880 | return 0; |