On Mon, Aug 24, 2020 at 11:48:44AM -0600, Jens Axboe wrote: > Some consumers of the iov_iter will return an error, but still have > bytes consumed in the iterator. This is an issue for -EAGAIN, since we > rely on a sane iov_iter state across retries. > > Fix this by ensuring that we revert consumed bytes, if any, if the file > operations have consumed any bytes from iterator. This is similar to what > generic_file_read_iter() does, and is always safe as we have the previous > bytes count handy already. > > Fixes: ff6165b2d7f6 ("io_uring: retain iov_iter state over io_read/io_write calls") > Reported-by: Dmitry Shulyak <yashulyak@xxxxxxxxx> > Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> > > --- > > diff --git a/fs/io_uring.c b/fs/io_uring.c > index c9d526ff55e0..e030b33fa53e 100644 > --- a/fs/io_uring.c > +++ b/fs/io_uring.c > @@ -3153,6 +3153,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock, > } else if (ret == -EAGAIN) { > if (!force_nonblock) > goto done; > + /* some cases will consume bytes even on error returns */ > + iov_iter_revert(iter, iov_count - iov_iter_count(iter)); > ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false); > if (ret) > goto out_free; > @@ -3294,6 +3296,8 @@ static int io_write(struct io_kiocb *req, bool force_nonblock, > if (!force_nonblock || ret2 != -EAGAIN) { > kiocb_done(kiocb, ret2, cs); > } else { > + /* some cases will consume bytes even on error returns */ > + iov_iter_revert(iter, iov_count - iov_iter_count(iter)); > copy_iov: > ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false); > if (!ret) > What about moving iov_iter_revert() in io_setup_async_rw(), passing iov_initial_count as parameter? Maybe it's out of purpose since we use it even when we're not trying again. Anyway the patch LGTM: Reviewed-by: Stefano Garzarella <sgarzare@xxxxxxxxxx> Thanks, Stefano