mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-09-14 11:19:08 +10:00
io_uring/poll: fix POLLERR handling
8c8492ca64
("io_uring/net: don't retry connect operation on EPOLLERR") is a little dirty hack that 1) wrongfully assumes that POLLERR equals to a failed request, which breaks all POLLERR users, e.g. all error queue recv interfaces. 2) deviates the connection request behaviour from connect(2), and 3) racy and solved at a wrong level. Nothing can be done with 2) now, and 3) is beyond the scope of the patch. At least solve 1) by moving the hack out of generic poll handling into io_connect(). Cc: stable@vger.kernel.org Fixes:8c8492ca64
("io_uring/net: don't retry connect operation on EPOLLERR") Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Link: https://lore.kernel.org/r/3dc89036388d602ebd84c28e5042e457bdfc952b.1752682444.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
08ca1409c4
commit
c7cafd5b81
@ -1738,9 +1738,11 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
|
||||
int ret;
|
||||
bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
|
||||
|
||||
if (unlikely(req->flags & REQ_F_FAIL)) {
|
||||
ret = -ECONNRESET;
|
||||
goto out;
|
||||
if (connect->in_progress) {
|
||||
struct poll_table_struct pt = { ._key = EPOLLERR };
|
||||
|
||||
if (vfs_poll(req->file, &pt) & EPOLLERR)
|
||||
goto get_sock_err;
|
||||
}
|
||||
|
||||
file_flags = force_nonblock ? O_NONBLOCK : 0;
|
||||
@ -1765,8 +1767,10 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
|
||||
* which means the previous result is good. For both of these,
|
||||
* grab the sock_error() and use that for the completion.
|
||||
*/
|
||||
if (ret == -EBADFD || ret == -EISCONN)
|
||||
if (ret == -EBADFD || ret == -EISCONN) {
|
||||
get_sock_err:
|
||||
ret = sock_error(sock_from_file(req->file)->sk);
|
||||
}
|
||||
}
|
||||
if (ret == -ERESTARTSYS)
|
||||
ret = -EINTR;
|
||||
|
@ -273,8 +273,6 @@ static int io_poll_check_events(struct io_kiocb *req, io_tw_token_t tw)
|
||||
return IOU_POLL_REISSUE;
|
||||
}
|
||||
}
|
||||
if (unlikely(req->cqe.res & EPOLLERR))
|
||||
req_set_fail(req);
|
||||
if (req->apoll_events & EPOLLONESHOT)
|
||||
return IOU_POLL_DONE;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user