summary refs log tree commit diff
path: root/io_uring/rw.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2022-06-24 10:24:45 -0600
committerJens Axboe <axboe@kernel.dk>2022-07-24 18:39:32 -0600
commite053aaf4da56cbf0afb33a0fda4a62188e2c0637 (patch)
tree4dbe314803d0eddfdcea133396452dbb977c03b2 /io_uring/rw.c
parent4e17aaab54359fa2cdeb0080c822a08f2980f979 (diff)
downloadlinux-e053aaf4da56cbf0afb33a0fda4a62188e2c0637.tar.gz
io_uring: fix issue with io_write() not always undoing sb_start_write()
This is actually an older issue, but we never used to hit the -EAGAIN
path before having done sb_start_write(). Make sure that we always call
kiocb_end_write() if we need to retry the write, so that we keep the
calls to sb_start_write() etc balanced.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring/rw.c')
-rw-r--r--io_uring/rw.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/io_uring/rw.c b/io_uring/rw.c
index 4d4ca6389876..1f4a8ff98254 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -945,6 +945,8 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)
 			if (rw)
 				rw->bytes_done += ret2;
 
+			if (kiocb->ki_flags & IOCB_WRITE)
+				kiocb_end_write(req);
 			return ret ? ret : -EAGAIN;
 		}
 done:
@@ -953,7 +955,12 @@ done:
 copy_iov:
 		iov_iter_restore(&s->iter, &s->iter_state);
 		ret = io_setup_async_rw(req, iovec, s, false);
-		return ret ?: -EAGAIN;
+		if (!ret) {
+			if (kiocb->ki_flags & IOCB_WRITE)
+				kiocb_end_write(req);
+			return -EAGAIN;
+		}
+		return ret;
 	}
 	/* it's reportedly faster than delegating the null check to kfree() */
 	if (iovec)