]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ublk: complete command synchronously on error
authorCaleb Sander Mateos <csander@purestorage.com>
Tue, 25 Feb 2025 21:24:55 +0000 (14:24 -0700)
committerJens Axboe <axboe@kernel.dk>
Mon, 3 Mar 2025 18:17:52 +0000 (11:17 -0700)
In case of an error, ublk's ->uring_cmd() functions currently return
-EIOCBQUEUED and immediately call io_uring_cmd_done(). -EIOCBQUEUED and
io_uring_cmd_done() are intended for asynchronous completions. For
synchronous completions, the ->uring_cmd() function can just return the
negative return code directly. This skips io_uring_cmd_del_cancelable(),
and deferring the completion to task work. So return the error code
directly from __ublk_ch_uring_cmd() and ublk_ctrl_uring_cmd().

Update ublk_ch_uring_cmd_cb(), which currently ignores the return value
from __ublk_ch_uring_cmd(), to call io_uring_cmd_done() for synchronous
completions.

Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Link: https://lore.kernel.org/r/20250225212456.2902549-1-csander@purestorage.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/ublk_drv.c

index 529085181f355026bf81c07dfe38d042054a5c61..ff648c6839c15446ab845ea3fbbb57713a665495 100644 (file)
@@ -1866,10 +1866,9 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
        return -EIOCBQUEUED;
 
  out:
-       io_uring_cmd_done(cmd, ret, 0, issue_flags);
        pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n",
                        __func__, cmd_op, tag, ret, io->flags);
-       return -EIOCBQUEUED;
+       return ret;
 }
 
 static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub,
@@ -1925,7 +1924,10 @@ static inline int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
 static void ublk_ch_uring_cmd_cb(struct io_uring_cmd *cmd,
                unsigned int issue_flags)
 {
-       ublk_ch_uring_cmd_local(cmd, issue_flags);
+       int ret = ublk_ch_uring_cmd_local(cmd, issue_flags);
+
+       if (ret != -EIOCBQUEUED)
+               io_uring_cmd_done(cmd, ret, 0, issue_flags);
 }
 
 static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
@@ -3056,10 +3058,9 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,
        if (ub)
                ublk_put_device(ub);
  out:
-       io_uring_cmd_done(cmd, ret, 0, issue_flags);
        pr_devel("%s: cmd done ret %d cmd_op %x, dev id %d qid %d\n",
                        __func__, ret, cmd->cmd_op, header->dev_id, header->queue_id);
-       return -EIOCBQUEUED;
+       return ret;
 }
 
 static const struct file_operations ublk_ctl_fops = {