On Fri, Mar 24, 2023 at 05:54:36PM -0600, Keith Busch wrote: > On Fri, Mar 24, 2023 at 08:35:38AM -0600, Jens Axboe wrote: > > @@ -402,7 +402,22 @@ static struct iovec *__io_import_iovec(int ddir, struct io_kiocb *req, > > req->ctx->compat); > > if (unlikely(ret < 0)) > > return ERR_PTR(ret); > > - return iovec; > > + if (iter->nr_segs != 1) > > + return iovec; > > + /* > > + * Convert to non-vectored request if we have a single segment. If we > > + * need to defer the request, then we no longer have to allocate and > > + * maintain a struct io_async_rw. Additionally, we won't have cleanup > > + * to do at completion time > > + */ > > + rw->addr = (unsigned long) iter->iov[0].iov_base; > > + rw->len = iter->iov[0].iov_len; > > + iov_iter_ubuf(iter, ddir, iter->iov[0].iov_base, rw->len); > > + /* readv -> read distance is the same as writev -> write */ > > + BUILD_BUG_ON((IORING_OP_READ - IORING_OP_READV) != > > + (IORING_OP_WRITE - IORING_OP_WRITEV)); > > + req->opcode += (IORING_OP_READ - IORING_OP_READV); > > + return NULL; > > } > > This may break anyone using io_uring with those bizarre drivers that have > entirely different readv semantics from normal read. I think we can safely say > no one's using io_uring for such interfaces, so probably a moot point. If you > wanted to be extra cautious though, you may want to skip this transformation if > the file->f_op implements both .read+read_iter and .write+.write_iter. Sorry, scratch that; those drivers are already broken if they implement both with different semantics, so we can definitely say none of those are using io_uring. This new patch should be safe then.