One case was missed in the short IO retry handling, and that's hitting -EAGAIN on a blocking attempt read (eg from io-wq context). This is a problem on sockets that are marked as non-blocking when created, they don't carry any REQ_F_NOWAIT information to help us terminate them instead of perpetually retrying.
Unified · Split
| @@ -3186,6 +3186,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock, · 3185 unmodified lines | ||
| 3186 | 3186 | ret = 0; |
| 3187 | 3187 | goto out_free; |
| 3188 | 3188 | } else if (ret == -EAGAIN) { |
| 3189 | + if (!force_nonblock) | |
| 3190 | + goto done; | |
| 3189 | 3191 | ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false); |
| 3190 | 3192 | if (ret) |
| 3191 | 3193 | goto out_free; |
| @@ -3195,7 +3197,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock, · 3 unmodified lines | ||
| 3195 | 3197 | } |
| 3196 | 3198 | |
| 3197 | 3199 | /* read it all, or we did blocking attempt. no retry. */ |
| 3198 | − if (!iov_iter_count(iter) || !force_nonblock) | |
| 3200 | + if (!iov_iter_count(iter) || !force_nonblock || | |
| 3201 | + (req->file->f_flags & O_NONBLOCK)) | |
| 3199 | 3202 | goto done; |
| 3200 | 3203 | |
| 3201 | 3204 | io_size -= ret; |