Hi, There's currently two places that know to call io_*_prep() for sqes. io_req_defer_prep() and io_issue_sqe(). E.g. for READV there's: static int io_req_defer_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ... case IORING_OP_READV: case IORING_OP_READ_FIXED: case IORING_OP_READ: ret = io_read_prep(req, sqe, true); break; and static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, struct io_kiocb **nxt, bool force_nonblock) { ... case IORING_OP_READV: case IORING_OP_READ_FIXED: case IORING_OP_READ: if (sqe) { ret = io_read_prep(req, sqe, force_nonblock); if (ret < 0) break; } ret = io_read(req, nxt, force_nonblock); break; that seems a bit unnecessary. How about breaking that out into a separate function? I can write up a patch, just didn't want to do so if there's a reason for the current split. Alternatively it'd could all be just be dispatches via io_op_defs, but that'd be a bigger change with potential performance implications. And it'd benefit from prior deduplication anyway. Greetings, Andres Freund