On Thu, 2022-07-21 at 20:08 +0700, Ammar Faizi wrote: > On 7/21/22 7:05 PM, Dylan Yudaken wrote: > > It seems to be a problem with blocking reads, buffer select and > > READV. > > My guess is that ext4/xfs are not blocking. > > > > in b66e65f41426 ("io_uring: never call io_buffer_select() for a > > buffer > > re-select"), this line was added in __io_iov_buffer_select > > > > - iov[0].iov_len = len; > > + req->rw.len = iov[0].iov_len = len; > > > > Basically stashing the buffer length in rw.len. The problem is that > > the > > next time around that breaks at > > > > if (req->rw.len != 1) > > return -EINVAL; > > > > > > The below fixes it as an example, but it's not great. Maybe someone > > can > > figure out a better patch? Otherwise I can try tomorrow: > > It's 8:05 PM from my end. I'll try to play with your patch after > dinner > while waiting for others say something. > I've just sent the below actually which is a bit simpler. I reran all the tests on btrfs and xfs and it seems to work now: diff --git a/fs/io_uring.c b/fs/io_uring.c index a01ea49f3017..b0180679584f 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1737,6 +1737,14 @@ static void io_kbuf_recycle(struct io_kiocb *req, unsigned issue_flags) (req->flags & REQ_F_PARTIAL_IO)) return; + /* + * READV uses fields in `struct io_rw` (len/addr) to stash the selected + * buffer data. However if that buffer is recycled the original request + * data stored in addr is lost. Therefore forbid recycling for now. + */ + if (req->opcode == IORING_OP_READV) + return; + /* * We don't need to recycle for REQ_F_BUFFER_RING, we can just clear * the flag and hence ensure that bl->head doesn't get incremented.