io_uring: fix explicit async read/write mapping for large segments

If we exceed UIO_FASTIOV, we don't handle the transition correctly
between an allocated vec for requests that are queued with IOSQE_ASYNC.
Store the iovec appropriately and re-set it in the iter iov in case
it changed.

Fixes: ff6165b2d7f6 ("io_uring: retain iov_iter state over io_read/io_write calls")
Reported-by: Nick Hill <nick@nickhill.org>
Tested-by: Norman Maurer <norman.maurer@googlemail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

Changed files
+4 -3
fs
+4 -3
fs/io_uring.c
··· 2980 2980 bool force_nonblock) 2981 2981 { 2982 2982 struct io_async_rw *iorw = &req->io->rw; 2983 + struct iovec *iov; 2983 2984 ssize_t ret; 2984 2985 2985 - iorw->iter.iov = iorw->fast_iov; 2986 - ret = __io_import_iovec(rw, req, (struct iovec **) &iorw->iter.iov, 2987 - &iorw->iter, !force_nonblock); 2986 + iorw->iter.iov = iov = iorw->fast_iov; 2987 + ret = __io_import_iovec(rw, req, &iov, &iorw->iter, !force_nonblock); 2988 2988 if (unlikely(ret < 0)) 2989 2989 return ret; 2990 2990 2991 + iorw->iter.iov = iov; 2991 2992 io_req_map_rw(req, iorw->iter.iov, iorw->fast_iov, &iorw->iter); 2992 2993 return 0; 2993 2994 }