diff options
Diffstat (limited to 'io_uring/rw.c')
| -rw-r--r-- | io_uring/rw.c | 42 |
1 files 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 { |