mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 18:09:56 +00:00
io_uring/net: avoid sending -ECONNABORTED on repeated connection requests
commit74e2e17ee1upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
4481ce2bfa
commit
7bc203584e
@@ -47,6 +47,7 @@ struct io_connect {
|
|||||||
struct sockaddr __user *addr;
|
struct sockaddr __user *addr;
|
||||||
int addr_len;
|
int addr_len;
|
||||||
bool in_progress;
|
bool in_progress;
|
||||||
|
bool seen_econnaborted;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct io_sr_msg {
|
struct io_sr_msg {
|
||||||
@@ -1431,7 +1432,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 = u64_to_user_ptr(READ_ONCE(sqe->addr));
|
||||||
conn->addr_len = READ_ONCE(sqe->addr2);
|
conn->addr_len = READ_ONCE(sqe->addr2);
|
||||||
conn->in_progress = false;
|
conn->in_progress = conn->seen_econnaborted = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1468,18 +1469,24 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
|
|||||||
|
|
||||||
ret = __sys_connect_file(req->file, &io->address,
|
ret = __sys_connect_file(req->file, &io->address,
|
||||||
connect->addr_len, file_flags);
|
connect->addr_len, file_flags);
|
||||||
if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) {
|
if ((ret == -EAGAIN || ret == -EINPROGRESS || ret == -ECONNABORTED)
|
||||||
|
&& force_nonblock) {
|
||||||
if (ret == -EINPROGRESS) {
|
if (ret == -EINPROGRESS) {
|
||||||
connect->in_progress = true;
|
connect->in_progress = true;
|
||||||
} else {
|
return -EAGAIN;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
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;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
if (ret == -ERESTARTSYS)
|
if (ret == -ERESTARTSYS)
|
||||||
|
|||||||
Reference in New Issue
Block a user