
From: Al Viro <viro@zeniv.linux.org.uk> mainline inclusion from mainline-v6.7-rc1 commit 1939316bf988f3e49a07d9c4dd6f660bf4daa53d category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IC6ES1 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- ->ki_pos value is unreliable in such cases. For an obvious example, consider O_DSYNC write - we feed the data to page cache and start IO, then we make sure it's completed. Update of ->ki_pos is dealt with by the first part; failure in the second ends up with negative value returned _and_ ->ki_pos left advanced as if sync had been successful. In the same situation write(2) does not advance the file position at all. Reviewed-by: Christian Brauner <brauner@kernel.org> Reviewed-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Conflicts: io_uring/rw.c [Commit f3b44f92e59a ("io_uring: move read/write related opcodes to its own file") move kiocb_done from io_uring.c to rw.c] Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com> --- io_uring/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index ea821d5c54a7..bdbd8fe36773 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -3073,7 +3073,7 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret, { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb); - if (req->flags & REQ_F_CUR_POS) + if (ret >= 0 && req->flags & REQ_F_CUR_POS) req->file->f_pos = kiocb->ki_pos; if (ret >= 0 && (kiocb->ki_complete == io_complete_rw)) { if (!__io_complete_rw_common(req, ret)) { -- 2.31.1