[PATCH 13/13] nvme: introduce generic per-namespace chardev

Minwoo Im minwoo.im.dev at gmail.com
Fri Apr 9 08:29:01 BST 2021


On 21-04-08 14:08:42, Christoph Hellwig wrote:
> diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
> index 001faf31fb944f..304dc66bcebf22 100644
> --- a/drivers/nvme/host/ioctl.c
> +++ b/drivers/nvme/host/ioctl.c
> @@ -357,6 +357,14 @@ int nvme_ioctl(struct block_device *bdev, fmode_t mode,
>  	return nvme_ns_ioctl(ns, cmd, argp);
>  }
>  
> +long nvme_ns_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> +	struct nvme_ns *ns =
> +		container_of(file_inode(file)->i_cdev, struct nvme_ns, cdev);
> +
> +	return nvme_ns_ioctl(ns, cmd, (void __user *)arg);
> +}
> +
>  #ifdef CONFIG_NVME_MULTIPATH
>  static int nvme_ns_head_ctrl_ioctl(struct nvme_ns_head *head,
>  		unsigned int cmd, void __user *argp)
> @@ -393,6 +401,15 @@ int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
>  		return nvme_ns_head_ctrl_ioctl(head, cmd, (void __user *)arg);
>  	return nvme_ns_head_ns_ioctl(head, cmd, (void __user *)arg);
>  }
> +
> +long nvme_ns_head_chr_ioctl(struct file *file, unsigned int cmd,
> +		unsigned long arg)
> +{
> +	struct cdev *cdev = file_inode(file)->i_cdev;
> +	struct nvme_ns_head *head = container_of(cdev, struct nvme_ns_head, cdev);
> +
> +	return nvme_ns_head_ns_ioctl(head, cmd, (void __user *)arg);
> +}
>  #endif /* CONFIG_NVME_MULTIPATH */

Tested with namespace-specific admin commmand (Identify Namespace).  And
it fails with invalid IOCTl because we don't have a route to the
controller IOCTL for the generic chrdev.

Maybe we can have the following patch with simplifying the little bit
duplicated codes and make blkdev and generic device consistent which
will make user-space application happy?

diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 304dc66bcebf..cbce9e35a591 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -346,15 +346,19 @@ static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
 	}
 }
 
+static int __nvme_ioctl(struct nvme_ns *ns, unsigned int cmd, void __user *arg)
+{
+	if (is_ctrl_ioctl(cmd))
+		return nvme_ctrl_ioctl(ns->ctrl, cmd, arg);
+	return nvme_ns_ioctl(ns, cmd, arg);
+}
+
 int nvme_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg)
 {
 	struct nvme_ns *ns = bdev->bd_disk->private_data;
-	void __user *argp = (void __user *)arg;
 
-	if (is_ctrl_ioctl(cmd))
-		return nvme_ctrl_ioctl(ns->ctrl, cmd, argp);
-	return nvme_ns_ioctl(ns, cmd, argp);
+	return __nvme_ioctl(ns, cmd, (void __user *)arg);
 }
 
 long nvme_ns_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -362,7 +366,7 @@ long nvme_ns_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	struct nvme_ns *ns =
 		container_of(file_inode(file)->i_cdev, struct nvme_ns, cdev);
 
-	return nvme_ns_ioctl(ns, cmd, (void __user *)arg);
+	return __nvme_ioctl(ns, cmd, (void __user *)arg);
 }
 
 #ifdef CONFIG_NVME_MULTIPATH
@@ -392,14 +396,20 @@ static int nvme_ns_head_ns_ioctl(struct nvme_ns_head *head,
 	return ret;
 }
 
+static int __nvme_ns_head_ioctl(struct nvme_ns_head *head, unsigned int cmd,
+		void __user *arg)
+{
+	if (is_ctrl_ioctl(cmd))
+		return nvme_ns_head_ctrl_ioctl(head, cmd, arg);
+	return nvme_ns_head_ns_ioctl(head, cmd, arg);
+}
+
 int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg)
 {
 	struct nvme_ns_head *head = bdev->bd_disk->private_data;
 
-	if (is_ctrl_ioctl(cmd))
-		return nvme_ns_head_ctrl_ioctl(head, cmd, (void __user *)arg);
-	return nvme_ns_head_ns_ioctl(head, cmd, (void __user *)arg);
+	return __nvme_ns_head_ioctl(head, cmd, (void __user *)arg);
 }
 
 long nvme_ns_head_chr_ioctl(struct file *file, unsigned int cmd,
@@ -408,7 +418,7 @@ long nvme_ns_head_chr_ioctl(struct file *file, unsigned int cmd,
 	struct cdev *cdev = file_inode(file)->i_cdev;
 	struct nvme_ns_head *head = container_of(cdev, struct nvme_ns_head, cdev);
 
-	return nvme_ns_head_ns_ioctl(head, cmd, (void __user *)arg);
+	return __nvme_ns_head_ioctl(head, cmd, (void __user *)arg);
 }
 #endif /* CONFIG_NVME_MULTIPATH */
 



More information about the Linux-nvme mailing list