linux-nvme.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* nvme ioctl refactor and generic per-namespace char device
@ 2021-04-08 12:08 ` Christoph Hellwig
  2021-04-08 12:08   ` [PATCH 01/13] nvme: add a nvme_ns_head_multipath helper Christoph Hellwig
                     ` (15 more replies)
  0 siblings, 16 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Hi all,

this series picks up the generic per-namespace character device
from Minwoo and Javier with a few small fixed, but rebases them on
an ioctl refactoring I had pending, which cleans up a lot of the
lower level code.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH 01/13] nvme: add a nvme_ns_head_multipath helper
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-09  2:33     ` Chaitanya Kulkarni
  2021-04-08 12:08   ` [PATCH 02/13] nvme: cleanup setting the disk name Christoph Hellwig
                     ` (14 subsequent siblings)
  15 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

From: Minwoo Im <minwoo.im.dev@gmail.com>

Move the multipath gendisk out of #ifdef CONFIG_NVME_MULTIPATH and add
a new nvme_ns_head_multipath that uses it to check if a ns_head has
a multipath device associated with it.

Signed-off-by: Minwoo Im <minwoo.im.dev@gmail.com>
[hch: added the IS_ENABLED, converted a few existing users]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c | 8 ++------
 drivers/nvme/host/nvme.h | 7 ++++++-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 314705da2c1076..4d13bca83cfefa 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1873,11 +1873,9 @@ static int nvme_open(struct block_device *bdev, fmode_t mode)
 {
 	struct nvme_ns *ns = bdev->bd_disk->private_data;
 
-#ifdef CONFIG_NVME_MULTIPATH
 	/* should never be called due to GENHD_FL_HIDDEN */
-	if (WARN_ON_ONCE(ns->head->disk))
+	if (WARN_ON_ONCE(nvme_ns_head_multipath(ns->head)))
 		goto fail;
-#endif
 	if (!kref_get_unless_zero(&ns->kref))
 		goto fail;
 	if (!try_module_get(ns->ctrl->ops->module))
@@ -2215,8 +2213,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
 			return ret;
 	}
 
-#ifdef CONFIG_NVME_MULTIPATH
-	if (ns->head->disk) {
+	if (nvme_ns_head_multipath(ns->head)) {
 		blk_mq_freeze_queue(ns->head->disk->queue);
 		nvme_update_disk_info(ns->head->disk, ns, id);
 		blk_stack_limits(&ns->head->disk->queue->limits,
@@ -2224,7 +2221,6 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
 		blk_queue_update_readahead(ns->head->disk->queue);
 		blk_mq_unfreeze_queue(ns->head->disk->queue);
 	}
-#endif
 	return 0;
 
 out_unfreeze:
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 815c032a190eff..67ff5d41e7d03b 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -413,8 +413,8 @@ struct nvme_ns_head {
 	bool			shared;
 	int			instance;
 	struct nvme_effects_log *effects;
-#ifdef CONFIG_NVME_MULTIPATH
 	struct gendisk		*disk;
+#ifdef CONFIG_NVME_MULTIPATH
 	struct bio_list		requeue_list;
 	spinlock_t		requeue_lock;
 	struct work_struct	requeue_work;
@@ -425,6 +425,11 @@ struct nvme_ns_head {
 #endif
 };
 
+static inline bool nvme_ns_head_multipath(struct nvme_ns_head *head)
+{
+	return IS_ENABLED(CONFIG_NVME_MULTIPATH) && head->disk;
+}
+
 enum nvme_ns_features {
 	NVME_NS_EXT_LBAS = 1 << 0, /* support extended LBA format */
 	NVME_NS_METADATA_SUPPORTED = 1 << 1, /* support getting generated md */
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 02/13] nvme: cleanup setting the disk name
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
  2021-04-08 12:08   ` [PATCH 01/13] nvme: add a nvme_ns_head_multipath helper Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-08 12:08   ` [PATCH 03/13] nvme: pass a user pointer to nvme_nvm_ioctl Christoph Hellwig
                     ` (13 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Return false from nvme_set_disk_name and let the caller set the
non-multipath name instead of duplicating the naming information in two
places.  Also remove the pointless local variables for the disk name
and flags and the not needed ctrl argument.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c      | 17 +++++++++++------
 drivers/nvme/host/multipath.c | 24 ++++++++++++------------
 drivers/nvme/host/nvme.h      | 14 ++++----------
 3 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 4d13bca83cfefa..8c60ddc47b546d 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3998,8 +3998,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
 	struct nvme_ns *ns;
 	struct gendisk *disk;
 	struct nvme_id_ns *id;
-	char disk_name[DISK_NAME_LEN];
-	int node = ctrl->numa_node, flags = GENHD_FL_EXT_DEVT;
+	int node = ctrl->numa_node;
 
 	if (nvme_identify_ns(ctrl, nsid, ids, &id))
 		return;
@@ -4025,7 +4024,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
 
 	if (nvme_init_ns_head(ns, nsid, ids, id->nmic & NVME_NS_NMIC_SHARED))
 		goto out_free_queue;
-	nvme_set_disk_name(disk_name, ns, ctrl, &flags);
 
 	disk = alloc_disk_node(0, node);
 	if (!disk)
@@ -4034,15 +4032,22 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
 	disk->fops = &nvme_bdev_ops;
 	disk->private_data = ns;
 	disk->queue = ns->queue;
-	disk->flags = flags;
-	memcpy(disk->disk_name, disk_name, DISK_NAME_LEN);
+	disk->flags = GENHD_FL_EXT_DEVT;
+	/*
+	 * Without the multipath code enabled, multiple controller per
+	 * subsystems are visible as devices and thus we cannot use the
+	 * subsystem instance.
+	 */
+	if (!nvme_mpath_set_disk_name(ns, disk->disk_name, &disk->flags))
+		sprintf(disk->disk_name, "nvme%dn%d", ctrl->instance,
+			ns->head->instance);
 	ns->disk = disk;
 
 	if (nvme_update_ns_info(ns, id))
 		goto out_put_disk;
 
 	if ((ctrl->quirks & NVME_QUIRK_LIGHTNVM) && id->vs[0] == 0x1) {
-		if (nvme_nvm_register(ns, disk_name, node)) {
+		if (nvme_nvm_register(ns, disk->disk_name, node)) {
 			dev_warn(ctrl->device, "LightNVM init failure\n");
 			goto out_put_disk;
 		}
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index f2d0ce0f4d3811..0f42b7e94ce3f3 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -50,19 +50,19 @@ void nvme_mpath_start_freeze(struct nvme_subsystem *subsys)
  * and those that have a single controller and use the controller node
  * directly.
  */
-void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns,
-			struct nvme_ctrl *ctrl, int *flags)
-{
-	if (!multipath) {
-		sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance);
-	} else if (ns->head->disk) {
-		sprintf(disk_name, "nvme%dc%dn%d", ctrl->subsys->instance,
-				ctrl->instance, ns->head->instance);
-		*flags = GENHD_FL_HIDDEN;
-	} else {
-		sprintf(disk_name, "nvme%dn%d", ctrl->subsys->instance,
-				ns->head->instance);
+bool nvme_mpath_set_disk_name(struct nvme_ns *ns, char *disk_name, int *flags)
+{
+	if (!multipath)
+		return false;
+	if (!ns->head->disk) {
+		sprintf(disk_name, "nvme%dn%d", ns->ctrl->subsys->instance,
+			ns->head->instance);
+		return true;
 	}
+	sprintf(disk_name, "nvme%dc%dn%d", ns->ctrl->subsys->instance,
+		ns->ctrl->instance, ns->head->instance);
+	*flags = GENHD_FL_HIDDEN;
+	return true;
 }
 
 void nvme_failover_req(struct request *req)
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 67ff5d41e7d03b..2ef0a355fbb4ae 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -668,8 +668,7 @@ static inline bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl)
 void nvme_mpath_unfreeze(struct nvme_subsystem *subsys);
 void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys);
 void nvme_mpath_start_freeze(struct nvme_subsystem *subsys);
-void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns,
-			struct nvme_ctrl *ctrl, int *flags);
+bool nvme_mpath_set_disk_name(struct nvme_ns *ns, char *disk_name, int *flags);
 void nvme_failover_req(struct request *req);
 void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl);
 int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head);
@@ -708,16 +707,11 @@ static inline bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl)
 {
 	return false;
 }
-/*
- * Without the multipath code enabled, multiple controller per subsystems are
- * visible as devices and thus we cannot use the subsystem instance.
- */
-static inline void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns,
-				      struct nvme_ctrl *ctrl, int *flags)
+static inline bool nvme_mpath_set_disk_name(struct nvme_ns *ns, char *disk_name,
+		int *flags)
 {
-	sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance);
+	return false;
 }
-
 static inline void nvme_failover_req(struct request *req)
 {
 }
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 03/13] nvme: pass a user pointer to nvme_nvm_ioctl
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
  2021-04-08 12:08   ` [PATCH 01/13] nvme: add a nvme_ns_head_multipath helper Christoph Hellwig
  2021-04-08 12:08   ` [PATCH 02/13] nvme: cleanup setting the disk name Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-08 12:08   ` [PATCH 04/13] nvme: factor out a nvme_ns_ioctl helper Christoph Hellwig
                     ` (12 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Pass the proper user pointer instead of the not all that useful integer
representation.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c     | 2 +-
 drivers/nvme/host/lightnvm.c | 8 ++++----
 drivers/nvme/host/nvme.h     | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 8c60ddc47b546d..6c0456e404319e 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1819,7 +1819,7 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
 		break;
 	default:
 		if (ns->ndev)
-			ret = nvme_nvm_ioctl(ns, cmd, arg);
+			ret = nvme_nvm_ioctl(ns, cmd, argp);
 		else
 			ret = -ENOTTY;
 	}
diff --git a/drivers/nvme/host/lightnvm.c b/drivers/nvme/host/lightnvm.c
index b705988629f224..d5ef114d2bf101 100644
--- a/drivers/nvme/host/lightnvm.c
+++ b/drivers/nvme/host/lightnvm.c
@@ -930,15 +930,15 @@ static int nvme_nvm_user_vcmd(struct nvme_ns *ns, int admin,
 	return ret;
 }
 
-int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg)
+int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, void __user *argp)
 {
 	switch (cmd) {
 	case NVME_NVM_IOCTL_ADMIN_VIO:
-		return nvme_nvm_user_vcmd(ns, 1, (void __user *)arg);
+		return nvme_nvm_user_vcmd(ns, 1, argp);
 	case NVME_NVM_IOCTL_IO_VIO:
-		return nvme_nvm_user_vcmd(ns, 0, (void __user *)arg);
+		return nvme_nvm_user_vcmd(ns, 0, argp);
 	case NVME_NVM_IOCTL_SUBMIT_VIO:
-		return nvme_nvm_submit_vio(ns, (void __user *)arg);
+		return nvme_nvm_submit_vio(ns, argp);
 	default:
 		return -ENOTTY;
 	}
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 2ef0a355fbb4ae..70018ae2cb1876 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -799,7 +799,7 @@ static inline int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf)
 int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node);
 void nvme_nvm_unregister(struct nvme_ns *ns);
 extern const struct attribute_group nvme_nvm_attr_group;
-int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg);
+int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, void __user *argp);
 #else
 static inline int nvme_nvm_register(struct nvme_ns *ns, char *disk_name,
 				    int node)
@@ -809,7 +809,7 @@ static inline int nvme_nvm_register(struct nvme_ns *ns, char *disk_name,
 
 static inline void nvme_nvm_unregister(struct nvme_ns *ns) {};
 static inline int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd,
-							unsigned long arg)
+		void __user *argp)
 {
 	return -ENOTTY;
 }
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 04/13] nvme: factor out a nvme_ns_ioctl helper
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (2 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 03/13] nvme: pass a user pointer to nvme_nvm_ioctl Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-09  2:40     ` Chaitanya Kulkarni
  2021-04-08 12:08   ` [PATCH 05/13] nvme: simplify the compat ioctl handling Christoph Hellwig
                     ` (11 subsequent siblings)
  15 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Factor out a helper for the namespace based ioctls.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c | 42 ++++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 6c0456e404319e..56fe5b9712e756 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1783,6 +1783,26 @@ static int nvme_handle_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd,
 	return ret;
 }
 
+static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
+		void __user *argp)
+{
+	switch (cmd) {
+	case NVME_IOCTL_ID:
+		force_successful_syscall_return();
+		return ns->head->ns_id;
+	case NVME_IOCTL_IO_CMD:
+		return nvme_user_cmd(ns->ctrl, ns, argp);
+	case NVME_IOCTL_SUBMIT_IO:
+		return nvme_submit_io(ns, argp);
+	case NVME_IOCTL_IO64_CMD:
+		return nvme_user_cmd64(ns->ctrl, ns, argp);
+	default:
+		if (!ns->ndev)
+			return -ENOTTY;
+		return nvme_nvm_ioctl(ns, cmd, argp);
+	}
+}
+
 static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg)
 {
@@ -1803,27 +1823,7 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
 	if (is_ctrl_ioctl(cmd))
 		return nvme_handle_ctrl_ioctl(ns, cmd, argp, head, srcu_idx);
 
-	switch (cmd) {
-	case NVME_IOCTL_ID:
-		force_successful_syscall_return();
-		ret = ns->head->ns_id;
-		break;
-	case NVME_IOCTL_IO_CMD:
-		ret = nvme_user_cmd(ns->ctrl, ns, argp);
-		break;
-	case NVME_IOCTL_SUBMIT_IO:
-		ret = nvme_submit_io(ns, argp);
-		break;
-	case NVME_IOCTL_IO64_CMD:
-		ret = nvme_user_cmd64(ns->ctrl, ns, argp);
-		break;
-	default:
-		if (ns->ndev)
-			ret = nvme_nvm_ioctl(ns, cmd, argp);
-		else
-			ret = -ENOTTY;
-	}
-
+	ret = nvme_ns_ioctl(ns, cmd, argp);
 	nvme_put_ns_from_disk(head, srcu_idx);
 	return ret;
 }
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 05/13] nvme: simplify the compat ioctl handling
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (3 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 04/13] nvme: factor out a nvme_ns_ioctl helper Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-09  2:42     ` Chaitanya Kulkarni
  2021-04-08 12:08   ` [PATCH 06/13] nvme: simplify block device ioctl handling for the !multipath case Christoph Hellwig
                     ` (10 subsequent siblings)
  15 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Don't bother defining a separate compat_ioctl handler, and just handle
the NVME_IOCTL_SUBMIT_IO32 case inline.  Also only defined it for those
ABIs (currently just i386 vs x86_64) that are affected.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c | 69 +++++++++++++++-------------------------
 1 file changed, 26 insertions(+), 43 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 56fe5b9712e756..1b80868e2539df 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1783,6 +1783,24 @@ static int nvme_handle_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd,
 	return ret;
 }
 
+#ifdef COMPAT_FOR_U64_ALIGNMENT
+struct nvme_user_io32 {
+	__u8	opcode;
+	__u8	flags;
+	__u16	control;
+	__u16	nblocks;
+	__u16	rsvd;
+	__u64	metadata;
+	__u64	addr;
+	__u64	slba;
+	__u32	dsmgmt;
+	__u32	reftag;
+	__u16	apptag;
+	__u16	appmask;
+} __attribute__((__packed__));
+#define NVME_IOCTL_SUBMIT_IO32	_IOW('N', 0x42, struct nvme_user_io32)
+#endif /* COMPAT_FOR_U64_ALIGNMENT */
+
 static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
 		void __user *argp)
 {
@@ -1792,6 +1810,14 @@ static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
 		return ns->head->ns_id;
 	case NVME_IOCTL_IO_CMD:
 		return nvme_user_cmd(ns->ctrl, ns, argp);
+	/*
+	 * struct nvme_user_io can has different padding on some 32-bit ABIs.
+	 * Just accept the compat version as all fields that are used are the
+	 * same size and at the same offset.
+	 */
+#ifdef COMPAT_FOR_U64_ALIGNMENT
+	case NVME_IOCTL_SUBMIT_IO32:
+#endif
 	case NVME_IOCTL_SUBMIT_IO:
 		return nvme_submit_io(ns, argp);
 	case NVME_IOCTL_IO64_CMD:
@@ -1828,47 +1854,6 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
 	return ret;
 }
 
-#ifdef CONFIG_COMPAT
-struct nvme_user_io32 {
-	__u8	opcode;
-	__u8	flags;
-	__u16	control;
-	__u16	nblocks;
-	__u16	rsvd;
-	__u64	metadata;
-	__u64	addr;
-	__u64	slba;
-	__u32	dsmgmt;
-	__u32	reftag;
-	__u16	apptag;
-	__u16	appmask;
-} __attribute__((__packed__));
-
-#define NVME_IOCTL_SUBMIT_IO32	_IOW('N', 0x42, struct nvme_user_io32)
-
-static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode,
-		unsigned int cmd, unsigned long arg)
-{
-	/*
-	 * Corresponds to the difference of NVME_IOCTL_SUBMIT_IO
-	 * between 32 bit programs and 64 bit kernel.
-	 * The cause is that the results of sizeof(struct nvme_user_io),
-	 * which is used to define NVME_IOCTL_SUBMIT_IO,
-	 * are not same between 32 bit compiler and 64 bit compiler.
-	 * NVME_IOCTL_SUBMIT_IO32 is for 64 bit kernel handling
-	 * NVME_IOCTL_SUBMIT_IO issued from 32 bit programs.
-	 * Other IOCTL numbers are same between 32 bit and 64 bit.
-	 * So there is nothing to do regarding to other IOCTL numbers.
-	 */
-	if (cmd == NVME_IOCTL_SUBMIT_IO32)
-		return nvme_ioctl(bdev, mode, NVME_IOCTL_SUBMIT_IO, arg);
-
-	return nvme_ioctl(bdev, mode, cmd, arg);
-}
-#else
-#define nvme_compat_ioctl	NULL
-#endif /* CONFIG_COMPAT */
-
 static int nvme_open(struct block_device *bdev, fmode_t mode)
 {
 	struct nvme_ns *ns = bdev->bd_disk->private_data;
@@ -2356,7 +2341,6 @@ EXPORT_SYMBOL_GPL(nvme_sec_submit);
 static const struct block_device_operations nvme_bdev_ops = {
 	.owner		= THIS_MODULE,
 	.ioctl		= nvme_ioctl,
-	.compat_ioctl	= nvme_compat_ioctl,
 	.open		= nvme_open,
 	.release	= nvme_release,
 	.getgeo		= nvme_getgeo,
@@ -2385,7 +2369,6 @@ const struct block_device_operations nvme_ns_head_ops = {
 	.open		= nvme_ns_head_open,
 	.release	= nvme_ns_head_release,
 	.ioctl		= nvme_ioctl,
-	.compat_ioctl	= nvme_compat_ioctl,
 	.getgeo		= nvme_getgeo,
 	.report_zones	= nvme_report_zones,
 	.pr_ops		= &nvme_pr_ops,
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 06/13] nvme: simplify block device ioctl handling for the !multipath case
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (4 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 05/13] nvme: simplify the compat ioctl handling Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-08 12:08   ` [PATCH 07/13] nvme: don't bother to look up a namespace for controller ioctls Christoph Hellwig
                     ` (9 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Only use the existing ioctl handler for the multipath case, and add a
simpler one that reverts to the pre-multipath case for not shared
use case.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c | 83 +++++++++++++++++++++++-----------------
 1 file changed, 47 insertions(+), 36 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 1b80868e2539df..edf7d7fc8e4bbb 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1757,30 +1757,17 @@ static bool is_ctrl_ioctl(unsigned int cmd)
 	return false;
 }
 
-static int nvme_handle_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd,
-				  void __user *argp,
-				  struct nvme_ns_head *head,
-				  int srcu_idx)
+static int nvme_ctrl_ioctl(struct nvme_ctrl *ctrl, unsigned int cmd,
+		void __user *argp)
 {
-	struct nvme_ctrl *ctrl = ns->ctrl;
-	int ret;
-
-	nvme_get_ctrl(ns->ctrl);
-	nvme_put_ns_from_disk(head, srcu_idx);
-
 	switch (cmd) {
 	case NVME_IOCTL_ADMIN_CMD:
-		ret = nvme_user_cmd(ctrl, NULL, argp);
-		break;
+		return nvme_user_cmd(ctrl, NULL, argp);
 	case NVME_IOCTL_ADMIN64_CMD:
-		ret = nvme_user_cmd64(ctrl, NULL, argp);
-		break;
+		return nvme_user_cmd64(ctrl, NULL, argp);
 	default:
-		ret = sed_ioctl(ctrl->opal_dev, cmd, argp);
-		break;
+		return sed_ioctl(ctrl->opal_dev, cmd, argp);
 	}
-	nvme_put_ctrl(ctrl);
-	return ret;
 }
 
 #ifdef COMPAT_FOR_U64_ALIGNMENT
@@ -1832,26 +1819,12 @@ static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
 static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg)
 {
-	struct nvme_ns_head *head = NULL;
+	struct nvme_ns *ns = bdev->bd_disk->private_data;
 	void __user *argp = (void __user *)arg;
-	struct nvme_ns *ns;
-	int srcu_idx, ret;
-
-	ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx);
-	if (unlikely(!ns))
-		return -EWOULDBLOCK;
 
-	/*
-	 * Handle ioctls that apply to the controller instead of the namespace
-	 * seperately and drop the ns SRCU reference early.  This avoids a
-	 * deadlock when deleting namespaces using the passthrough interface.
-	 */
 	if (is_ctrl_ioctl(cmd))
-		return nvme_handle_ctrl_ioctl(ns, cmd, argp, head, srcu_idx);
-
-	ret = nvme_ns_ioctl(ns, cmd, argp);
-	nvme_put_ns_from_disk(head, srcu_idx);
-	return ret;
+		return nvme_ctrl_ioctl(ns->ctrl, cmd, argp);
+	return nvme_ns_ioctl(ns, cmd, argp);
 }
 
 static int nvme_open(struct block_device *bdev, fmode_t mode)
@@ -2363,12 +2336,50 @@ static void nvme_ns_head_release(struct gendisk *disk, fmode_t mode)
 	nvme_put_ns_head(disk->private_data);
 }
 
+static int nvme_ns_head_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd,
+		void __user *argp, struct nvme_ns_head *head, int srcu_idx)
+{
+	struct nvme_ctrl *ctrl = ns->ctrl;
+	int ret;
+
+	nvme_get_ctrl(ns->ctrl);
+	nvme_put_ns_from_disk(head, srcu_idx);
+	ret = nvme_ctrl_ioctl(ns->ctrl, cmd, argp);
+	nvme_put_ctrl(ctrl);
+	return ret;
+}
+
+static int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
+		unsigned int cmd, unsigned long arg)
+{
+	struct nvme_ns_head *head = NULL;
+	void __user *argp = (void __user *)arg;
+	struct nvme_ns *ns;
+	int srcu_idx, ret;
+
+	ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx);
+	if (unlikely(!ns))
+		return -EWOULDBLOCK;
+
+	/*
+	 * Handle ioctls that apply to the controller instead of the namespace
+	 * seperately and drop the ns SRCU reference early.  This avoids a
+	 * deadlock when deleting namespaces using the passthrough interface.
+	 */
+	if (is_ctrl_ioctl(cmd))
+		return nvme_ns_head_ctrl_ioctl(ns, cmd, argp, head, srcu_idx);
+
+	ret = nvme_ns_ioctl(ns, cmd, argp);
+	nvme_put_ns_from_disk(head, srcu_idx);
+	return ret;
+}
+
 const struct block_device_operations nvme_ns_head_ops = {
 	.owner		= THIS_MODULE,
 	.submit_bio	= nvme_ns_head_submit_bio,
 	.open		= nvme_ns_head_open,
 	.release	= nvme_ns_head_release,
-	.ioctl		= nvme_ioctl,
+	.ioctl		= nvme_ns_head_ioctl,
 	.getgeo		= nvme_getgeo,
 	.report_zones	= nvme_report_zones,
 	.pr_ops		= &nvme_pr_ops,
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 07/13] nvme: don't bother to look up a namespace for controller ioctls
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (5 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 06/13] nvme: simplify block device ioctl handling for the !multipath case Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-08 12:08   ` [PATCH 08/13] nvme: move the ioctl code to a separate file Christoph Hellwig
                     ` (8 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Don't bother to look up a namespace just to drop if after retreiving the
controller for the multipath case.  Just look up a live controller for
the subsystem directly.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c | 66 +++++++++++++++++++++++++---------------
 1 file changed, 42 insertions(+), 24 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index edf7d7fc8e4bbb..75e230dcbfef06 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2336,42 +2336,60 @@ static void nvme_ns_head_release(struct gendisk *disk, fmode_t mode)
 	nvme_put_ns_head(disk->private_data);
 }
 
-static int nvme_ns_head_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd,
-		void __user *argp, struct nvme_ns_head *head, int srcu_idx)
+static struct nvme_ctrl *nvme_find_get_live_ctrl(struct nvme_subsystem *subsys)
 {
-	struct nvme_ctrl *ctrl = ns->ctrl;
+	struct nvme_ctrl *ctrl;
 	int ret;
 
-	nvme_get_ctrl(ns->ctrl);
-	nvme_put_ns_from_disk(head, srcu_idx);
-	ret = nvme_ctrl_ioctl(ns->ctrl, cmd, argp);
+	ret = mutex_lock_killable(&nvme_subsystems_lock);
+	if (ret)
+		return ERR_PTR(ret);
+	list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
+		if (ctrl->state == NVME_CTRL_LIVE)
+			goto found;
+	}
+	mutex_unlock(&nvme_subsystems_lock);
+	return ERR_PTR(-EWOULDBLOCK);
+found:
+	nvme_get_ctrl(ctrl);
+	mutex_unlock(&nvme_subsystems_lock);
+	return ctrl;
+}
+
+static int nvme_ns_head_ctrl_ioctl(struct nvme_ns_head *head,
+		unsigned int cmd, void __user *argp)
+{
+	struct nvme_ctrl *ctrl = nvme_find_get_live_ctrl(head->subsys);
+	int ret;
+
+	if (IS_ERR(ctrl))
+		return PTR_ERR(ctrl);
+	ret = nvme_ctrl_ioctl(ctrl, cmd, argp);
 	nvme_put_ctrl(ctrl);
 	return ret;
 }
 
+static int nvme_ns_head_ns_ioctl(struct nvme_ns_head *head,
+		unsigned int cmd, void __user *argp)
+{
+	int srcu_idx = srcu_read_lock(&head->srcu);
+	struct nvme_ns *ns = nvme_find_path(head);
+	int ret = -EWOULDBLOCK;
+
+	if (ns)
+		ret = nvme_ns_ioctl(ns, cmd, argp);
+	srcu_read_unlock(&head->srcu, srcu_idx);
+	return ret;
+}
+
 static int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg)
 {
-	struct nvme_ns_head *head = NULL;
-	void __user *argp = (void __user *)arg;
-	struct nvme_ns *ns;
-	int srcu_idx, ret;
-
-	ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx);
-	if (unlikely(!ns))
-		return -EWOULDBLOCK;
+	struct nvme_ns_head *head = bdev->bd_disk->private_data;
 
-	/*
-	 * Handle ioctls that apply to the controller instead of the namespace
-	 * seperately and drop the ns SRCU reference early.  This avoids a
-	 * deadlock when deleting namespaces using the passthrough interface.
-	 */
 	if (is_ctrl_ioctl(cmd))
-		return nvme_ns_head_ctrl_ioctl(ns, cmd, argp, head, srcu_idx);
-
-	ret = nvme_ns_ioctl(ns, cmd, argp);
-	nvme_put_ns_from_disk(head, srcu_idx);
-	return ret;
+		return nvme_ns_head_ctrl_ioctl(head, cmd, (void __user *)arg);
+	return nvme_ns_head_ns_ioctl(head, cmd, (void __user *)arg);
 }
 
 const struct block_device_operations nvme_ns_head_ops = {
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 08/13] nvme: move the ioctl code to a separate file
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (6 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 07/13] nvme: don't bother to look up a namespace for controller ioctls Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-09  2:45     ` Chaitanya Kulkarni
  2021-04-08 12:08   ` [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper Christoph Hellwig
                     ` (7 subsequent siblings)
  15 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Split out the ioctl code from core.c into a new file.  Also update
copyrights while we're at it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/Makefile |   2 +-
 drivers/nvme/host/core.c   | 450 +-----------------------------------
 drivers/nvme/host/ioctl.c  | 455 +++++++++++++++++++++++++++++++++++++
 drivers/nvme/host/nvme.h   |  10 +-
 4 files changed, 468 insertions(+), 449 deletions(-)
 create mode 100644 drivers/nvme/host/ioctl.c

diff --git a/drivers/nvme/host/Makefile b/drivers/nvme/host/Makefile
index d7f6a87687b8d9..cbc509784b2e73 100644
--- a/drivers/nvme/host/Makefile
+++ b/drivers/nvme/host/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_NVME_RDMA)			+= nvme-rdma.o
 obj-$(CONFIG_NVME_FC)			+= nvme-fc.o
 obj-$(CONFIG_NVME_TCP)			+= nvme-tcp.o
 
-nvme-core-y				:= core.o
+nvme-core-y				:= core.o ioctl.o
 nvme-core-$(CONFIG_TRACING)		+= trace.o
 nvme-core-$(CONFIG_NVME_MULTIPATH)	+= multipath.o
 nvme-core-$(CONFIG_NVM)			+= lightnvm.o
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 75e230dcbfef06..98d87bff4ca37f 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -112,7 +112,7 @@ static void nvme_set_queue_dying(struct nvme_ns *ns)
 	set_capacity_and_notify(ns->disk, 0);
 }
 
-static void nvme_queue_scan(struct nvme_ctrl *ctrl)
+void nvme_queue_scan(struct nvme_ctrl *ctrl)
 {
 	/*
 	 * Only new queue scan work when admin and IO queues are both alive
@@ -179,7 +179,7 @@ int nvme_reset_ctrl(struct nvme_ctrl *ctrl)
 }
 EXPORT_SYMBOL_GPL(nvme_reset_ctrl);
 
-static int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl)
+int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl)
 {
 	int ret;
 
@@ -1016,40 +1016,6 @@ int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
 }
 EXPORT_SYMBOL_GPL(nvme_submit_sync_cmd);
 
-static void *nvme_add_user_metadata(struct bio *bio, void __user *ubuf,
-		unsigned len, u32 seed, bool write)
-{
-	struct bio_integrity_payload *bip;
-	int ret = -ENOMEM;
-	void *buf;
-
-	buf = kmalloc(len, GFP_KERNEL);
-	if (!buf)
-		goto out;
-
-	ret = -EFAULT;
-	if (write && copy_from_user(buf, ubuf, len))
-		goto out_free_meta;
-
-	bip = bio_integrity_alloc(bio, GFP_KERNEL, 1);
-	if (IS_ERR(bip)) {
-		ret = PTR_ERR(bip);
-		goto out_free_meta;
-	}
-
-	bip->bip_iter.bi_size = len;
-	bip->bip_iter.bi_sector = seed;
-	ret = bio_integrity_add_page(bio, virt_to_page(buf), len,
-			offset_in_page(buf));
-	if (ret == len)
-		return buf;
-	ret = -ENOMEM;
-out_free_meta:
-	kfree(buf);
-out:
-	return ERR_PTR(ret);
-}
-
 static u32 nvme_known_admin_effects(u8 opcode)
 {
 	switch (opcode) {
@@ -1138,66 +1104,6 @@ void nvme_execute_passthru_rq(struct request *rq)
 }
 EXPORT_SYMBOL_NS_GPL(nvme_execute_passthru_rq, NVME_TARGET_PASSTHRU);
 
-static int nvme_submit_user_cmd(struct request_queue *q,
-		struct nvme_command *cmd, void __user *ubuffer,
-		unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
-		u32 meta_seed, u64 *result, unsigned timeout)
-{
-	bool write = nvme_is_write(cmd);
-	struct nvme_ns *ns = q->queuedata;
-	struct block_device *bdev = ns ? ns->disk->part0 : NULL;
-	struct request *req;
-	struct bio *bio = NULL;
-	void *meta = NULL;
-	int ret;
-
-	req = nvme_alloc_request(q, cmd, 0);
-	if (IS_ERR(req))
-		return PTR_ERR(req);
-
-	if (timeout)
-		req->timeout = timeout;
-	nvme_req(req)->flags |= NVME_REQ_USERCMD;
-
-	if (ubuffer && bufflen) {
-		ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen,
-				GFP_KERNEL);
-		if (ret)
-			goto out;
-		bio = req->bio;
-		if (bdev)
-			bio_set_dev(bio, bdev);
-		if (bdev && meta_buffer && meta_len) {
-			meta = nvme_add_user_metadata(bio, meta_buffer, meta_len,
-					meta_seed, write);
-			if (IS_ERR(meta)) {
-				ret = PTR_ERR(meta);
-				goto out_unmap;
-			}
-			req->cmd_flags |= REQ_INTEGRITY;
-		}
-	}
-
-	nvme_execute_passthru_rq(req);
-	if (nvme_req(req)->flags & NVME_REQ_CANCELLED)
-		ret = -EINTR;
-	else
-		ret = nvme_req(req)->status;
-	if (result)
-		*result = le64_to_cpu(nvme_req(req)->result.u64);
-	if (meta && !ret && !write) {
-		if (copy_to_user(meta_buffer, meta, meta_len))
-			ret = -EFAULT;
-	}
-	kfree(meta);
- out_unmap:
-	if (bio)
-		blk_rq_unmap_user(bio);
- out:
-	blk_mq_free_request(req);
-	return ret;
-}
-
 static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status)
 {
 	struct nvme_ctrl *ctrl = rq->end_io_data;
@@ -1542,182 +1448,6 @@ static void nvme_enable_aen(struct nvme_ctrl *ctrl)
 	queue_work(nvme_wq, &ctrl->async_event_work);
 }
 
-/*
- * Convert integer values from ioctl structures to user pointers, silently
- * ignoring the upper bits in the compat case to match behaviour of 32-bit
- * kernels.
- */
-static void __user *nvme_to_user_ptr(uintptr_t ptrval)
-{
-	if (in_compat_syscall())
-		ptrval = (compat_uptr_t)ptrval;
-	return (void __user *)ptrval;
-}
-
-static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
-{
-	struct nvme_user_io io;
-	struct nvme_command c;
-	unsigned length, meta_len;
-	void __user *metadata;
-
-	if (copy_from_user(&io, uio, sizeof(io)))
-		return -EFAULT;
-	if (io.flags)
-		return -EINVAL;
-
-	switch (io.opcode) {
-	case nvme_cmd_write:
-	case nvme_cmd_read:
-	case nvme_cmd_compare:
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	length = (io.nblocks + 1) << ns->lba_shift;
-
-	if ((io.control & NVME_RW_PRINFO_PRACT) &&
-	    ns->ms == sizeof(struct t10_pi_tuple)) {
-		/*
-		 * Protection information is stripped/inserted by the
-		 * controller.
-		 */
-		if (nvme_to_user_ptr(io.metadata))
-			return -EINVAL;
-		meta_len = 0;
-		metadata = NULL;
-	} else {
-		meta_len = (io.nblocks + 1) * ns->ms;
-		metadata = nvme_to_user_ptr(io.metadata);
-	}
-
-	if (ns->features & NVME_NS_EXT_LBAS) {
-		length += meta_len;
-		meta_len = 0;
-	} else if (meta_len) {
-		if ((io.metadata & 3) || !io.metadata)
-			return -EINVAL;
-	}
-
-	memset(&c, 0, sizeof(c));
-	c.rw.opcode = io.opcode;
-	c.rw.flags = io.flags;
-	c.rw.nsid = cpu_to_le32(ns->head->ns_id);
-	c.rw.slba = cpu_to_le64(io.slba);
-	c.rw.length = cpu_to_le16(io.nblocks);
-	c.rw.control = cpu_to_le16(io.control);
-	c.rw.dsmgmt = cpu_to_le32(io.dsmgmt);
-	c.rw.reftag = cpu_to_le32(io.reftag);
-	c.rw.apptag = cpu_to_le16(io.apptag);
-	c.rw.appmask = cpu_to_le16(io.appmask);
-
-	return nvme_submit_user_cmd(ns->queue, &c,
-			nvme_to_user_ptr(io.addr), length,
-			metadata, meta_len, lower_32_bits(io.slba), NULL, 0);
-}
-
-static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
-			struct nvme_passthru_cmd __user *ucmd)
-{
-	struct nvme_passthru_cmd cmd;
-	struct nvme_command c;
-	unsigned timeout = 0;
-	u64 result;
-	int status;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EACCES;
-	if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
-		return -EFAULT;
-	if (cmd.flags)
-		return -EINVAL;
-	if (ns && cmd.nsid != ns->head->ns_id) {
-		dev_err(ctrl->device,
-			"%s: nsid (%u) in cmd does not match nsid (%u) of namespace\n",
-			current->comm, cmd.nsid, ns->head->ns_id);
-		return -EINVAL;
-	}
-
-	memset(&c, 0, sizeof(c));
-	c.common.opcode = cmd.opcode;
-	c.common.flags = cmd.flags;
-	c.common.nsid = cpu_to_le32(cmd.nsid);
-	c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
-	c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
-	c.common.cdw10 = cpu_to_le32(cmd.cdw10);
-	c.common.cdw11 = cpu_to_le32(cmd.cdw11);
-	c.common.cdw12 = cpu_to_le32(cmd.cdw12);
-	c.common.cdw13 = cpu_to_le32(cmd.cdw13);
-	c.common.cdw14 = cpu_to_le32(cmd.cdw14);
-	c.common.cdw15 = cpu_to_le32(cmd.cdw15);
-
-	if (cmd.timeout_ms)
-		timeout = msecs_to_jiffies(cmd.timeout_ms);
-
-	status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
-			nvme_to_user_ptr(cmd.addr), cmd.data_len,
-			nvme_to_user_ptr(cmd.metadata), cmd.metadata_len,
-			0, &result, timeout);
-
-	if (status >= 0) {
-		if (put_user(result, &ucmd->result))
-			return -EFAULT;
-	}
-
-	return status;
-}
-
-static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
-			struct nvme_passthru_cmd64 __user *ucmd)
-{
-	struct nvme_passthru_cmd64 cmd;
-	struct nvme_command c;
-	unsigned timeout = 0;
-	int status;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EACCES;
-	if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
-		return -EFAULT;
-	if (cmd.flags)
-		return -EINVAL;
-	if (ns && cmd.nsid != ns->head->ns_id) {
-		dev_err(ctrl->device,
-			"%s: nsid (%u) in cmd does not match nsid (%u) of namespace\n",
-			current->comm, cmd.nsid, ns->head->ns_id);
-		return -EINVAL;
-	}
-
-	memset(&c, 0, sizeof(c));
-	c.common.opcode = cmd.opcode;
-	c.common.flags = cmd.flags;
-	c.common.nsid = cpu_to_le32(cmd.nsid);
-	c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
-	c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
-	c.common.cdw10 = cpu_to_le32(cmd.cdw10);
-	c.common.cdw11 = cpu_to_le32(cmd.cdw11);
-	c.common.cdw12 = cpu_to_le32(cmd.cdw12);
-	c.common.cdw13 = cpu_to_le32(cmd.cdw13);
-	c.common.cdw14 = cpu_to_le32(cmd.cdw14);
-	c.common.cdw15 = cpu_to_le32(cmd.cdw15);
-
-	if (cmd.timeout_ms)
-		timeout = msecs_to_jiffies(cmd.timeout_ms);
-
-	status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
-			nvme_to_user_ptr(cmd.addr), cmd.data_len,
-			nvme_to_user_ptr(cmd.metadata), cmd.metadata_len,
-			0, &cmd.result, timeout);
-
-	if (status >= 0) {
-		if (put_user(cmd.result, &ucmd->result))
-			return -EFAULT;
-	}
-
-	return status;
-}
-
 /*
  * Issue ioctl requests on the first available path.  Note that unlike normal
  * block layer requests we will not retry failed request on another controller.
@@ -1748,85 +1478,6 @@ void nvme_put_ns_from_disk(struct nvme_ns_head *head, int idx)
 		srcu_read_unlock(&head->srcu, idx);
 }
 
-static bool is_ctrl_ioctl(unsigned int cmd)
-{
-	if (cmd == NVME_IOCTL_ADMIN_CMD || cmd == NVME_IOCTL_ADMIN64_CMD)
-		return true;
-	if (is_sed_ioctl(cmd))
-		return true;
-	return false;
-}
-
-static int nvme_ctrl_ioctl(struct nvme_ctrl *ctrl, unsigned int cmd,
-		void __user *argp)
-{
-	switch (cmd) {
-	case NVME_IOCTL_ADMIN_CMD:
-		return nvme_user_cmd(ctrl, NULL, argp);
-	case NVME_IOCTL_ADMIN64_CMD:
-		return nvme_user_cmd64(ctrl, NULL, argp);
-	default:
-		return sed_ioctl(ctrl->opal_dev, cmd, argp);
-	}
-}
-
-#ifdef COMPAT_FOR_U64_ALIGNMENT
-struct nvme_user_io32 {
-	__u8	opcode;
-	__u8	flags;
-	__u16	control;
-	__u16	nblocks;
-	__u16	rsvd;
-	__u64	metadata;
-	__u64	addr;
-	__u64	slba;
-	__u32	dsmgmt;
-	__u32	reftag;
-	__u16	apptag;
-	__u16	appmask;
-} __attribute__((__packed__));
-#define NVME_IOCTL_SUBMIT_IO32	_IOW('N', 0x42, struct nvme_user_io32)
-#endif /* COMPAT_FOR_U64_ALIGNMENT */
-
-static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
-		void __user *argp)
-{
-	switch (cmd) {
-	case NVME_IOCTL_ID:
-		force_successful_syscall_return();
-		return ns->head->ns_id;
-	case NVME_IOCTL_IO_CMD:
-		return nvme_user_cmd(ns->ctrl, ns, argp);
-	/*
-	 * struct nvme_user_io can has different padding on some 32-bit ABIs.
-	 * Just accept the compat version as all fields that are used are the
-	 * same size and at the same offset.
-	 */
-#ifdef COMPAT_FOR_U64_ALIGNMENT
-	case NVME_IOCTL_SUBMIT_IO32:
-#endif
-	case NVME_IOCTL_SUBMIT_IO:
-		return nvme_submit_io(ns, argp);
-	case NVME_IOCTL_IO64_CMD:
-		return nvme_user_cmd64(ns->ctrl, ns, argp);
-	default:
-		if (!ns->ndev)
-			return -ENOTTY;
-		return nvme_nvm_ioctl(ns, cmd, argp);
-	}
-}
-
-static 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);
-}
-
 static int nvme_open(struct block_device *bdev, fmode_t mode)
 {
 	struct nvme_ns *ns = bdev->bd_disk->private_data;
@@ -2336,7 +1987,7 @@ static void nvme_ns_head_release(struct gendisk *disk, fmode_t mode)
 	nvme_put_ns_head(disk->private_data);
 }
 
-static struct nvme_ctrl *nvme_find_get_live_ctrl(struct nvme_subsystem *subsys)
+struct nvme_ctrl *nvme_find_get_live_ctrl(struct nvme_subsystem *subsys)
 {
 	struct nvme_ctrl *ctrl;
 	int ret;
@@ -2356,42 +2007,6 @@ static struct nvme_ctrl *nvme_find_get_live_ctrl(struct nvme_subsystem *subsys)
 	return ctrl;
 }
 
-static int nvme_ns_head_ctrl_ioctl(struct nvme_ns_head *head,
-		unsigned int cmd, void __user *argp)
-{
-	struct nvme_ctrl *ctrl = nvme_find_get_live_ctrl(head->subsys);
-	int ret;
-
-	if (IS_ERR(ctrl))
-		return PTR_ERR(ctrl);
-	ret = nvme_ctrl_ioctl(ctrl, cmd, argp);
-	nvme_put_ctrl(ctrl);
-	return ret;
-}
-
-static int nvme_ns_head_ns_ioctl(struct nvme_ns_head *head,
-		unsigned int cmd, void __user *argp)
-{
-	int srcu_idx = srcu_read_lock(&head->srcu);
-	struct nvme_ns *ns = nvme_find_path(head);
-	int ret = -EWOULDBLOCK;
-
-	if (ns)
-		ret = nvme_ns_ioctl(ns, cmd, argp);
-	srcu_read_unlock(&head->srcu, srcu_idx);
-	return ret;
-}
-
-static 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);
-}
-
 const struct block_device_operations nvme_ns_head_ops = {
 	.owner		= THIS_MODULE,
 	.submit_bio	= nvme_ns_head_submit_bio,
@@ -3354,65 +2969,6 @@ static int nvme_dev_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
-static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp)
-{
-	struct nvme_ns *ns;
-	int ret;
-
-	down_read(&ctrl->namespaces_rwsem);
-	if (list_empty(&ctrl->namespaces)) {
-		ret = -ENOTTY;
-		goto out_unlock;
-	}
-
-	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;
-	}
-
-	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);
-
-	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,
-		unsigned long arg)
-{
-	struct nvme_ctrl *ctrl = file->private_data;
-	void __user *argp = (void __user *)arg;
-
-	switch (cmd) {
-	case NVME_IOCTL_ADMIN_CMD:
-		return nvme_user_cmd(ctrl, NULL, argp);
-	case NVME_IOCTL_ADMIN64_CMD:
-		return nvme_user_cmd64(ctrl, NULL, argp);
-	case NVME_IOCTL_IO_CMD:
-		return nvme_dev_user_cmd(ctrl, argp);
-	case NVME_IOCTL_RESET:
-		dev_warn(ctrl->device, "resetting controller\n");
-		return nvme_reset_ctrl_sync(ctrl);
-	case NVME_IOCTL_SUBSYS_RESET:
-		return nvme_reset_subsystem(ctrl);
-	case NVME_IOCTL_RESCAN:
-		nvme_queue_scan(ctrl);
-		return 0;
-	default:
-		return -ENOTTY;
-	}
-}
-
 static const struct file_operations nvme_dev_fops = {
 	.owner		= THIS_MODULE,
 	.open		= nvme_dev_open,
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
new file mode 100644
index 00000000000000..001faf31fb944f
--- /dev/null
+++ b/drivers/nvme/host/ioctl.c
@@ -0,0 +1,455 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2011-2014, Intel Corporation.
+ * Copyright (c) 2017-2021 Christoph Hellwig.
+ */
+#include <linux/ptrace.h>	/* for force_successful_syscall_return */
+#include <linux/nvme_ioctl.h>
+#include "nvme.h"
+
+/*
+ * Convert integer values from ioctl structures to user pointers, silently
+ * ignoring the upper bits in the compat case to match behaviour of 32-bit
+ * kernels.
+ */
+static void __user *nvme_to_user_ptr(uintptr_t ptrval)
+{
+	if (in_compat_syscall())
+		ptrval = (compat_uptr_t)ptrval;
+	return (void __user *)ptrval;
+}
+
+static void *nvme_add_user_metadata(struct bio *bio, void __user *ubuf,
+		unsigned len, u32 seed, bool write)
+{
+	struct bio_integrity_payload *bip;
+	int ret = -ENOMEM;
+	void *buf;
+
+	buf = kmalloc(len, GFP_KERNEL);
+	if (!buf)
+		goto out;
+
+	ret = -EFAULT;
+	if (write && copy_from_user(buf, ubuf, len))
+		goto out_free_meta;
+
+	bip = bio_integrity_alloc(bio, GFP_KERNEL, 1);
+	if (IS_ERR(bip)) {
+		ret = PTR_ERR(bip);
+		goto out_free_meta;
+	}
+
+	bip->bip_iter.bi_size = len;
+	bip->bip_iter.bi_sector = seed;
+	ret = bio_integrity_add_page(bio, virt_to_page(buf), len,
+			offset_in_page(buf));
+	if (ret == len)
+		return buf;
+	ret = -ENOMEM;
+out_free_meta:
+	kfree(buf);
+out:
+	return ERR_PTR(ret);
+}
+
+static int nvme_submit_user_cmd(struct request_queue *q,
+		struct nvme_command *cmd, void __user *ubuffer,
+		unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
+		u32 meta_seed, u64 *result, unsigned timeout)
+{
+	bool write = nvme_is_write(cmd);
+	struct nvme_ns *ns = q->queuedata;
+	struct block_device *bdev = ns ? ns->disk->part0 : NULL;
+	struct request *req;
+	struct bio *bio = NULL;
+	void *meta = NULL;
+	int ret;
+
+	req = nvme_alloc_request(q, cmd, 0);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	if (timeout)
+		req->timeout = timeout;
+	nvme_req(req)->flags |= NVME_REQ_USERCMD;
+
+	if (ubuffer && bufflen) {
+		ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen,
+				GFP_KERNEL);
+		if (ret)
+			goto out;
+		bio = req->bio;
+		if (bdev)
+			bio_set_dev(bio, bdev);
+		if (bdev && meta_buffer && meta_len) {
+			meta = nvme_add_user_metadata(bio, meta_buffer, meta_len,
+					meta_seed, write);
+			if (IS_ERR(meta)) {
+				ret = PTR_ERR(meta);
+				goto out_unmap;
+			}
+			req->cmd_flags |= REQ_INTEGRITY;
+		}
+	}
+
+	nvme_execute_passthru_rq(req);
+	if (nvme_req(req)->flags & NVME_REQ_CANCELLED)
+		ret = -EINTR;
+	else
+		ret = nvme_req(req)->status;
+	if (result)
+		*result = le64_to_cpu(nvme_req(req)->result.u64);
+	if (meta && !ret && !write) {
+		if (copy_to_user(meta_buffer, meta, meta_len))
+			ret = -EFAULT;
+	}
+	kfree(meta);
+ out_unmap:
+	if (bio)
+		blk_rq_unmap_user(bio);
+ out:
+	blk_mq_free_request(req);
+	return ret;
+}
+
+
+static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+{
+	struct nvme_user_io io;
+	struct nvme_command c;
+	unsigned length, meta_len;
+	void __user *metadata;
+
+	if (copy_from_user(&io, uio, sizeof(io)))
+		return -EFAULT;
+	if (io.flags)
+		return -EINVAL;
+
+	switch (io.opcode) {
+	case nvme_cmd_write:
+	case nvme_cmd_read:
+	case nvme_cmd_compare:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	length = (io.nblocks + 1) << ns->lba_shift;
+
+	if ((io.control & NVME_RW_PRINFO_PRACT) &&
+	    ns->ms == sizeof(struct t10_pi_tuple)) {
+		/*
+		 * Protection information is stripped/inserted by the
+		 * controller.
+		 */
+		if (nvme_to_user_ptr(io.metadata))
+			return -EINVAL;
+		meta_len = 0;
+		metadata = NULL;
+	} else {
+		meta_len = (io.nblocks + 1) * ns->ms;
+		metadata = nvme_to_user_ptr(io.metadata);
+	}
+
+	if (ns->features & NVME_NS_EXT_LBAS) {
+		length += meta_len;
+		meta_len = 0;
+	} else if (meta_len) {
+		if ((io.metadata & 3) || !io.metadata)
+			return -EINVAL;
+	}
+
+	memset(&c, 0, sizeof(c));
+	c.rw.opcode = io.opcode;
+	c.rw.flags = io.flags;
+	c.rw.nsid = cpu_to_le32(ns->head->ns_id);
+	c.rw.slba = cpu_to_le64(io.slba);
+	c.rw.length = cpu_to_le16(io.nblocks);
+	c.rw.control = cpu_to_le16(io.control);
+	c.rw.dsmgmt = cpu_to_le32(io.dsmgmt);
+	c.rw.reftag = cpu_to_le32(io.reftag);
+	c.rw.apptag = cpu_to_le16(io.apptag);
+	c.rw.appmask = cpu_to_le16(io.appmask);
+
+	return nvme_submit_user_cmd(ns->queue, &c,
+			nvme_to_user_ptr(io.addr), length,
+			metadata, meta_len, lower_32_bits(io.slba), NULL, 0);
+}
+
+static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+			struct nvme_passthru_cmd __user *ucmd)
+{
+	struct nvme_passthru_cmd cmd;
+	struct nvme_command c;
+	unsigned timeout = 0;
+	u64 result;
+	int status;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+	if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
+		return -EFAULT;
+	if (cmd.flags)
+		return -EINVAL;
+	if (ns && cmd.nsid != ns->head->ns_id) {
+		dev_err(ctrl->device,
+			"%s: nsid (%u) in cmd does not match nsid (%u) of namespace\n",
+			current->comm, cmd.nsid, ns->head->ns_id);
+		return -EINVAL;
+	}
+
+	memset(&c, 0, sizeof(c));
+	c.common.opcode = cmd.opcode;
+	c.common.flags = cmd.flags;
+	c.common.nsid = cpu_to_le32(cmd.nsid);
+	c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
+	c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
+	c.common.cdw10 = cpu_to_le32(cmd.cdw10);
+	c.common.cdw11 = cpu_to_le32(cmd.cdw11);
+	c.common.cdw12 = cpu_to_le32(cmd.cdw12);
+	c.common.cdw13 = cpu_to_le32(cmd.cdw13);
+	c.common.cdw14 = cpu_to_le32(cmd.cdw14);
+	c.common.cdw15 = cpu_to_le32(cmd.cdw15);
+
+	if (cmd.timeout_ms)
+		timeout = msecs_to_jiffies(cmd.timeout_ms);
+
+	status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+			nvme_to_user_ptr(cmd.addr), cmd.data_len,
+			nvme_to_user_ptr(cmd.metadata), cmd.metadata_len,
+			0, &result, timeout);
+
+	if (status >= 0) {
+		if (put_user(result, &ucmd->result))
+			return -EFAULT;
+	}
+
+	return status;
+}
+
+static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+			struct nvme_passthru_cmd64 __user *ucmd)
+{
+	struct nvme_passthru_cmd64 cmd;
+	struct nvme_command c;
+	unsigned timeout = 0;
+	int status;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+	if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
+		return -EFAULT;
+	if (cmd.flags)
+		return -EINVAL;
+	if (ns && cmd.nsid != ns->head->ns_id) {
+		dev_err(ctrl->device,
+			"%s: nsid (%u) in cmd does not match nsid (%u) of namespace\n",
+			current->comm, cmd.nsid, ns->head->ns_id);
+		return -EINVAL;
+	}
+
+	memset(&c, 0, sizeof(c));
+	c.common.opcode = cmd.opcode;
+	c.common.flags = cmd.flags;
+	c.common.nsid = cpu_to_le32(cmd.nsid);
+	c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
+	c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
+	c.common.cdw10 = cpu_to_le32(cmd.cdw10);
+	c.common.cdw11 = cpu_to_le32(cmd.cdw11);
+	c.common.cdw12 = cpu_to_le32(cmd.cdw12);
+	c.common.cdw13 = cpu_to_le32(cmd.cdw13);
+	c.common.cdw14 = cpu_to_le32(cmd.cdw14);
+	c.common.cdw15 = cpu_to_le32(cmd.cdw15);
+
+	if (cmd.timeout_ms)
+		timeout = msecs_to_jiffies(cmd.timeout_ms);
+
+	status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+			nvme_to_user_ptr(cmd.addr), cmd.data_len,
+			nvme_to_user_ptr(cmd.metadata), cmd.metadata_len,
+			0, &cmd.result, timeout);
+
+	if (status >= 0) {
+		if (put_user(cmd.result, &ucmd->result))
+			return -EFAULT;
+	}
+
+	return status;
+}
+
+static bool is_ctrl_ioctl(unsigned int cmd)
+{
+	if (cmd == NVME_IOCTL_ADMIN_CMD || cmd == NVME_IOCTL_ADMIN64_CMD)
+		return true;
+	if (is_sed_ioctl(cmd))
+		return true;
+	return false;
+}
+
+static int nvme_ctrl_ioctl(struct nvme_ctrl *ctrl, unsigned int cmd,
+		void __user *argp)
+{
+	switch (cmd) {
+	case NVME_IOCTL_ADMIN_CMD:
+		return nvme_user_cmd(ctrl, NULL, argp);
+	case NVME_IOCTL_ADMIN64_CMD:
+		return nvme_user_cmd64(ctrl, NULL, argp);
+	default:
+		return sed_ioctl(ctrl->opal_dev, cmd, argp);
+	}
+}
+
+#ifdef COMPAT_FOR_U64_ALIGNMENT
+struct nvme_user_io32 {
+	__u8	opcode;
+	__u8	flags;
+	__u16	control;
+	__u16	nblocks;
+	__u16	rsvd;
+	__u64	metadata;
+	__u64	addr;
+	__u64	slba;
+	__u32	dsmgmt;
+	__u32	reftag;
+	__u16	apptag;
+	__u16	appmask;
+} __attribute__((__packed__));
+#define NVME_IOCTL_SUBMIT_IO32	_IOW('N', 0x42, struct nvme_user_io32)
+#endif /* COMPAT_FOR_U64_ALIGNMENT */
+
+static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
+		void __user *argp)
+{
+	switch (cmd) {
+	case NVME_IOCTL_ID:
+		force_successful_syscall_return();
+		return ns->head->ns_id;
+	case NVME_IOCTL_IO_CMD:
+		return nvme_user_cmd(ns->ctrl, ns, argp);
+	/*
+	 * struct nvme_user_io can has different padding on some 32-bit ABIs.
+	 * Just accept the compat version as all fields that are used are the
+	 * same size and at the same offset.
+	 */
+#ifdef COMPAT_FOR_U64_ALIGNMENT
+	case NVME_IOCTL_SUBMIT_IO32:
+#endif
+	case NVME_IOCTL_SUBMIT_IO:
+		return nvme_submit_io(ns, argp);
+	case NVME_IOCTL_IO64_CMD:
+		return nvme_user_cmd64(ns->ctrl, ns, argp);
+	default:
+		if (!ns->ndev)
+			return -ENOTTY;
+		return nvme_nvm_ioctl(ns, cmd, argp);
+	}
+}
+
+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);
+}
+
+#ifdef CONFIG_NVME_MULTIPATH
+static int nvme_ns_head_ctrl_ioctl(struct nvme_ns_head *head,
+		unsigned int cmd, void __user *argp)
+{
+	struct nvme_ctrl *ctrl = nvme_find_get_live_ctrl(head->subsys);
+	int ret;
+
+	if (IS_ERR(ctrl))
+		return PTR_ERR(ctrl);
+	ret = nvme_ctrl_ioctl(ctrl, cmd, argp);
+	nvme_put_ctrl(ctrl);
+	return ret;
+}
+
+static int nvme_ns_head_ns_ioctl(struct nvme_ns_head *head,
+		unsigned int cmd, void __user *argp)
+{
+	int srcu_idx = srcu_read_lock(&head->srcu);
+	struct nvme_ns *ns = nvme_find_path(head);
+	int ret = -EWOULDBLOCK;
+
+	if (ns)
+		ret = nvme_ns_ioctl(ns, cmd, argp);
+	srcu_read_unlock(&head->srcu, srcu_idx);
+	return ret;
+}
+
+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);
+}
+#endif /* CONFIG_NVME_MULTIPATH */
+
+static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp)
+{
+	struct nvme_ns *ns;
+	int ret;
+
+	down_read(&ctrl->namespaces_rwsem);
+	if (list_empty(&ctrl->namespaces)) {
+		ret = -ENOTTY;
+		goto out_unlock;
+	}
+
+	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;
+	}
+
+	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);
+
+	ret = nvme_user_cmd(ctrl, ns, argp);
+	nvme_put_ns(ns);
+	return ret;
+
+out_unlock:
+	up_read(&ctrl->namespaces_rwsem);
+	return ret;
+}
+
+long nvme_dev_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg)
+{
+	struct nvme_ctrl *ctrl = file->private_data;
+	void __user *argp = (void __user *)arg;
+
+	switch (cmd) {
+	case NVME_IOCTL_ADMIN_CMD:
+		return nvme_user_cmd(ctrl, NULL, argp);
+	case NVME_IOCTL_ADMIN64_CMD:
+		return nvme_user_cmd64(ctrl, NULL, argp);
+	case NVME_IOCTL_IO_CMD:
+		return nvme_dev_user_cmd(ctrl, argp);
+	case NVME_IOCTL_RESET:
+		dev_warn(ctrl->device, "resetting controller\n");
+		return nvme_reset_ctrl_sync(ctrl);
+	case NVME_IOCTL_SUBSYS_RESET:
+		return nvme_reset_subsystem(ctrl);
+	case NVME_IOCTL_RESCAN:
+		nvme_queue_scan(ctrl);
+		return 0;
+	default:
+		return -ENOTTY;
+	}
+}
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 70018ae2cb1876..d41c9ceeafa1b8 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -647,14 +647,22 @@ int nvme_get_features(struct nvme_ctrl *dev, unsigned int fid,
 int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count);
 void nvme_stop_keep_alive(struct nvme_ctrl *ctrl);
 int nvme_reset_ctrl(struct nvme_ctrl *ctrl);
+int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl);
 int nvme_try_sched_reset(struct nvme_ctrl *ctrl);
 int nvme_delete_ctrl(struct nvme_ctrl *ctrl);
-
+void nvme_queue_scan(struct nvme_ctrl *ctrl);
 int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi,
 		void *log, size_t size, u64 offset);
 struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk,
 		struct nvme_ns_head **head, int *srcu_idx);
 void nvme_put_ns_from_disk(struct nvme_ns_head *head, int idx);
+struct nvme_ctrl *nvme_find_get_live_ctrl(struct nvme_subsystem *subsys);
+int nvme_ioctl(struct block_device *bdev, fmode_t mode,
+		unsigned int cmd, unsigned long arg);
+int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
+		unsigned int cmd, unsigned long arg);
+long nvme_dev_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg);
 
 extern const struct attribute_group *nvme_ns_id_attr_groups[];
 extern const struct block_device_operations nvme_ns_head_ops;
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (7 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 08/13] nvme: move the ioctl code to a separate file Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-09  2:46     ` Chaitanya Kulkarni
  2021-04-09  9:18     ` Kanchan Joshi
  2021-04-08 12:08   ` [PATCH 10/13] nvme: move nvme_ns_head_ops to multipath.c Christoph Hellwig
                     ` (6 subsequent siblings)
  15 siblings, 2 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Add a helper to avoid opencoding ns_head->ref manipulations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 98d87bff4ca37f..9637f2e5e9232c 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -549,6 +549,11 @@ static void nvme_free_ns_head(struct kref *ref)
 	kfree(head);
 }
 
+static bool nvme_tryget_ns_head(struct nvme_ns_head *head)
+{
+	return kref_get_unless_zero(&head->ref);
+}
+
 static void nvme_put_ns_head(struct nvme_ns_head *head)
 {
 	kref_put(&head->ref, nvme_free_ns_head);
@@ -1975,9 +1980,7 @@ static const struct block_device_operations nvme_bdev_ops = {
 #ifdef CONFIG_NVME_MULTIPATH
 static int nvme_ns_head_open(struct block_device *bdev, fmode_t mode)
 {
-	struct nvme_ns_head *head = bdev->bd_disk->private_data;
-
-	if (!kref_get_unless_zero(&head->ref))
+	if (!nvme_tryget_ns_head(bdev->bd_disk->private_data))
 		return -ENXIO;
 	return 0;
 }
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 10/13] nvme: move nvme_ns_head_ops to multipath.c
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (8 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-09  2:47     ` Chaitanya Kulkarni
  2021-04-08 12:08   ` [PATCH 11/13] nvme: factor out nvme_ns_open and nvme_ns_release helpers Christoph Hellwig
                     ` (5 subsequent siblings)
  15 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Move the multipath block_device_operations to multipath.c, where they
belong.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c      | 31 ++++---------------------------
 drivers/nvme/host/multipath.c | 25 ++++++++++++++++++++++++-
 drivers/nvme/host/nvme.h      |  5 ++++-
 3 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 9637f2e5e9232c..0072df1dfd54c7 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -549,12 +549,12 @@ static void nvme_free_ns_head(struct kref *ref)
 	kfree(head);
 }
 
-static bool nvme_tryget_ns_head(struct nvme_ns_head *head)
+bool nvme_tryget_ns_head(struct nvme_ns_head *head)
 {
 	return kref_get_unless_zero(&head->ref);
 }
 
-static void nvme_put_ns_head(struct nvme_ns_head *head)
+void nvme_put_ns_head(struct nvme_ns_head *head)
 {
 	kref_put(&head->ref, nvme_free_ns_head);
 }
@@ -1511,7 +1511,7 @@ static void nvme_release(struct gendisk *disk, fmode_t mode)
 	nvme_put_ns(ns);
 }
 
-static int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
 	/* some standard values */
 	geo->heads = 1 << 6;
@@ -1937,7 +1937,7 @@ static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type
 	return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
 }
 
-static const struct pr_ops nvme_pr_ops = {
+const struct pr_ops nvme_pr_ops = {
 	.pr_register	= nvme_pr_register,
 	.pr_reserve	= nvme_pr_reserve,
 	.pr_release	= nvme_pr_release,
@@ -1978,18 +1978,6 @@ static const struct block_device_operations nvme_bdev_ops = {
 };
 
 #ifdef CONFIG_NVME_MULTIPATH
-static int nvme_ns_head_open(struct block_device *bdev, fmode_t mode)
-{
-	if (!nvme_tryget_ns_head(bdev->bd_disk->private_data))
-		return -ENXIO;
-	return 0;
-}
-
-static void nvme_ns_head_release(struct gendisk *disk, fmode_t mode)
-{
-	nvme_put_ns_head(disk->private_data);
-}
-
 struct nvme_ctrl *nvme_find_get_live_ctrl(struct nvme_subsystem *subsys)
 {
 	struct nvme_ctrl *ctrl;
@@ -2009,17 +1997,6 @@ struct nvme_ctrl *nvme_find_get_live_ctrl(struct nvme_subsystem *subsys)
 	mutex_unlock(&nvme_subsystems_lock);
 	return ctrl;
 }
-
-const struct block_device_operations nvme_ns_head_ops = {
-	.owner		= THIS_MODULE,
-	.submit_bio	= nvme_ns_head_submit_bio,
-	.open		= nvme_ns_head_open,
-	.release	= nvme_ns_head_release,
-	.ioctl		= nvme_ns_head_ioctl,
-	.getgeo		= nvme_getgeo,
-	.report_zones	= nvme_report_zones,
-	.pr_ops		= &nvme_pr_ops,
-};
 #endif /* CONFIG_NVME_MULTIPATH */
 
 static int nvme_wait_ready(struct nvme_ctrl *ctrl, u64 cap, bool enabled)
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 0f42b7e94ce3f3..2bbc1685799d44 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -294,7 +294,7 @@ static bool nvme_available_path(struct nvme_ns_head *head)
 	return false;
 }
 
-blk_qc_t nvme_ns_head_submit_bio(struct bio *bio)
+static blk_qc_t nvme_ns_head_submit_bio(struct bio *bio)
 {
 	struct nvme_ns_head *head = bio->bi_bdev->bd_disk->private_data;
 	struct device *dev = disk_to_dev(head->disk);
@@ -334,6 +334,29 @@ blk_qc_t nvme_ns_head_submit_bio(struct bio *bio)
 	return ret;
 }
 
+static int nvme_ns_head_open(struct block_device *bdev, fmode_t mode)
+{
+	if (!nvme_tryget_ns_head(bdev->bd_disk->private_data))
+		return -ENXIO;
+	return 0;
+}
+
+static void nvme_ns_head_release(struct gendisk *disk, fmode_t mode)
+{
+	nvme_put_ns_head(disk->private_data);
+}
+
+const struct block_device_operations nvme_ns_head_ops = {
+	.owner		= THIS_MODULE,
+	.submit_bio	= nvme_ns_head_submit_bio,
+	.open		= nvme_ns_head_open,
+	.release	= nvme_ns_head_release,
+	.ioctl		= nvme_ns_head_ioctl,
+	.getgeo		= nvme_getgeo,
+	.report_zones	= nvme_report_zones,
+	.pr_ops		= &nvme_pr_ops,
+};
+
 static void nvme_requeue_work(struct work_struct *work)
 {
 	struct nvme_ns_head *head =
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index d41c9ceeafa1b8..c6102ce83bb405 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -656,6 +656,8 @@ int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi,
 struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk,
 		struct nvme_ns_head **head, int *srcu_idx);
 void nvme_put_ns_from_disk(struct nvme_ns_head *head, int idx);
+bool nvme_tryget_ns_head(struct nvme_ns_head *head);
+void nvme_put_ns_head(struct nvme_ns_head *head);
 struct nvme_ctrl *nvme_find_get_live_ctrl(struct nvme_subsystem *subsys);
 int nvme_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg);
@@ -663,8 +665,10 @@ int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg);
 long nvme_dev_ioctl(struct file *file, unsigned int cmd,
 		unsigned long arg);
+int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
 extern const struct attribute_group *nvme_ns_id_attr_groups[];
+extern const struct pr_ops nvme_pr_ops;
 extern const struct block_device_operations nvme_ns_head_ops;
 
 #ifdef CONFIG_NVME_MULTIPATH
@@ -688,7 +692,6 @@ void nvme_mpath_stop(struct nvme_ctrl *ctrl);
 bool nvme_mpath_clear_current_path(struct nvme_ns *ns);
 void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl);
 struct nvme_ns *nvme_find_path(struct nvme_ns_head *head);
-blk_qc_t nvme_ns_head_submit_bio(struct bio *bio);
 
 static inline void nvme_mpath_check_last_path(struct nvme_ns *ns)
 {
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 11/13] nvme: factor out nvme_ns_open and nvme_ns_release helpers
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (9 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 10/13] nvme: move nvme_ns_head_ops to multipath.c Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-09  2:48     ` Chaitanya Kulkarni
  2021-04-08 12:08   ` [PATCH 12/13] nvme: let namespace probing continue for unsupported features Christoph Hellwig
                     ` (4 subsequent siblings)
  15 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

These will be reused for the per-namespace character devices.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 0072df1dfd54c7..7ebe0225e01412 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1483,9 +1483,8 @@ void nvme_put_ns_from_disk(struct nvme_ns_head *head, int idx)
 		srcu_read_unlock(&head->srcu, idx);
 }
 
-static int nvme_open(struct block_device *bdev, fmode_t mode)
+static int nvme_ns_open(struct nvme_ns *ns)
 {
-	struct nvme_ns *ns = bdev->bd_disk->private_data;
 
 	/* should never be called due to GENHD_FL_HIDDEN */
 	if (WARN_ON_ONCE(nvme_ns_head_multipath(ns->head)))
@@ -1503,14 +1502,23 @@ static int nvme_open(struct block_device *bdev, fmode_t mode)
 	return -ENXIO;
 }
 
-static void nvme_release(struct gendisk *disk, fmode_t mode)
+static void nvme_ns_release(struct nvme_ns *ns)
 {
-	struct nvme_ns *ns = disk->private_data;
 
 	module_put(ns->ctrl->ops->module);
 	nvme_put_ns(ns);
 }
 
+static int nvme_open(struct block_device *bdev, fmode_t mode)
+{
+	return nvme_ns_open(bdev->bd_disk->private_data);
+}
+
+static void nvme_release(struct gendisk *disk, fmode_t mode)
+{
+	nvme_ns_release(disk->private_data);
+}
+
 int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
 	/* some standard values */
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 12/13] nvme: let namespace probing continue for unsupported features
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (10 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 11/13] nvme: factor out nvme_ns_open and nvme_ns_release helpers Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-08 22:42     ` Keith Busch
  2021-04-08 12:08   ` [PATCH 13/13] nvme: introduce generic per-namespace chardev Christoph Hellwig
                     ` (3 subsequent siblings)
  15 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

Instead of failing to scan the namespace entirely when unsupported
features are detected, just mark the gendisk hidden but allow other
access like the upcoming per-namespace character device.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c | 11 ++++++++++-
 drivers/nvme/host/zns.c  |  4 ++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 7ebe0225e01412..eba676b260b820 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1832,7 +1832,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
 	if (blk_queue_is_zoned(ns->queue)) {
 		ret = nvme_revalidate_zones(ns);
 		if (ret && !nvme_first_scan(ns->disk))
-			return ret;
+			goto out;
 	}
 
 	if (nvme_ns_head_multipath(ns->head)) {
@@ -1847,6 +1847,15 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
 
 out_unfreeze:
 	blk_mq_unfreeze_queue(ns->disk->queue);
+out:
+	/*
+	 * If probing fails due an unsupported feature, hide the block device,
+	 * but still allow other access.
+	 */
+	if (ret == -ENODEV) {
+		ns->disk->flags |= GENHD_FL_HIDDEN;
+		ret = 0;
+	}
 	return ret;
 }
 
diff --git a/drivers/nvme/host/zns.c b/drivers/nvme/host/zns.c
index bc2f344f0ae018..475dd45c3db49b 100644
--- a/drivers/nvme/host/zns.c
+++ b/drivers/nvme/host/zns.c
@@ -96,7 +96,7 @@ int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf)
 		dev_warn(ns->ctrl->device,
 			"zone operations:%x not supported for namespace:%u\n",
 			le16_to_cpu(id->zoc), ns->head->ns_id);
-		status = -EINVAL;
+		status = -ENODEV;
 		goto free_data;
 	}
 
@@ -105,7 +105,7 @@ int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf)
 		dev_warn(ns->ctrl->device,
 			"invalid zone size:%llu for namespace:%u\n",
 			ns->zsze, ns->head->ns_id);
-		status = -EINVAL;
+		status = -ENODEV;
 		goto free_data;
 	}
 
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (11 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 12/13] nvme: let namespace probing continue for unsupported features Christoph Hellwig
@ 2021-04-08 12:08   ` Christoph Hellwig
  2021-04-08 16:56     ` Keith Busch
  2021-04-09  7:29     ` Minwoo Im
  2021-04-08 22:43   ` nvme ioctl refactor and generic per-namespace char device Keith Busch
                     ` (2 subsequent siblings)
  15 siblings, 2 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 12:08 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

From: Minwoo Im <minwoo.im.dev@gmail.com>

Userspace has not been allowed to I/O to device that's failed to
be initialized.  This patch introduces generic per-namespace character
device to allow userspace to I/O regardless the block device is there or
not.

The chardev naming convention will similar to the existing blkdev naming,
using a ng prefix instead of nvme, i.e.

	- /dev/ngXnY

It also supports multipath which means it will not expose chardev for the
hidden namespace blkdevs (e.g., nvmeXcYnZ).  If /dev/ngXnY is created for
a ns_head, then I/O request will be routed to a specific controller
selected by the iopolicy of the subsystem.

Signed-off-by: Minwoo Im <minwoo.im.dev@gmail.com>
Signed-off-by: Javier González <javier.gonz@samsung.com>
[hch: rebased on top of the ioctl cleanups, split the ns_head and ns
 implementations]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c      | 81 +++++++++++++++++++++++++++++++++++
 drivers/nvme/host/ioctl.c     | 17 ++++++++
 drivers/nvme/host/multipath.c | 51 ++++++++++++++++++++--
 drivers/nvme/host/nvme.h      | 12 ++++++
 4 files changed, 158 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index eba676b260b820..fa8bddc31442a3 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -89,6 +89,10 @@ static dev_t nvme_ctrl_base_chr_devt;
 static struct class *nvme_class;
 static struct class *nvme_subsys_class;
 
+static DEFINE_IDA(nvme_ns_chr_minor_ida);
+static dev_t nvme_ns_chr_devt;
+static struct class *nvme_ns_chr_class;
+
 static void nvme_put_subsystem(struct nvme_subsystem *subsys);
 static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
 					   unsigned nsid);
@@ -3424,6 +3428,60 @@ static int __nvme_check_ids(struct nvme_subsystem *subsys,
 	return 0;
 }
 
+int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device,
+		const struct file_operations *fops, struct module *owner)
+{
+	int minor, ret;
+
+	minor = ida_simple_get(&nvme_ns_chr_minor_ida, 0, 0, GFP_KERNEL);
+	if (minor < 0)
+		return minor;
+	cdev_device->devt = MKDEV(MAJOR(nvme_ns_chr_devt), minor);
+	cdev_device->class = nvme_ns_chr_class;
+	device_initialize(cdev_device);
+	cdev_init(cdev, fops);
+	cdev->owner = owner;
+	ret = cdev_device_add(cdev, cdev_device);
+	if (ret)
+		ida_simple_remove(&nvme_ns_chr_minor_ida, minor);
+	return ret;
+}
+
+static int nvme_ns_chr_open(struct inode *inode, struct file *file)
+{
+	return nvme_ns_open(container_of(inode->i_cdev, struct nvme_ns, cdev));
+}
+
+static int nvme_ns_chr_release(struct inode *inode, struct file *file)
+{
+	nvme_ns_release(container_of(inode->i_cdev, struct nvme_ns, cdev));
+	return 0;
+}
+
+static const struct file_operations nvme_ns_chr_fops = {
+	.owner		= THIS_MODULE,
+	.open		= nvme_ns_chr_open,
+	.release	= nvme_ns_chr_release,
+	.unlocked_ioctl	= nvme_ns_chr_ioctl,
+	.compat_ioctl	= compat_ptr_ioctl,
+};
+
+static int nvme_add_ns_cdev(struct nvme_ns *ns)
+{
+	int ret;
+
+	ns->cdev_device.parent = ns->ctrl->device;
+	ret = dev_set_name(&ns->cdev_device, "ng%dn%d",
+			   ns->ctrl->instance, ns->head->instance);
+	if (ret)
+		return ret;
+	ret = nvme_cdev_add(&ns->cdev, &ns->cdev_device, &nvme_ns_chr_fops,
+			    ns->ctrl->ops->module);
+	if (ret)
+		kfree_const(ns->cdev_device.kobj.name);
+	return ret;
+}
+
 static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
 		unsigned nsid, struct nvme_ns_ids *ids)
 {
@@ -3625,6 +3683,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
 	nvme_get_ctrl(ctrl);
 
 	device_add_disk(ctrl->device, ns->disk, nvme_ns_id_attr_groups);
+	if (!nvme_ns_head_multipath(ns->head))
+		nvme_add_ns_cdev(ns);
 
 	nvme_mpath_add_disk(ns, id);
 	nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name);
@@ -3669,6 +3729,8 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 	synchronize_srcu(&ns->head->srcu); /* wait for concurrent submissions */
 
 	if (ns->disk->flags & GENHD_FL_UP) {
+		if (!nvme_ns_head_multipath(ns->head))
+			cdev_device_del(&ns->cdev, &ns->cdev_device);
 		del_gendisk(ns->disk);
 		blk_cleanup_queue(ns->queue);
 		if (blk_get_integrity(ns->disk))
@@ -4459,8 +4521,24 @@ static int __init nvme_core_init(void)
 		result = PTR_ERR(nvme_subsys_class);
 		goto destroy_class;
 	}
+
+	result = alloc_chrdev_region(&nvme_ns_chr_devt, 0, NVME_MINORS,
+				     "nvme-generic");
+	if (result < 0)
+		goto destroy_subsys_class;
+
+	nvme_ns_chr_class = class_create(THIS_MODULE, "nvme-generic");
+	if (IS_ERR(nvme_ns_chr_class)) {
+		result = PTR_ERR(nvme_ns_chr_class);
+		goto unregister_generic_ns;
+	}
+
 	return 0;
 
+unregister_generic_ns:
+	unregister_chrdev_region(nvme_ns_chr_devt, NVME_MINORS);
+destroy_subsys_class:
+	class_destroy(nvme_subsys_class);
 destroy_class:
 	class_destroy(nvme_class);
 unregister_chrdev:
@@ -4477,12 +4555,15 @@ static int __init nvme_core_init(void)
 
 static void __exit nvme_core_exit(void)
 {
+	class_destroy(nvme_ns_chr_class);
 	class_destroy(nvme_subsys_class);
 	class_destroy(nvme_class);
+	unregister_chrdev_region(nvme_ns_chr_devt, NVME_MINORS);
 	unregister_chrdev_region(nvme_ctrl_base_chr_devt, NVME_MINORS);
 	destroy_workqueue(nvme_delete_wq);
 	destroy_workqueue(nvme_reset_wq);
 	destroy_workqueue(nvme_wq);
+	ida_destroy(&nvme_ns_chr_minor_ida);
 	ida_destroy(&nvme_instance_ida);
 }
 
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 */
 
 static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp)
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 2bbc1685799d44..40c6cc989e373a 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -357,6 +357,48 @@ const struct block_device_operations nvme_ns_head_ops = {
 	.pr_ops		= &nvme_pr_ops,
 };
 
+static inline struct nvme_ns_head *cdev_to_ns_head(struct cdev *cdev)
+{
+	return container_of(cdev, struct nvme_ns_head, cdev);
+}
+
+static int nvme_ns_head_chr_open(struct inode *inode, struct file *file)
+{
+	if (!nvme_tryget_ns_head(cdev_to_ns_head(inode->i_cdev)))
+		return -ENXIO;
+	return 0;
+}
+
+static int nvme_ns_head_chr_release(struct inode *inode, struct file *file)
+{
+	nvme_put_ns_head(cdev_to_ns_head(inode->i_cdev));
+	return 0;
+}
+
+static const struct file_operations nvme_ns_head_chr_fops = {
+	.owner		= THIS_MODULE,
+	.open		= nvme_ns_head_chr_open,
+	.release	= nvme_ns_head_chr_release,
+	.unlocked_ioctl	= nvme_ns_head_chr_ioctl,
+	.compat_ioctl	= compat_ptr_ioctl,
+};
+
+static int nvme_add_ns_head_cdev(struct nvme_ns_head *head)
+{
+	int ret;
+
+	head->cdev_device.parent = &head->subsys->dev;
+	ret = dev_set_name(&head->cdev_device, "ng%dn%d",
+			   head->subsys->instance, head->instance);
+	if (ret)
+		return ret;
+	ret = nvme_cdev_add(&head->cdev, &head->cdev_device,
+			    &nvme_ns_head_chr_fops, THIS_MODULE);
+	if (ret)
+		kfree_const(head->cdev_device.kobj.name);
+	return ret;
+}
+
 static void nvme_requeue_work(struct work_struct *work)
 {
 	struct nvme_ns_head *head =
@@ -435,9 +477,11 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
 	if (!head->disk)
 		return;
 
-	if (!test_and_set_bit(NVME_NSHEAD_DISK_LIVE, &head->flags))
+	if (!test_and_set_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) {
 		device_add_disk(&head->subsys->dev, head->disk,
 				nvme_ns_id_attr_groups);
+		nvme_add_ns_head_cdev(head);
+	}
 
 	mutex_lock(&head->lock);
 	if (nvme_path_is_optimized(ns)) {
@@ -714,8 +758,10 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
 {
 	if (!head->disk)
 		return;
-	if (head->disk->flags & GENHD_FL_UP)
+	if (head->disk->flags & GENHD_FL_UP) {
+		cdev_device_del(&head->cdev, &head->cdev_device);
 		del_gendisk(head->disk);
+	}
 	blk_set_queue_dying(head->disk->queue);
 	/* make sure all pending bios are cleaned up */
 	kblockd_schedule_work(&head->requeue_work);
@@ -785,4 +831,3 @@ void nvme_mpath_uninit(struct nvme_ctrl *ctrl)
 	kfree(ctrl->ana_log_buf);
 	ctrl->ana_log_buf = NULL;
 }
-
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index c6102ce83bb405..d34e29d76abb54 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -413,6 +413,10 @@ struct nvme_ns_head {
 	bool			shared;
 	int			instance;
 	struct nvme_effects_log *effects;
+
+	struct cdev		cdev;
+	struct device		cdev_device;
+
 	struct gendisk		*disk;
 #ifdef CONFIG_NVME_MULTIPATH
 	struct bio_list		requeue_list;
@@ -465,6 +469,9 @@ struct nvme_ns {
 #define NVME_NS_ANA_PENDING	2
 #define NVME_NS_FORCE_RO	3
 
+	struct cdev		cdev;
+	struct device		cdev_device;
+
 	struct nvme_fault_inject fault_inject;
 
 };
@@ -659,10 +666,15 @@ void nvme_put_ns_from_disk(struct nvme_ns_head *head, int idx);
 bool nvme_tryget_ns_head(struct nvme_ns_head *head);
 void nvme_put_ns_head(struct nvme_ns_head *head);
 struct nvme_ctrl *nvme_find_get_live_ctrl(struct nvme_subsystem *subsys);
+int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device,
+		const struct file_operations *fops, struct module *owner);
 int nvme_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg);
+long nvme_ns_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg);
+long nvme_ns_head_chr_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg);
 long nvme_dev_ioctl(struct file *file, unsigned int cmd,
 		unsigned long arg);
 int nvme_getgeo(struct block_device *bdev, struct hd_geometry *geo);
-- 
2.30.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-08 12:08   ` [PATCH 13/13] nvme: introduce generic per-namespace chardev Christoph Hellwig
@ 2021-04-08 16:56     ` Keith Busch
  2021-04-08 17:00       ` Christoph Hellwig
  2021-04-09  6:14       ` Christoph Hellwig
  2021-04-09  7:29     ` Minwoo Im
  1 sibling, 2 replies; 45+ messages in thread
From: Keith Busch @ 2021-04-08 16:56 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minwoo Im, Sagi Grimberg, Kanchan Joshi, Javier Gonz??lez, linux-nvme

On Thu, Apr 08, 2021 at 02:08:42PM +0200, Christoph Hellwig wrote:
> +int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device,
> +		const struct file_operations *fops, struct module *owner)
> +{
> +	int minor, ret;
> +
> +	minor = ida_simple_get(&nvme_ns_chr_minor_ida, 0, 0, GFP_KERNEL);

Do we really need to allocate a minor specific for this char dev? It
looks like the ns->head->instance can provide the unique value.

> +	if (minor < 0)
> +		return minor;
> +	cdev_device->devt = MKDEV(MAJOR(nvme_ns_chr_devt), minor);

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-08 16:56     ` Keith Busch
@ 2021-04-08 17:00       ` Christoph Hellwig
  2021-04-09  6:14       ` Christoph Hellwig
  1 sibling, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-08 17:00 UTC (permalink / raw)
  To: Keith Busch
  Cc: Christoph Hellwig, Minwoo Im, Sagi Grimberg, Kanchan Joshi,
	Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 01:56:13AM +0900, Keith Busch wrote:
> On Thu, Apr 08, 2021 at 02:08:42PM +0200, Christoph Hellwig wrote:
> > +int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device,
> > +		const struct file_operations *fops, struct module *owner)
> > +{
> > +	int minor, ret;
> > +
> > +	minor = ida_simple_get(&nvme_ns_chr_minor_ida, 0, 0, GFP_KERNEL);
> 
> Do we really need to allocate a minor specific for this char dev? It
> looks like the ns->head->instance can provide the unique value.

Indeed.  I think we can just kill off this IDA, let me give that a spin.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 12/13] nvme: let namespace probing continue for unsupported features
  2021-04-08 12:08   ` [PATCH 12/13] nvme: let namespace probing continue for unsupported features Christoph Hellwig
@ 2021-04-08 22:42     ` Keith Busch
  2021-04-09  5:39       ` Christoph Hellwig
  0 siblings, 1 reply; 45+ messages in thread
From: Keith Busch @ 2021-04-08 22:42 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minwoo Im, Sagi Grimberg, Kanchan Joshi, Javier Gonz??lez, linux-nvme

On Thu, Apr 08, 2021 at 02:08:41PM +0200, Christoph Hellwig wrote:
> Instead of failing to scan the namespace entirely when unsupported
> features are detected, just mark the gendisk hidden but allow other
> access like the upcoming per-namespace character device.

This part looks fine for what it is, but I thought we were going even
further by allocating a namespace for the generic char device even if
its Command Set Indicator was unsupported by the kernel.
 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  drivers/nvme/host/core.c | 11 ++++++++++-
>  drivers/nvme/host/zns.c  |  4 ++--
>  2 files changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 7ebe0225e01412..eba676b260b820 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -1832,7 +1832,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
>  	if (blk_queue_is_zoned(ns->queue)) {
>  		ret = nvme_revalidate_zones(ns);
>  		if (ret && !nvme_first_scan(ns->disk))
> -			return ret;
> +			goto out;
>  	}
>  
>  	if (nvme_ns_head_multipath(ns->head)) {
> @@ -1847,6 +1847,15 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
>  
>  out_unfreeze:
>  	blk_mq_unfreeze_queue(ns->disk->queue);
> +out:
> +	/*
> +	 * If probing fails due an unsupported feature, hide the block device,
> +	 * but still allow other access.
> +	 */
> +	if (ret == -ENODEV) {
> +		ns->disk->flags |= GENHD_FL_HIDDEN;
> +		ret = 0;
> +	}
>  	return ret;
>  }
>  
> diff --git a/drivers/nvme/host/zns.c b/drivers/nvme/host/zns.c
> index bc2f344f0ae018..475dd45c3db49b 100644
> --- a/drivers/nvme/host/zns.c
> +++ b/drivers/nvme/host/zns.c
> @@ -96,7 +96,7 @@ int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf)
>  		dev_warn(ns->ctrl->device,
>  			"zone operations:%x not supported for namespace:%u\n",
>  			le16_to_cpu(id->zoc), ns->head->ns_id);
> -		status = -EINVAL;
> +		status = -ENODEV;
>  		goto free_data;
>  	}
>  
> @@ -105,7 +105,7 @@ int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf)
>  		dev_warn(ns->ctrl->device,
>  			"invalid zone size:%llu for namespace:%u\n",
>  			ns->zsze, ns->head->ns_id);
> -		status = -EINVAL;
> +		status = -ENODEV;
>  		goto free_data;
>  	}
>  
> -- 

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: nvme ioctl refactor and generic per-namespace char device
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (12 preceding siblings ...)
  2021-04-08 12:08   ` [PATCH 13/13] nvme: introduce generic per-namespace chardev Christoph Hellwig
@ 2021-04-08 22:43   ` Keith Busch
  2021-04-09 17:45   ` Javier Gonz??lez
  2021-04-10  6:46   ` Christoph Hellwig
  15 siblings, 0 replies; 45+ messages in thread
From: Keith Busch @ 2021-04-08 22:43 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minwoo Im, Sagi Grimberg, Kanchan Joshi, Javier Gonz??lez, linux-nvme

On Thu, Apr 08, 2021 at 02:08:29PM +0200, Christoph Hellwig wrote:
> Hi all,
> 
> this series picks up the generic per-namespace character device
> from Minwoo and Javier with a few small fixed, but rebases them on
> an ioctl refactoring I had pending, which cleans up a lot of the
> lower level code.

Patches 1-12 look good.

Reviewed-by: Keith Busch <kbusch@kernel.org>

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 01/13] nvme: add a nvme_ns_head_multipath helper
  2021-04-08 12:08   ` [PATCH 01/13] nvme: add a nvme_ns_head_multipath helper Christoph Hellwig
@ 2021-04-09  2:33     ` Chaitanya Kulkarni
  0 siblings, 0 replies; 45+ messages in thread
From: Chaitanya Kulkarni @ 2021-04-09  2:33 UTC (permalink / raw)
  To: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

On 4/8/21 05:22, Christoph Hellwig wrote:
> From: Minwoo Im <minwoo.im.dev@gmail.com>
>
> Move the multipath gendisk out of #ifdef CONFIG_NVME_MULTIPATH and add
> a new nvme_ns_head_multipath that uses it to check if a ns_head has
> a multipath device associated with it.
>
> Signed-off-by: Minwoo Im <minwoo.im.dev@gmail.com>
> [hch: added the IS_ENABLED, converted a few existing users]
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Looks good.

Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>



_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 04/13] nvme: factor out a nvme_ns_ioctl helper
  2021-04-08 12:08   ` [PATCH 04/13] nvme: factor out a nvme_ns_ioctl helper Christoph Hellwig
@ 2021-04-09  2:40     ` Chaitanya Kulkarni
  0 siblings, 0 replies; 45+ messages in thread
From: Chaitanya Kulkarni @ 2021-04-09  2:40 UTC (permalink / raw)
  To: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

On 4/8/21 05:31, Christoph Hellwig wrote:
> Factor out a helper for the namespace based ioctls.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Looks good.

Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>



_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 05/13] nvme: simplify the compat ioctl handling
  2021-04-08 12:08   ` [PATCH 05/13] nvme: simplify the compat ioctl handling Christoph Hellwig
@ 2021-04-09  2:42     ` Chaitanya Kulkarni
  2021-04-09  5:39       ` Christoph Hellwig
  0 siblings, 1 reply; 45+ messages in thread
From: Chaitanya Kulkarni @ 2021-04-09  2:42 UTC (permalink / raw)
  To: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

On 4/8/21 05:32, Christoph Hellwig wrote:
> +	 * struct nvme_user_io can has different padding on some 32-bit ABIs.

s/can has/can have/ ?


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 08/13] nvme: move the ioctl code to a separate file
  2021-04-08 12:08   ` [PATCH 08/13] nvme: move the ioctl code to a separate file Christoph Hellwig
@ 2021-04-09  2:45     ` Chaitanya Kulkarni
  0 siblings, 0 replies; 45+ messages in thread
From: Chaitanya Kulkarni @ 2021-04-09  2:45 UTC (permalink / raw)
  To: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

On 4/8/21 05:35, Christoph Hellwig wrote:
> Split out the ioctl code from core.c into a new file.  Also update
> copyrights while we're at it.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---

Looks good.

Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>



_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper
  2021-04-08 12:08   ` [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper Christoph Hellwig
@ 2021-04-09  2:46     ` Chaitanya Kulkarni
  2021-04-09  5:39       ` Christoph Hellwig
  2021-04-09  9:18     ` Kanchan Joshi
  1 sibling, 1 reply; 45+ messages in thread
From: Chaitanya Kulkarni @ 2021-04-09  2:46 UTC (permalink / raw)
  To: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

On 4/8/21 05:35, Christoph Hellwig wrote:
> Add a helper to avoid opencoding ns_head->ref manipulations.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Should we wait to have a second user for this ? unless it is there
in next patches in this series.

In any case, looks good.

Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>



_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 10/13] nvme: move nvme_ns_head_ops to multipath.c
  2021-04-08 12:08   ` [PATCH 10/13] nvme: move nvme_ns_head_ops to multipath.c Christoph Hellwig
@ 2021-04-09  2:47     ` Chaitanya Kulkarni
  0 siblings, 0 replies; 45+ messages in thread
From: Chaitanya Kulkarni @ 2021-04-09  2:47 UTC (permalink / raw)
  To: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

On 4/8/21 05:34, Christoph Hellwig wrote:
> Move the multipath block_device_operations to multipath.c, where they
> belong.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Looks good.

Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>



_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 11/13] nvme: factor out nvme_ns_open and nvme_ns_release helpers
  2021-04-08 12:08   ` [PATCH 11/13] nvme: factor out nvme_ns_open and nvme_ns_release helpers Christoph Hellwig
@ 2021-04-09  2:48     ` Chaitanya Kulkarni
  0 siblings, 0 replies; 45+ messages in thread
From: Chaitanya Kulkarni @ 2021-04-09  2:48 UTC (permalink / raw)
  To: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

On 4/8/21 05:35, Christoph Hellwig wrote:
> These will be reused for the per-namespace character devices.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Looks good.

Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>



_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 12/13] nvme: let namespace probing continue for unsupported features
  2021-04-08 22:42     ` Keith Busch
@ 2021-04-09  5:39       ` Christoph Hellwig
  2021-04-09  5:47         ` Keith Busch
  0 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-09  5:39 UTC (permalink / raw)
  To: Keith Busch
  Cc: Christoph Hellwig, Minwoo Im, Sagi Grimberg, Kanchan Joshi,
	Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 07:42:59AM +0900, Keith Busch wrote:
> On Thu, Apr 08, 2021 at 02:08:41PM +0200, Christoph Hellwig wrote:
> > Instead of failing to scan the namespace entirely when unsupported
> > features are detected, just mark the gendisk hidden but allow other
> > access like the upcoming per-namespace character device.
> 
> This part looks fine for what it is, but I thought we were going even
> further by allocating a namespace for the generic char device even if
> its Command Set Indicator was unsupported by the kernel.

We need a currently unpublished TP (don't remember the number offhand)
that adds another new Identify page for that.  So it is on the TODO
list but can't be done yet.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 05/13] nvme: simplify the compat ioctl handling
  2021-04-09  2:42     ` Chaitanya Kulkarni
@ 2021-04-09  5:39       ` Christoph Hellwig
  0 siblings, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-09  5:39 UTC (permalink / raw)
  To: Chaitanya Kulkarni
  Cc: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg,
	Kanchan Joshi, Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 02:42:25AM +0000, Chaitanya Kulkarni wrote:
> On 4/8/21 05:32, Christoph Hellwig wrote:
> > +	 * struct nvme_user_io can has different padding on some 32-bit ABIs.
> 
> s/can has/can have/ ?

Yes.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper
  2021-04-09  2:46     ` Chaitanya Kulkarni
@ 2021-04-09  5:39       ` Christoph Hellwig
  2021-04-09  5:40         ` Chaitanya Kulkarni
  0 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-09  5:39 UTC (permalink / raw)
  To: Chaitanya Kulkarni
  Cc: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg,
	Kanchan Joshi, Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 02:46:45AM +0000, Chaitanya Kulkarni wrote:
> On 4/8/21 05:35, Christoph Hellwig wrote:
> > Add a helper to avoid opencoding ns_head->ref manipulations.
> >
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Should we wait to have a second user for this ? unless it is there
> in next patches in this series.

It is really to be symmetric to the put case.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper
  2021-04-09  5:39       ` Christoph Hellwig
@ 2021-04-09  5:40         ` Chaitanya Kulkarni
  0 siblings, 0 replies; 45+ messages in thread
From: Chaitanya Kulkarni @ 2021-04-09  5:40 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minwoo Im, Keith Busch, Sagi Grimberg, Kanchan Joshi,
	Javier Gonz??lez, linux-nvme

On 4/8/21 22:40, Christoph Hellwig wrote:
>> Should we wait to have a second user for this ? unless it is there
>> in next patches in this series.
> It is really to be symmetric to the put case.
>

Okay.



_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 12/13] nvme: let namespace probing continue for unsupported features
  2021-04-09  5:39       ` Christoph Hellwig
@ 2021-04-09  5:47         ` Keith Busch
  2021-04-09  5:53           ` Christoph Hellwig
  0 siblings, 1 reply; 45+ messages in thread
From: Keith Busch @ 2021-04-09  5:47 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minwoo Im, Sagi Grimberg, Kanchan Joshi, Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 07:39:02AM +0200, Christoph Hellwig wrote:
> On Fri, Apr 09, 2021 at 07:42:59AM +0900, Keith Busch wrote:
> > On Thu, Apr 08, 2021 at 02:08:41PM +0200, Christoph Hellwig wrote:
> > > Instead of failing to scan the namespace entirely when unsupported
> > > features are detected, just mark the gendisk hidden but allow other
> > > access like the upcoming per-namespace character device.
> > 
> > This part looks fine for what it is, but I thought we were going even
> > further by allocating a namespace for the generic char device even if
> > its Command Set Indicator was unsupported by the kernel.
> 
> We need a currently unpublished TP (don't remember the number offhand)
> that adds another new Identify page for that.  So it is on the TODO
> list but can't be done yet.

Oh, I was thinking if the kernel doesn't have CONFIG_BLK_DEV_ZONED.
That's not necessary for the ng device.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 12/13] nvme: let namespace probing continue for unsupported features
  2021-04-09  5:47         ` Keith Busch
@ 2021-04-09  5:53           ` Christoph Hellwig
  0 siblings, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-09  5:53 UTC (permalink / raw)
  To: Keith Busch
  Cc: Christoph Hellwig, Minwoo Im, Sagi Grimberg, Kanchan Joshi,
	Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 02:47:56PM +0900, Keith Busch wrote:
> > We need a currently unpublished TP (don't remember the number offhand)
> > that adds another new Identify page for that.  So it is on the TODO
> > list but can't be done yet.
> 
> Oh, I was thinking if the kernel doesn't have CONFIG_BLK_DEV_ZONED.
> That's not necessary for the ng device.

Hmm.  That means we need another special just for ZNS that does not
use the command set independent identify.  Not sure that is really
worth it.  I'd rather wait for the new TP and have one generic path.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-08 16:56     ` Keith Busch
  2021-04-08 17:00       ` Christoph Hellwig
@ 2021-04-09  6:14       ` Christoph Hellwig
  2021-04-09 14:29         ` Keith Busch
  1 sibling, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-09  6:14 UTC (permalink / raw)
  To: Keith Busch
  Cc: Christoph Hellwig, Minwoo Im, Sagi Grimberg, Kanchan Joshi,
	Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 01:56:13AM +0900, Keith Busch wrote:
> On Thu, Apr 08, 2021 at 02:08:42PM +0200, Christoph Hellwig wrote:
> > +int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device,
> > +		const struct file_operations *fops, struct module *owner)
> > +{
> > +	int minor, ret;
> > +
> > +	minor = ida_simple_get(&nvme_ns_chr_minor_ida, 0, 0, GFP_KERNEL);
> 
> Do we really need to allocate a minor specific for this char dev? It
> looks like the ns->head->instance can provide the unique value.

Looking at this:  no, head->instance doesn't help as it is an
instance relative to subsystem, but doesn't help with a global
allocation over all subsystems.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-08 12:08   ` [PATCH 13/13] nvme: introduce generic per-namespace chardev Christoph Hellwig
  2021-04-08 16:56     ` Keith Busch
@ 2021-04-09  7:29     ` Minwoo Im
  2021-04-09  7:54       ` Christoph Hellwig
  1 sibling, 1 reply; 45+ messages in thread
From: Minwoo Im @ 2021-04-09  7:29 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Keith Busch, Sagi Grimberg, Kanchan Joshi, Javier Gonz??lez, linux-nvme

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 */
 

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-09  7:29     ` Minwoo Im
@ 2021-04-09  7:54       ` Christoph Hellwig
  2021-04-09  8:02         ` Minwoo Im
  0 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-09  7:54 UTC (permalink / raw)
  To: Minwoo Im
  Cc: Christoph Hellwig, Keith Busch, Sagi Grimberg, Kanchan Joshi,
	Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 04:29:01PM +0900, Minwoo Im wrote:
> 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.

Yes, that is intentional, as supporting the per-controller ioctls
on the per-namespace devices is a mess.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-09  7:54       ` Christoph Hellwig
@ 2021-04-09  8:02         ` Minwoo Im
  2021-04-09  9:52           ` Christoph Hellwig
  0 siblings, 1 reply; 45+ messages in thread
From: Minwoo Im @ 2021-04-09  8:02 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Keith Busch, Sagi Grimberg, Kanchan Joshi, Javier Gonz??lez, linux-nvme

On 21-04-09 09:54:15, Christoph Hellwig wrote:
> On Fri, Apr 09, 2021 at 04:29:01PM +0900, Minwoo Im wrote:
> > 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.
> 
> Yes, that is intentional, as supporting the per-controller ioctls
> on the per-namespace devices is a mess.

In multipath case, head blkdev is also per-namespace node which is now
supporting the controller ioctl by nvme_find_get_live_ctrl().  Is there
any different policy between the existing blkdev and generic device in
the current series ? Or should be just deprecate the controller ioctl
from the head blkdev ioctl in multipath case ?

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper
  2021-04-08 12:08   ` [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper Christoph Hellwig
  2021-04-09  2:46     ` Chaitanya Kulkarni
@ 2021-04-09  9:18     ` Kanchan Joshi
  2021-04-09  9:49       ` Christoph Hellwig
  1 sibling, 1 reply; 45+ messages in thread
From: Kanchan Joshi @ 2021-04-09  9:18 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minwoo Im, Keith Busch, Sagi Grimberg, Javier Gonz??lez, linux-nvme

On Thu, Apr 8, 2021 at 5:50 PM Christoph Hellwig <hch@lst.de> wrote:
>
> Add a helper to avoid opencoding ns_head->ref manipulations.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  drivers/nvme/host/core.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 98d87bff4ca37f..9637f2e5e9232c 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -549,6 +549,11 @@ static void nvme_free_ns_head(struct kref *ref)
>         kfree(head);
>  }
>
> +static bool nvme_tryget_ns_head(struct nvme_ns_head *head)
> +{
> +       return kref_get_unless_zero(&head->ref);
> +}
> +
>  static void nvme_put_ns_head(struct nvme_ns_head *head)
>  {
>         kref_put(&head->ref, nvme_free_ns_head);
> @@ -1975,9 +1980,7 @@ static const struct block_device_operations nvme_bdev_ops = {
>  #ifdef CONFIG_NVME_MULTIPATH
>  static int nvme_ns_head_open(struct block_device *bdev, fmode_t mode)
>  {
> -       struct nvme_ns_head *head = bdev->bd_disk->private_data;
> -
> -       if (!kref_get_unless_zero(&head->ref))
> +       if (!nvme_tryget_ns_head(bdev->bd_disk->private_data))
>                 return -ENXIO;
>         return 0;
>  }

This new helper needs to be added inside nvme_find_ns_head() as well?

Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>

-- 
Kanchan

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper
  2021-04-09  9:18     ` Kanchan Joshi
@ 2021-04-09  9:49       ` Christoph Hellwig
  0 siblings, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-09  9:49 UTC (permalink / raw)
  To: Kanchan Joshi
  Cc: Christoph Hellwig, Minwoo Im, Keith Busch, Sagi Grimberg,
	Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 02:48:20PM +0530, Kanchan Joshi wrote:
> This new helper needs to be added inside nvme_find_ns_head() as well?

Yes, good idea.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-09  8:02         ` Minwoo Im
@ 2021-04-09  9:52           ` Christoph Hellwig
  2021-04-09 11:24             ` Minwoo Im
  0 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-09  9:52 UTC (permalink / raw)
  To: Minwoo Im
  Cc: Christoph Hellwig, Keith Busch, Sagi Grimberg, Kanchan Joshi,
	Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 05:02:14PM +0900, Minwoo Im wrote:
> On 21-04-09 09:54:15, Christoph Hellwig wrote:
> > On Fri, Apr 09, 2021 at 04:29:01PM +0900, Minwoo Im wrote:
> > > 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.
> > 
> > Yes, that is intentional, as supporting the per-controller ioctls
> > on the per-namespace devices is a mess.
> 
> In multipath case, head blkdev is also per-namespace node which is now
> supporting the controller ioctl by nvme_find_get_live_ctrl().  Is there
> any different policy between the existing blkdev and generic device in
> the current series ? Or should be just deprecate the controller ioctl
> from the head blkdev ioctl in multipath case ?

Well, the multipath block device is supposed to be a full drop in
for the block device, including having the same name.  So I don't think
we can just deprecate it, even if that would really improve things.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-09  9:52           ` Christoph Hellwig
@ 2021-04-09 11:24             ` Minwoo Im
  2021-04-12  7:44               ` Christoph Hellwig
  0 siblings, 1 reply; 45+ messages in thread
From: Minwoo Im @ 2021-04-09 11:24 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Keith Busch, Sagi Grimberg, Kanchan Joshi, Javier Gonz??lez, linux-nvme

On 21-04-09 11:52:05, Christoph Hellwig wrote:
> On Fri, Apr 09, 2021 at 05:02:14PM +0900, Minwoo Im wrote:
> > On 21-04-09 09:54:15, Christoph Hellwig wrote:
> > > On Fri, Apr 09, 2021 at 04:29:01PM +0900, Minwoo Im wrote:
> > > > 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.
> > > 
> > > Yes, that is intentional, as supporting the per-controller ioctls
> > > on the per-namespace devices is a mess.
> > 
> > In multipath case, head blkdev is also per-namespace node which is now
> > supporting the controller ioctl by nvme_find_get_live_ctrl().  Is there
> > any different policy between the existing blkdev and generic device in
> > the current series ? Or should be just deprecate the controller ioctl
> > from the head blkdev ioctl in multipath case ?
> 
> Well, the multipath block device is supposed to be a full drop in
> for the block device, including having the same name.  So I don't think
> we can just deprecate it, even if that would really improve things.

I think if we don't have a route to the live controller from the
multipath node /dev/ng0n1, how does application figure out controller
node to request admin commands like Identify Namespace before their
own I/O ?

We have sysfs, but it does not provide every information about the
namespace.  Or is there any charming way to find out the live
controller from a head node through sysfs or something that I missed
here ? :)

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-09  6:14       ` Christoph Hellwig
@ 2021-04-09 14:29         ` Keith Busch
  2021-04-09 14:35           ` Christoph Hellwig
  0 siblings, 1 reply; 45+ messages in thread
From: Keith Busch @ 2021-04-09 14:29 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minwoo Im, Sagi Grimberg, Kanchan Joshi, Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 08:14:32AM +0200, Christoph Hellwig wrote:
> On Fri, Apr 09, 2021 at 01:56:13AM +0900, Keith Busch wrote:
> > On Thu, Apr 08, 2021 at 02:08:42PM +0200, Christoph Hellwig wrote:
> > > +int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device,
> > > +		const struct file_operations *fops, struct module *owner)
> > > +{
> > > +	int minor, ret;
> > > +
> > > +	minor = ida_simple_get(&nvme_ns_chr_minor_ida, 0, 0, GFP_KERNEL);
> > 
> > Do we really need to allocate a minor specific for this char dev? It
> > looks like the ns->head->instance can provide the unique value.
> 
> Looking at this:  no, head->instance doesn't help as it is an
> instance relative to subsystem, but doesn't help with a global
> allocation over all subsystems.

Right, my mistake.

In that case, there needs to be a ida_simple_remove() after the
cdev_device_del() so we don't leak the ida.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-09 14:29         ` Keith Busch
@ 2021-04-09 14:35           ` Christoph Hellwig
  0 siblings, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-09 14:35 UTC (permalink / raw)
  To: Keith Busch
  Cc: Christoph Hellwig, Minwoo Im, Sagi Grimberg, Kanchan Joshi,
	Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 08:29:27AM -0600, Keith Busch wrote:
> Right, my mistake.
> 
> In that case, there needs to be a ida_simple_remove() after the
> cdev_device_del() so we don't leak the ida.

Yes, I actually noticed that while I looked into your idea.  As of
this morning my local tree has a helper that does the cdev_device_del
and the ida_simple_remove in one go.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: nvme ioctl refactor and generic per-namespace char device
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (13 preceding siblings ...)
  2021-04-08 22:43   ` nvme ioctl refactor and generic per-namespace char device Keith Busch
@ 2021-04-09 17:45   ` Javier Gonz??lez
  2021-04-10  6:46   ` Christoph Hellwig
  15 siblings, 0 replies; 45+ messages in thread
From: Javier Gonz??lez @ 2021-04-09 17:45 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minwoo Im, Keith Busch, Sagi Grimberg, Kanchan Joshi, linux-nvme

On 08.04.2021 14:08, Christoph Hellwig wrote:
>Hi all,
>
>this series picks up the generic per-namespace character device
>from Minwoo and Javier with a few small fixed, but rebases them on
>an ioctl refactoring I had pending, which cleans up a lot of the
>lower level code.

You can also add my review tag for 1-12.

Reviewed-by: Javier González <javier.gonz@samsung.com>

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: nvme ioctl refactor and generic per-namespace char device
  2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
                     ` (14 preceding siblings ...)
  2021-04-09 17:45   ` Javier Gonz??lez
@ 2021-04-10  6:46   ` Christoph Hellwig
  15 siblings, 0 replies; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-10  6:46 UTC (permalink / raw)
  To: Minwoo Im, Keith Busch, Sagi Grimberg
  Cc: Kanchan Joshi, Javier Gonz??lez, linux-nvme

On Thu, Apr 08, 2021 at 02:08:29PM +0200, Christoph Hellwig wrote:
> Hi all,
> 
> this series picks up the generic per-namespace character device
> from Minwoo and Javier with a few small fixed, but rebases them on
> an ioctl refactoring I had pending, which cleans up a lot of the
> lower level code.

I've pulled patches into nvme-5.13, and I'll resend patch 13.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-09 11:24             ` Minwoo Im
@ 2021-04-12  7:44               ` Christoph Hellwig
  2021-04-12 11:52                 ` Javier Gonz??lez
  0 siblings, 1 reply; 45+ messages in thread
From: Christoph Hellwig @ 2021-04-12  7:44 UTC (permalink / raw)
  To: Minwoo Im
  Cc: Christoph Hellwig, Keith Busch, Sagi Grimberg, Kanchan Joshi,
	Javier Gonz??lez, linux-nvme

On Fri, Apr 09, 2021 at 08:24:01PM +0900, Minwoo Im wrote:
> I think if we don't have a route to the live controller from the
> multipath node /dev/ng0n1, how does application figure out controller
> node to request admin commands like Identify Namespace before their
> own I/O ?
> 
> We have sysfs, but it does not provide every information about the
> namespace.  Or is there any charming way to find out the live
> controller from a head node through sysfs or something that I missed
> here ? :)

The devie links points to the subsystem, which then points to the
controllers:

root@testvm:/sys/class/nvme-generic/ng0n1# ls -l device/
total 0
-r--r--r-- 1 root root 4096 Apr 12 07:43 firmware_rev
-rw-r--r-- 1 root root 4096 Apr 12 07:44 iopolicy
-r--r--r-- 1 root root 4096 Apr 12 07:43 model
drwxr-xr-x 3 root root    0 Apr 12 07:43 ng0n1
drwxr-xr-x 3 root root    0 Apr 12 07:43 ng0n2
lrwxrwxrwx 1 root root    0 Apr 12 07:44 nvme0 -> ../../nvme-fabrics/ctl/nvme0
drwxr-xr-x 9 root root    0 Apr 12 07:43 nvme0n1
drwxr-xr-x 9 root root    0 Apr 12 07:43 nvme0n2
lrwxrwxrwx 1 root root    0 Apr 12 07:44 nvme1 -> ../../nvme-fabrics/ctl/nvme1
drwxr-xr-x 2 root root    0 Apr 12 07:44 power
-r--r--r-- 1 root root 4096 Apr 12 07:43 serial
-r--r--r-- 1 root root 4096 Apr 12 07:44 subsysnqn
lrwxrwxrwx 1 root root    0 Apr 12 07:43 subsystem -> ../../../../class/nvme-subsystem
-rw-r--r-- 1 root root 4096 Apr 12 07:43 uevent


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 13/13] nvme: introduce generic per-namespace chardev
  2021-04-12  7:44               ` Christoph Hellwig
@ 2021-04-12 11:52                 ` Javier Gonz??lez
  0 siblings, 0 replies; 45+ messages in thread
From: Javier Gonz??lez @ 2021-04-12 11:52 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Minwoo Im, Keith Busch, Sagi Grimberg, Kanchan Joshi, linux-nvme

On 12.04.2021 09:44, Christoph Hellwig wrote:
>On Fri, Apr 09, 2021 at 08:24:01PM +0900, Minwoo Im wrote:
>> I think if we don't have a route to the live controller from the
>> multipath node /dev/ng0n1, how does application figure out controller
>> node to request admin commands like Identify Namespace before their
>> own I/O ?
>>
>> We have sysfs, but it does not provide every information about the
>> namespace.  Or is there any charming way to find out the live
>> controller from a head node through sysfs or something that I missed
>> here ? :)
>
>The devie links points to the subsystem, which then points to the
>controllers:
>
>root@testvm:/sys/class/nvme-generic/ng0n1# ls -l device/
>total 0
>-r--r--r-- 1 root root 4096 Apr 12 07:43 firmware_rev
>-rw-r--r-- 1 root root 4096 Apr 12 07:44 iopolicy
>-r--r--r-- 1 root root 4096 Apr 12 07:43 model
>drwxr-xr-x 3 root root    0 Apr 12 07:43 ng0n1
>drwxr-xr-x 3 root root    0 Apr 12 07:43 ng0n2
>lrwxrwxrwx 1 root root    0 Apr 12 07:44 nvme0 -> ../../nvme-fabrics/ctl/nvme0
>drwxr-xr-x 9 root root    0 Apr 12 07:43 nvme0n1
>drwxr-xr-x 9 root root    0 Apr 12 07:43 nvme0n2
>lrwxrwxrwx 1 root root    0 Apr 12 07:44 nvme1 -> ../../nvme-fabrics/ctl/nvme1
>drwxr-xr-x 2 root root    0 Apr 12 07:44 power
>-r--r--r-- 1 root root 4096 Apr 12 07:43 serial
>-r--r--r-- 1 root root 4096 Apr 12 07:44 subsysnqn
>lrwxrwxrwx 1 root root    0 Apr 12 07:43 subsystem -> ../../../../class/nvme-subsystem
>-rw-r--r-- 1 root root 4096 Apr 12 07:43 uevent
>

It seems like a limitation that we have to transverse sysfs to make an
in-application enumeration to submit namespace-specific admin commands.

Ideally, applications that are already using IOCTLs should be able to
directly work with the char device. If this is not the case, I am afraid
that the applicability will be limited.

I understand that identifying the live controller in multipath is
something that we need to improve. The question is that if this is a
reasonable thing for you. If there is no fundamental limitation here, I
think we can work the details of enabling namespace admin commands
through and merge the same support for the block device and the char
device.

What do you think?

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2021-04-12 11:53 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20210408121108eucas1p1fb60de8498a7461b453295497c206246@eucas1p1.samsung.com>
2021-04-08 12:08 ` nvme ioctl refactor and generic per-namespace char device Christoph Hellwig
2021-04-08 12:08   ` [PATCH 01/13] nvme: add a nvme_ns_head_multipath helper Christoph Hellwig
2021-04-09  2:33     ` Chaitanya Kulkarni
2021-04-08 12:08   ` [PATCH 02/13] nvme: cleanup setting the disk name Christoph Hellwig
2021-04-08 12:08   ` [PATCH 03/13] nvme: pass a user pointer to nvme_nvm_ioctl Christoph Hellwig
2021-04-08 12:08   ` [PATCH 04/13] nvme: factor out a nvme_ns_ioctl helper Christoph Hellwig
2021-04-09  2:40     ` Chaitanya Kulkarni
2021-04-08 12:08   ` [PATCH 05/13] nvme: simplify the compat ioctl handling Christoph Hellwig
2021-04-09  2:42     ` Chaitanya Kulkarni
2021-04-09  5:39       ` Christoph Hellwig
2021-04-08 12:08   ` [PATCH 06/13] nvme: simplify block device ioctl handling for the !multipath case Christoph Hellwig
2021-04-08 12:08   ` [PATCH 07/13] nvme: don't bother to look up a namespace for controller ioctls Christoph Hellwig
2021-04-08 12:08   ` [PATCH 08/13] nvme: move the ioctl code to a separate file Christoph Hellwig
2021-04-09  2:45     ` Chaitanya Kulkarni
2021-04-08 12:08   ` [PATCH 09/13] nvme: factor out a nvme_tryget_ns_head helper Christoph Hellwig
2021-04-09  2:46     ` Chaitanya Kulkarni
2021-04-09  5:39       ` Christoph Hellwig
2021-04-09  5:40         ` Chaitanya Kulkarni
2021-04-09  9:18     ` Kanchan Joshi
2021-04-09  9:49       ` Christoph Hellwig
2021-04-08 12:08   ` [PATCH 10/13] nvme: move nvme_ns_head_ops to multipath.c Christoph Hellwig
2021-04-09  2:47     ` Chaitanya Kulkarni
2021-04-08 12:08   ` [PATCH 11/13] nvme: factor out nvme_ns_open and nvme_ns_release helpers Christoph Hellwig
2021-04-09  2:48     ` Chaitanya Kulkarni
2021-04-08 12:08   ` [PATCH 12/13] nvme: let namespace probing continue for unsupported features Christoph Hellwig
2021-04-08 22:42     ` Keith Busch
2021-04-09  5:39       ` Christoph Hellwig
2021-04-09  5:47         ` Keith Busch
2021-04-09  5:53           ` Christoph Hellwig
2021-04-08 12:08   ` [PATCH 13/13] nvme: introduce generic per-namespace chardev Christoph Hellwig
2021-04-08 16:56     ` Keith Busch
2021-04-08 17:00       ` Christoph Hellwig
2021-04-09  6:14       ` Christoph Hellwig
2021-04-09 14:29         ` Keith Busch
2021-04-09 14:35           ` Christoph Hellwig
2021-04-09  7:29     ` Minwoo Im
2021-04-09  7:54       ` Christoph Hellwig
2021-04-09  8:02         ` Minwoo Im
2021-04-09  9:52           ` Christoph Hellwig
2021-04-09 11:24             ` Minwoo Im
2021-04-12  7:44               ` Christoph Hellwig
2021-04-12 11:52                 ` Javier Gonz??lez
2021-04-08 22:43   ` nvme ioctl refactor and generic per-namespace char device Keith Busch
2021-04-09 17:45   ` Javier Gonz??lez
2021-04-10  6:46   ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).