aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2021-03-04 21:02:58 -0700
committerJens Axboe <axboe@kernel.dk>2021-03-05 08:43:09 -0700
commitb5b0ecb736f1ce1e68eb50613c0cfecff10198eb (patch)
tree2bbe77a9b47c89fa01c46e198e0bcafbfe1e00b1
parentca0a26511c679a797f86589894a4523db36d833e (diff)
downloadlinux-b5b0ecb736f1ce1e68eb50613c0cfecff10198eb.tar.gz
io_uring: clear IOCB_WAITQ for non -EIOCBQUEUED return
The callback can only be armed, if we get -EIOCBQUEUED returned. It's important that we clear the WAITQ bit for other cases, otherwise we can queue for async retry and filemap will assume that we're armed and return -EAGAIN instead of just blocking for the IO. Cc: stable@vger.kernel.org # 5.9+ Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--fs/io_uring.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 044170165402f0..5762750c666c6f 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -3286,6 +3286,7 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags)
if (ret == -EIOCBQUEUED)
return 0;
/* we got some bytes, but not all. retry. */
+ kiocb->ki_flags &= ~IOCB_WAITQ;
} while (ret > 0 && ret < io_size);
done:
kiocb_done(kiocb, ret, issue_flags);