aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Penyaev <rpenyaev@suse.de>2019-03-25 15:09:24 -0400
committerJens Axboe <axboe@kernel.dk>2019-03-25 15:13:21 -0400
commit9bf7933fc3f306bc4ce74ad734f690a71670178a (patch)
tree99a1c127e6ca7f99bee5b2595532f8c07b2ddb06
parente6d1fa584e0dd9bfebaf345e9feea588cf75ead2 (diff)
io_uring: offload write to async worker in case of -EAGAIN
In case of direct write -EAGAIN will be returned if page cache was previously populated. To avoid immediate completion of a request with -EAGAIN error write has to be offloaded to the async worker, like io_read() does. Signed-off-by: Roman Penyaev <rpenyaev@suse.de> Cc: Jens Axboe <axboe@kernel.dk> Cc: linux-block@vger.kernel.org Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--fs/io_uring.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 8f48d29abf76..bbdbd56cf2ac 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1022,6 +1022,8 @@ static int io_write(struct io_kiocb *req, const struct sqe_submit *s,
1022 1022
1023 ret = rw_verify_area(WRITE, file, &kiocb->ki_pos, iov_count); 1023 ret = rw_verify_area(WRITE, file, &kiocb->ki_pos, iov_count);
1024 if (!ret) { 1024 if (!ret) {
1025 ssize_t ret2;
1026
1025 /* 1027 /*
1026 * Open-code file_start_write here to grab freeze protection, 1028 * Open-code file_start_write here to grab freeze protection,
1027 * which will be released by another thread in 1029 * which will be released by another thread in
@@ -1036,7 +1038,19 @@ static int io_write(struct io_kiocb *req, const struct sqe_submit *s,
1036 SB_FREEZE_WRITE); 1038 SB_FREEZE_WRITE);
1037 } 1039 }
1038 kiocb->ki_flags |= IOCB_WRITE; 1040 kiocb->ki_flags |= IOCB_WRITE;
1039 io_rw_done(kiocb, call_write_iter(file, kiocb, &iter)); 1041
1042 ret2 = call_write_iter(file, kiocb, &iter);
1043 if (!force_nonblock || ret2 != -EAGAIN) {
1044 io_rw_done(kiocb, ret2);
1045 } else {
1046 /*
1047 * If ->needs_lock is true, we're already in async
1048 * context.
1049 */
1050 if (!s->needs_lock)
1051 io_async_list_note(WRITE, req, iov_count);
1052 ret = -EAGAIN;
1053 }
1040 } 1054 }
1041out_free: 1055out_free:
1042 kfree(iovec); 1056 kfree(iovec);