diff options
author | Roman Penyaev <rpenyaev@suse.de> | 2019-03-25 15:09:24 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-03-25 15:13:21 -0400 |
commit | 9bf7933fc3f306bc4ce74ad734f690a71670178a (patch) | |
tree | 99a1c127e6ca7f99bee5b2595532f8c07b2ddb06 | |
parent | e6d1fa584e0dd9bfebaf345e9feea588cf75ead2 (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.c | 16 |
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 | } |
1041 | out_free: | 1055 | out_free: |
1042 | kfree(iovec); | 1056 | kfree(iovec); |