io_uring/net: avoid sending -ECONNABORTED on repeated connection requests
Since io_uring does nonblocking connect requests, if we do two repeated
ones without having a listener, the second will get -ECONNABORTED rather
than the expected -ECONNREFUSED. Treat -ECONNABORTED like a normal retry
condition if we're nonblocking, if we haven't already seen it.
Cc: stable@vger.kernel.org
Fixes: 3fb1bd6881
("io_uring/net: handle -EINPROGRESS correct for IORING_OP_CONNECT")
Link: https://github.com/axboe/liburing/issues/828
Reported-by: Hui, Chunyang <sanqian.hcy@antgroup.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Родитель
d2acf78908
Коммит
74e2e17ee1
|
@ -47,6 +47,7 @@ struct io_connect {
|
|||
struct sockaddr __user *addr;
|
||||
int addr_len;
|
||||
bool in_progress;
|
||||
bool seen_econnaborted;
|
||||
};
|
||||
|
||||
struct io_sr_msg {
|
||||
|
@ -1424,7 +1425,7 @@ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
|||
|
||||
conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));
|
||||
conn->addr_len = READ_ONCE(sqe->addr2);
|
||||
conn->in_progress = false;
|
||||
conn->in_progress = conn->seen_econnaborted = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1461,18 +1462,24 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
|
|||
|
||||
ret = __sys_connect_file(req->file, &io->address,
|
||||
connect->addr_len, file_flags);
|
||||
if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) {
|
||||
if ((ret == -EAGAIN || ret == -EINPROGRESS || ret == -ECONNABORTED)
|
||||
&& force_nonblock) {
|
||||
if (ret == -EINPROGRESS) {
|
||||
connect->in_progress = true;
|
||||
} else {
|
||||
if (req_has_async_data(req))
|
||||
return -EAGAIN;
|
||||
if (io_alloc_async_data(req)) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
memcpy(req->async_data, &__io, sizeof(__io));
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (ret == -ECONNABORTED) {
|
||||
if (connect->seen_econnaborted)
|
||||
goto out;
|
||||
connect->seen_econnaborted = true;
|
||||
}
|
||||
if (req_has_async_data(req))
|
||||
return -EAGAIN;
|
||||
if (io_alloc_async_data(req)) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
memcpy(req->async_data, &__io, sizeof(__io));
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (ret == -ERESTARTSYS)
|
||||
|
|
Загрузка…
Ссылка в новой задаче