Messages in this thread Patch in this message | | | From | Niklas Cassel <> | Subject | [RFC PATCH] nvme: allow NVME_IOCTL_IO_CMD on controller char dev even when multiple ns | Date | Fri, 26 Mar 2021 20:59:59 +0000 |
| |
From: Niklas Cassel <niklas.cassel@wdc.com>
Currently when doing NVME_IOCTL_IO_CMD on the controller character device, the command is rejected if there is more than one namespace in the ctrl->namespaces list.
There is not really any reason for this restriction. Instead, check the nsid value specified in the passthru command, and try to find the matching namespace in ctrl->namespaces list. If found, call nvme_user_cmd() on the namespace. If not found, reject the command.
While at it, remove the warning that says that NVME_IOCTL_IO_CMD is deprecated on the controller character device. There is no comment saying why it is deprecated. It might be very unsafe to send a passthru command, but if that is the issue with this IOCTL, then we should add a warning about that instead.
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> --- drivers/nvme/host/core.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index a50352ea3f7b..b50fdf143b90 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3264,35 +3264,31 @@ static int nvme_dev_release(struct inode *inode, struct file *file) static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp) { + struct nvme_passthru_cmd cmd; struct nvme_ns *ns; int ret; down_read(&ctrl->namespaces_rwsem); if (list_empty(&ctrl->namespaces)) { - ret = -ENOTTY; - goto out_unlock; + up_read(&ctrl->namespaces_rwsem); + return -ENOTTY; } + up_read(&ctrl->namespaces_rwsem); - ns = list_first_entry(&ctrl->namespaces, struct nvme_ns, list); - if (ns != list_last_entry(&ctrl->namespaces, struct nvme_ns, list)) { - dev_warn(ctrl->device, - "NVME_IOCTL_IO_CMD not supported when multiple namespaces present!\n"); - ret = -EINVAL; - goto out_unlock; - } + if (copy_from_user(&cmd, argp, sizeof(cmd))) + return -EFAULT; - dev_warn(ctrl->device, - "using deprecated NVME_IOCTL_IO_CMD ioctl on the char device!\n"); - kref_get(&ns->kref); - up_read(&ctrl->namespaces_rwsem); + ns = nvme_find_get_ns(ctrl, cmd.nsid); + if (!ns) { + dev_err(ctrl->device, + "%s: could not find namespace with nsid %u\n", + current->comm, cmd.nsid); + return -EINVAL; + } ret = nvme_user_cmd(ctrl, ns, argp); nvme_put_ns(ns); return ret; - -out_unlock: - up_read(&ctrl->namespaces_rwsem); - return ret; } static long nvme_dev_ioctl(struct file *file, unsigned int cmd, -- 2.30.2
| |