* [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
@ 2026-07-20 11:41 Yitang Yang
2026-07-21 16:32 ` Jens Axboe
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Yitang Yang @ 2026-07-20 11:41 UTC (permalink / raw)
To: axboe; +Cc: krisman, io-uring, Yitang Yang
Both read and write may receive internal restart error codes from
the filesystem layer and should be converted to -EINTR. However,
when multishot read support was added, the error code normalization
was lost for both io_read() and io_read_mshot().
Extract the conversion into io_fixup_restart_res() and apply it
in all three locations: io_rw_done(), io_read(), and io_read_mshot().
Fixes: a08d195b586a ("io_uring/rw: split io_read() into a helper")
Signed-off-by: Yitang Yang <yi1tang.yang@gmail.com>
---
io_uring/rw.c | 38 ++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/io_uring/rw.c b/io_uring/rw.c
index 63b6519e498c..e505479e3773 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -615,6 +615,24 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res)
smp_store_release(&req->iopoll_completed, 1);
}
+static inline ssize_t io_fixup_restart_res(ssize_t ret)
+{
+ switch (ret) {
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ case -ERESTARTNOHAND:
+ case -ERESTART_RESTARTBLOCK:
+ /*
+ * We can't just restart the syscall, since previously
+ * submitted sqes may already be in progress. Just fail
+ * this IO with EINTR.
+ */
+ return -EINTR;
+ default:
+ return ret;
+ }
+}
+
static inline void io_rw_done(struct io_kiocb *req, ssize_t ret)
{
struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
@@ -625,19 +643,7 @@ static inline void io_rw_done(struct io_kiocb *req, ssize_t ret)
/* transform internal restart error codes */
if (unlikely(ret < 0)) {
- switch (ret) {
- case -ERESTARTSYS:
- case -ERESTARTNOINTR:
- case -ERESTARTNOHAND:
- case -ERESTART_RESTARTBLOCK:
- /*
- * We can't just restart the syscall, since previously
- * submitted sqes may already be in progress. Just fail
- * this IO with EINTR.
- */
- ret = -EINTR;
- break;
- }
+ ret = io_fixup_restart_res(ret);
}
if (req->flags & REQ_F_IOPOLL)
@@ -1034,6 +1040,8 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags)
if (req->flags & REQ_F_BUFFERS_COMMIT)
io_kbuf_recycle(req, sel.buf_list, issue_flags);
+
+ ret = io_fixup_restart_res(ret);
return ret;
}
@@ -1068,8 +1076,10 @@ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
return IOU_RETRY;
} else if (ret <= 0) {
io_kbuf_recycle(req, sel.buf_list, issue_flags);
- if (ret < 0)
+ if (ret < 0) {
+ ret = io_fixup_restart_res(ret);
req_set_fail(req);
+ }
} else if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
cflags = io_put_kbuf(req, ret, sel.buf_list);
} else {
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
2026-07-20 11:41 [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths Yitang Yang
@ 2026-07-21 16:32 ` Jens Axboe
2026-07-22 3:08 ` Yitang Yang
2026-07-22 10:32 ` Jens Axboe
2026-07-22 12:45 ` [PATCH v2] " Yitang Yang
2 siblings, 1 reply; 9+ messages in thread
From: Jens Axboe @ 2026-07-21 16:32 UTC (permalink / raw)
To: Yitang Yang; +Cc: krisman, io-uring
On 7/20/26 5:41 AM, Yitang Yang wrote:
> Both read and write may receive internal restart error codes from
> the filesystem layer and should be converted to -EINTR. However,
> when multishot read support was added, the error code normalization
> was lost for both io_read() and io_read_mshot().
>
> Extract the conversion into io_fixup_restart_res() and apply it
> in all three locations: io_rw_done(), io_read(), and io_read_mshot().
How was this found? Reason I ask is that I wonder if this is even
necessary in the first place. If you found this because of an issue
you ran into, then that answers that question clearly (yes we need it).
But if this some LLM find, then that's an entirely different story.
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
2026-07-21 16:32 ` Jens Axboe
@ 2026-07-22 3:08 ` Yitang Yang
2026-07-22 10:28 ` Jens Axboe
0 siblings, 1 reply; 9+ messages in thread
From: Yitang Yang @ 2026-07-22 3:08 UTC (permalink / raw)
To: Jens Axboe; +Cc: krisman, io-uring
I found this while trying to combine io_uring read multishot with
userfaultfd. I wrote a reproducer here:
https://gist.github.com/wokron/7f75026e02792844b0bbf26b7e79c9ef
Running it with "sudo ./userfaultfd-uring -n 16 -p 10000" on
my machine consistently produces "io_uring_cqe error: Unknown error 512".
Jens Axboe <axboe@kernel.dk> 于2026年7月22日周三 00:32写道:
>
> On 7/20/26 5:41 AM, Yitang Yang wrote:
> > Both read and write may receive internal restart error codes from
> > the filesystem layer and should be converted to -EINTR. However,
> > when multishot read support was added, the error code normalization
> > was lost for both io_read() and io_read_mshot().
> >
> > Extract the conversion into io_fixup_restart_res() and apply it
> > in all three locations: io_rw_done(), io_read(), and io_read_mshot().
>
> How was this found? Reason I ask is that I wonder if this is even
> necessary in the first place. If you found this because of an issue
> you ran into, then that answers that question clearly (yes we need it).
> But if this some LLM find, then that's an entirely different story.
>
> --
> Jens Axboe
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
2026-07-22 3:08 ` Yitang Yang
@ 2026-07-22 10:28 ` Jens Axboe
0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2026-07-22 10:28 UTC (permalink / raw)
To: Yitang Yang; +Cc: krisman, io-uring
On 7/21/26 9:08 PM, Yitang Yang wrote:
> I found this while trying to combine io_uring read multishot with
> userfaultfd. I wrote a reproducer here:
> https://gist.github.com/wokron/7f75026e02792844b0bbf26b7e79c9ef
>
> Running it with "sudo ./userfaultfd-uring -n 16 -p 10000" on
> my machine consistently produces "io_uring_cqe error: Unknown error 512".
Perfect, that's a much more useful find then! I'll take a closer look at
your patch.
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
2026-07-20 11:41 [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths Yitang Yang
2026-07-21 16:32 ` Jens Axboe
@ 2026-07-22 10:32 ` Jens Axboe
2026-07-22 12:36 ` Yitang Yang
2026-07-22 12:45 ` [PATCH v2] " Yitang Yang
2 siblings, 1 reply; 9+ messages in thread
From: Jens Axboe @ 2026-07-22 10:32 UTC (permalink / raw)
To: Yitang Yang; +Cc: krisman, io-uring
On 7/20/26 5:41 AM, Yitang Yang wrote:
> Both read and write may receive internal restart error codes from
> the filesystem layer and should be converted to -EINTR. However,
> when multishot read support was added, the error code normalization
> was lost for both io_read() and io_read_mshot().
>
> Extract the conversion into io_fixup_restart_res() and apply it
> in all three locations: io_rw_done(), io_read(), and io_read_mshot().
Functionally this looks good, just a few cosmetic nits below.
> Fixes: a08d195b586a ("io_uring/rw: split io_read() into a helper")
> Signed-off-by: Yitang Yang <yi1tang.yang@gmail.com>
And this one needs a Cc: stable@vger.kernel.org
> @@ -625,19 +643,7 @@ static inline void io_rw_done(struct io_kiocb *req, ssize_t ret)
>
> /* transform internal restart error codes */
> if (unlikely(ret < 0)) {
> - switch (ret) {
> - case -ERESTARTSYS:
> - case -ERESTARTNOINTR:
> - case -ERESTARTNOHAND:
> - case -ERESTART_RESTARTBLOCK:
> - /*
> - * We can't just restart the syscall, since previously
> - * submitted sqes may already be in progress. Just fail
> - * this IO with EINTR.
> - */
> - ret = -EINTR;
> - break;
> - }
> + ret = io_fixup_restart_res(ret);
> }
No need for braces anymore on the 'if' statement, just drop those.
> @@ -1034,6 +1040,8 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags)
>
> if (req->flags & REQ_F_BUFFERS_COMMIT)
> io_kbuf_recycle(req, sel.buf_list, issue_flags);
> +
> + ret = io_fixup_restart_res(ret);
> return ret;
> }
return io_fixup_restart_res(ret);
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
2026-07-22 10:32 ` Jens Axboe
@ 2026-07-22 12:36 ` Yitang Yang
2026-07-22 13:37 ` Jens Axboe
0 siblings, 1 reply; 9+ messages in thread
From: Yitang Yang @ 2026-07-22 12:36 UTC (permalink / raw)
To: Jens Axboe; +Cc: krisman, io-uring
Thanks! I'll send a v2.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
2026-07-20 11:41 [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths Yitang Yang
2026-07-21 16:32 ` Jens Axboe
2026-07-22 10:32 ` Jens Axboe
@ 2026-07-22 12:45 ` Yitang Yang
2026-07-22 13:37 ` Jens Axboe
2 siblings, 1 reply; 9+ messages in thread
From: Yitang Yang @ 2026-07-22 12:45 UTC (permalink / raw)
To: Jens Axboe; +Cc: Gabriel Krisman Bertazi, io-uring, Yitang Yang, stable
Both read and write may receive internal restart error codes from
the filesystem layer and should be converted to -EINTR. However,
when multishot read support was added, the error code normalization
was lost for both io_read() and io_read_mshot().
Extract the conversion into io_fixup_restart_res() and apply it
in all three locations: io_rw_done(), io_read(), and io_read_mshot().
Fixes: a08d195b586a ("io_uring/rw: split io_read() into a helper")
Cc: stable@vger.kernel.org
Signed-off-by: Yitang Yang <yi1tang.yang@gmail.com>
---
io_uring/rw.c | 42 +++++++++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/io_uring/rw.c b/io_uring/rw.c
index 63b6519e498c..95038cfda615 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -615,6 +615,24 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res)
smp_store_release(&req->iopoll_completed, 1);
}
+static inline ssize_t io_fixup_restart_res(ssize_t ret)
+{
+ switch (ret) {
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ case -ERESTARTNOHAND:
+ case -ERESTART_RESTARTBLOCK:
+ /*
+ * We can't just restart the syscall, since previously
+ * submitted sqes may already be in progress. Just fail
+ * this IO with EINTR.
+ */
+ return -EINTR;
+ default:
+ return ret;
+ }
+}
+
static inline void io_rw_done(struct io_kiocb *req, ssize_t ret)
{
struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
@@ -624,21 +642,8 @@ static inline void io_rw_done(struct io_kiocb *req, ssize_t ret)
return;
/* transform internal restart error codes */
- if (unlikely(ret < 0)) {
- switch (ret) {
- case -ERESTARTSYS:
- case -ERESTARTNOINTR:
- case -ERESTARTNOHAND:
- case -ERESTART_RESTARTBLOCK:
- /*
- * We can't just restart the syscall, since previously
- * submitted sqes may already be in progress. Just fail
- * this IO with EINTR.
- */
- ret = -EINTR;
- break;
- }
- }
+ if (unlikely(ret < 0))
+ ret = io_fixup_restart_res(ret);
if (req->flags & REQ_F_IOPOLL)
io_complete_rw_iopoll(&rw->kiocb, ret);
@@ -1034,7 +1039,8 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags)
if (req->flags & REQ_F_BUFFERS_COMMIT)
io_kbuf_recycle(req, sel.buf_list, issue_flags);
- return ret;
+
+ return io_fixup_restart_res(ret);
}
int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
@@ -1068,8 +1074,10 @@ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
return IOU_RETRY;
} else if (ret <= 0) {
io_kbuf_recycle(req, sel.buf_list, issue_flags);
- if (ret < 0)
+ if (ret < 0) {
+ ret = io_fixup_restart_res(ret);
req_set_fail(req);
+ }
} else if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
cflags = io_put_kbuf(req, ret, sel.buf_list);
} else {
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
2026-07-22 12:45 ` [PATCH v2] " Yitang Yang
@ 2026-07-22 13:37 ` Jens Axboe
0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2026-07-22 13:37 UTC (permalink / raw)
To: Yitang Yang; +Cc: Gabriel Krisman Bertazi, io-uring, stable
On Wed, 22 Jul 2026 20:45:51 +0800, Yitang Yang wrote:
> Both read and write may receive internal restart error codes from
> the filesystem layer and should be converted to -EINTR. However,
> when multishot read support was added, the error code normalization
> was lost for both io_read() and io_read_mshot().
>
> Extract the conversion into io_fixup_restart_res() and apply it
> in all three locations: io_rw_done(), io_read(), and io_read_mshot().
>
> [...]
Applied, thanks!
[1/1] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
commit: ab05caca123c6d0b41850b7c05b246e4dca4a770
Best regards,
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths
2026-07-22 12:36 ` Yitang Yang
@ 2026-07-22 13:37 ` Jens Axboe
0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2026-07-22 13:37 UTC (permalink / raw)
To: Yitang Yang; +Cc: krisman, io-uring
On 7/22/26 6:36 AM, Yitang Yang wrote:
> Thanks! I'll send a v2.
Thanks, applied it - can you send your test case as a liburing test/
addition as well?
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-07-22 13:37 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20 11:41 [PATCH] io_uring/rw: fix missing ERESTARTSYS conversion in read paths Yitang Yang
2026-07-21 16:32 ` Jens Axboe
2026-07-22 3:08 ` Yitang Yang
2026-07-22 10:28 ` Jens Axboe
2026-07-22 10:32 ` Jens Axboe
2026-07-22 12:36 ` Yitang Yang
2026-07-22 13:37 ` Jens Axboe
2026-07-22 12:45 ` [PATCH v2] " Yitang Yang
2026-07-22 13:37 ` Jens Axboe
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.