Commit 74e2e17e authored by Jens Axboe's avatar Jens Axboe
Browse files

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: 3fb1bd68 ("io_uring/net: handle -EINPROGRESS correct for IORING_OP_CONNECT")
Link: https://github.com/axboe/liburing/issues/828


Reported-by: default avatarHui, Chunyang <sanqian.hcy@antgroup.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent d2acf789
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -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,10 +1462,17 @@ 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 {
			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)) {
@@ -1472,7 +1480,6 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
			goto out;
		}
		memcpy(req->async_data, &__io, sizeof(__io));
		}
		return -EAGAIN;
	}
	if (ret == -ERESTARTSYS)