From f9c90d04b6806b8a8b923952a7cea0a6215a58e7 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 1 Dec 2025 11:55:19 +0100 Subject: [PATCH 1/2] ioctl: fix return code handling in uring code With the recent cleanup in the passthru code, the uring code was not updated. Since the calling code is not really interested in the status code from the nvme command, let's remove this for the time being. Fixes: 94b1e1443132 ("src: drop result argument from submit API") Signed-off-by: Daniel Wagner --- libnvme/src/nvme/ioctl.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/libnvme/src/nvme/ioctl.c b/libnvme/src/nvme/ioctl.c index 36ccae6bf1..818e6472bf 100644 --- a/libnvme/src/nvme/ioctl.c +++ b/libnvme/src/nvme/ioctl.c @@ -260,7 +260,7 @@ static void nvme_uring_cmd_exit(struct io_uring *ring) } static int nvme_uring_cmd_admin_passthru_async(struct nvme_transport_handle *hdl, - struct io_uring *ring, struct nvme_passthru_cmd *cmd, __u32 *result) + struct io_uring *ring, struct nvme_passthru_cmd *cmd) { struct io_uring_sqe *sqe; int ret; @@ -274,7 +274,6 @@ static int nvme_uring_cmd_admin_passthru_async(struct nvme_transport_handle *hdl sqe->fd = hdl->fd; sqe->opcode = IORING_OP_URING_CMD; sqe->cmd_op = NVME_URING_CMD_ADMIN; - sqe->user_data = (__u64)(uintptr_t)result; ret = io_uring_submit(ring); if (ret < 0) @@ -286,26 +285,16 @@ static int nvme_uring_cmd_admin_passthru_async(struct nvme_transport_handle *hdl static int nvme_uring_cmd_wait_complete(struct io_uring *ring, int n) { struct io_uring_cqe *cqe; - int i, ret = 0; - __u32 *result; + int ret, i; for (i = 0; i < n; i++) { ret = io_uring_wait_cqe(ring, &cqe); - if (ret) - return -1; - - if (cqe->res) { - result = (__u32 *)cqe->user_data; - if (result) - *result = cqe->res; - ret = cqe->res; - break; - } - + if (ret < 0) + return -errno; io_uring_cqe_seen(ring, cqe); } - return ret; + return 0; } static bool nvme_uring_is_usable(struct nvme_transport_handle *hdl) @@ -388,15 +377,16 @@ int nvme_get_log(struct nvme_transport_handle *hdl, #ifdef CONFIG_LIBURING if (use_uring) { if (n >= NVME_URING_ENTRIES) { - nvme_uring_cmd_wait_complete(&ring, n); + ret = nvme_uring_cmd_wait_complete(&ring, n); + if (ret) + goto uring_exit; n = 0; } n += 1; - ret = nvme_uring_cmd_admin_passthru_async(hdl, &ring, - cmd, result); - + ret = nvme_uring_cmd_admin_passthru_async(hdl, + &ring, cmd); if (ret) - nvme_uring_cmd_exit(&ring); + goto uring_exit; } else { ret = nvme_submit_admin_passthru(hdl, cmd); if (ret) @@ -414,7 +404,8 @@ int nvme_get_log(struct nvme_transport_handle *hdl, #ifdef CONFIG_LIBURING if (use_uring) { - nvme_uring_cmd_wait_complete(&ring, n); + ret = nvme_uring_cmd_wait_complete(&ring, n); +uring_exit: nvme_uring_cmd_exit(&ring); if (ret) return ret; From 640b0fa76f0eb58b50a5b886c05755f980152db1 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 8 Dec 2025 14:18:40 +0100 Subject: [PATCH 2/2] nvme: add fallback support for block vs char device to dsm command The dsm command is only supported by the block device. The kernel has support to map NVME_IOCTL_IO_CMD when user spaces uses the char device. Though for NVME_IOCTL_IO64_CMD this support is missing and wont be added to the kernel. Thus add the fallback code to userland. Signed-off-by: Daniel Wagner --- nvme.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/nvme.c b/nvme.c index f078d0adcc..32bfffd344 100644 --- a/nvme.c +++ b/nvme.c @@ -7350,6 +7350,28 @@ static int dsm(int argc, char **argv, struct command *acmd, struct plugin *plugi if (err) return err; + if (nvme_transport_handle_is_chardev(hdl)) { + _cleanup_free_ char *cdev = NULL; + + if (!cfg.namespace_id) { + nvme_show_error("char device not supported without --namespace-id"); + return -EINVAL; + } + + if (asprintf(&cdev, "/dev/%sn%d", + nvme_transport_handle_get_name(hdl), + cfg.namespace_id) < 0) + return -ENOMEM; + + nvme_close(hdl); + + err = nvme_open(ctx, cdev, &hdl); + if (err) { + nvme_show_error("could not open %s", cdev); + return err; + } + } + err = validate_output_format(nvme_cfg.output_format, &flags); if (err < 0) { nvme_show_error("Invalid output format");