| From 5df6646864caef2931e25351fc4aa64f7b47c6cc Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 25 Feb 2025 14:24:55 -0700 |
| Subject: ublk: complete command synchronously on error |
| |
| From: Caleb Sander Mateos <csander@purestorage.com> |
| |
| [ Upstream commit 603f9be21c1894e462416e3324962d6c9c2b95f8 ] |
| |
| 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> |
| Stable-dep-of: c6a45ee7607d ("ublk: prevent invalid access with DEBUG") |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/block/ublk_drv.c | 11 ++++++----- |
| 1 file changed, 6 insertions(+), 5 deletions(-) |
| |
| diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c |
| index 6419f304fa5e2..88d566f0ffa64 100644 |
| --- a/drivers/block/ublk_drv.c |
| +++ b/drivers/block/ublk_drv.c |
| @@ -1821,10 +1821,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, |
| @@ -1880,7 +1879,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) |
| @@ -2948,10 +2950,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 = { |
| -- |
| 2.51.0 |
| |