On Wed, Jul 2, 2025 at 12:04 AM Ming Lei <ming.lei@xxxxxxxxxx> wrote: > > Refactor ublk_commit_and_fetch() in the following way for removing > parameter of `struct ublksrv_io_cmd *`: > > - return `struct request *` from ublk_fill_io_cmd(), so that we can > use request reference reliably in this way cause both request and > io_uring_cmd reference share same storage > > - move ublk_fill_io_cmd() before calling into ublk_commit_and_fetch(), > so that ublk_fill_io_cmd() could be run with per-io lock held for > supporting command batch. > > - pass ->zone_append_lba to ublk_commit_and_fetch() directly > > The main motivation is to reproduce ublk_commit_and_fetch() for fetching > io command batch with multishot uring_cmd. > > Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> > --- > drivers/block/ublk_drv.c | 43 ++++++++++++++++++++++++++-------------- > 1 file changed, 28 insertions(+), 15 deletions(-) > > diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c > index 2dc6962c804a..1780f9ce3a24 100644 > --- a/drivers/block/ublk_drv.c > +++ b/drivers/block/ublk_drv.c > @@ -1983,10 +1983,13 @@ static inline int ublk_check_cmd_op(u32 cmd_op) > return 0; > } > > -static inline void ublk_fill_io_cmd(struct ublk_io *io, > - struct io_uring_cmd *cmd, unsigned long buf_addr, > - int result) > +/* Once we return, `io->req` can't be used any more */ > +static inline struct request * > +ublk_fill_io_cmd(struct ublk_io *io, struct io_uring_cmd *cmd, > + unsigned long buf_addr, int result) > { > + struct request *req = io->req; > + > io->cmd = cmd; > io->flags |= UBLK_IO_FLAG_ACTIVE; > io->addr = buf_addr; > @@ -1994,6 +1997,8 @@ static inline void ublk_fill_io_cmd(struct ublk_io *io, > > /* now this cmd slot is owned by ublk driver */ > io->flags &= ~UBLK_IO_FLAG_OWNED_BY_SRV; > + > + return req; This is nice symmetry with __ublk_prep_compl_io_cmd(). Reviewed-by: Caleb Sander Mateos <csander@xxxxxxxxxxxxxxx> > } > > static inline void ublk_prep_cancel(struct io_uring_cmd *cmd, > @@ -2159,10 +2164,8 @@ static int ublk_fetch(struct io_uring_cmd *cmd, struct ublk_queue *ubq, > return ret; > } > > -static int ublk_commit_and_fetch(const struct ublk_queue *ubq, > - struct ublk_io *io, struct io_uring_cmd *cmd, > - const struct ublksrv_io_cmd *ub_cmd, > - unsigned int issue_flags) > +static int ublk_check_commit_and_fetch(const struct ublk_queue *ubq, > + struct ublk_io *io, __u64 buf_addr) > { > struct request *req = io->req; > > @@ -2171,10 +2174,10 @@ static int ublk_commit_and_fetch(const struct ublk_queue *ubq, > * COMMIT_AND_FETCH_REQ has to provide IO buffer if > * NEED GET DATA is not enabled or it is Read IO. > */ > - if (!ub_cmd->addr && (!ublk_need_get_data(ubq) || > + if (!buf_addr && (!ublk_need_get_data(ubq) || > req_op(req) == REQ_OP_READ)) > return -EINVAL; > - } else if (req_op(req) != REQ_OP_ZONE_APPEND && ub_cmd->addr) { > + } else if (req_op(req) != REQ_OP_ZONE_APPEND && buf_addr) { > /* > * User copy requires addr to be unset when command is > * not zone append > @@ -2182,6 +2185,14 @@ static int ublk_commit_and_fetch(const struct ublk_queue *ubq, > return -EINVAL; > } > > + return 0; > +} > + > +static int ublk_commit_and_fetch(const struct ublk_queue *ubq, > + struct ublk_io *io, struct io_uring_cmd *cmd, > + struct request *req, unsigned int issue_flags, > + __u64 zone_append_lba) > +{ > if (ublk_support_auto_buf_reg(ubq)) { > int ret; > > @@ -2207,10 +2218,8 @@ static int ublk_commit_and_fetch(const struct ublk_queue *ubq, > return ret; > } > > - ublk_fill_io_cmd(io, cmd, ub_cmd->addr, ub_cmd->result); > - > if (req_op(req) == REQ_OP_ZONE_APPEND) > - req->__sector = ub_cmd->zone_append_lba; > + req->__sector = zone_append_lba; > > if (ublk_need_req_ref(ubq)) > ublk_sub_req_ref(io, req); > @@ -2316,7 +2325,12 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, > return ublk_daemon_register_io_buf(cmd, ubq, io, ub_cmd->addr, > issue_flags); > case UBLK_IO_COMMIT_AND_FETCH_REQ: > - ret = ublk_commit_and_fetch(ubq, io, cmd, ub_cmd, issue_flags); > + ret = ublk_check_commit_and_fetch(ubq, io, ub_cmd->addr); > + if (ret) > + goto out; > + req = ublk_fill_io_cmd(io, cmd, ub_cmd->addr, ub_cmd->result); > + ret = ublk_commit_and_fetch(ubq, io, cmd, req, issue_flags, > + ub_cmd->zone_append_lba); > if (ret) > goto out; > break; > @@ -2326,8 +2340,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, > * uring_cmd active first and prepare for handling new requeued > * request > */ > - req = io->req; > - ublk_fill_io_cmd(io, cmd, ub_cmd->addr, 0); > + req = ublk_fill_io_cmd(io, cmd, ub_cmd->addr, 0); > if (likely(ublk_get_data(ubq, io, req))) { > __ublk_prep_compl_io_cmd(io, req); > return UBLK_IO_RES_OK; > -- > 2.47.0 >