[PATCH V2 2/2] nvme: decouple nvme_get_ctrl() from file open
Chaitanya Kulkarni
chaitanya.kulkarni at wdc.com
Tue Sep 15 23:53:26 EDT 2020
Rename nvme_ctrl_get_by_path() -> nvme_ctrl_get_by_file() and lift
the file opening and error handling in the caller so that we can unwind
appropriately in the error path (in nvmet_passthru_ctrl_enable()).
Now that we decoupled the file open/close from host/core.c move the
nvme_get_ctrl() to nvmet_passthru_ctrl_enable(), also close the file
before we release the passthru controller's reference.
Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni at wdc.com>
---
drivers/nvme/host/core.c | 15 ++++-----------
drivers/nvme/host/nvme.h | 2 +-
drivers/nvme/target/nvmet.h | 1 +
drivers/nvme/target/passthru.c | 19 +++++++++++++++----
4 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index c5f9d64b2bec..c446584d8b12 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4649,28 +4649,21 @@ void nvme_sync_queues(struct nvme_ctrl *ctrl)
}
EXPORT_SYMBOL_GPL(nvme_sync_queues);
-struct nvme_ctrl *nvme_ctrl_get_by_path(const char *path)
+struct nvme_ctrl *nvme_ctrl_get_by_file(struct file *f)
{
struct nvme_ctrl *ctrl;
- struct file *f;
-
- f = filp_open(path, O_RDWR, 0);
- if (IS_ERR(f))
- return ERR_CAST(f);
if (f->f_op != &nvme_dev_fops) {
ctrl = ERR_PTR(-EINVAL);
- goto out_close;
+ goto out;
}
ctrl = f->private_data;
- nvme_get_ctrl(ctrl);
-out_close:
- filp_close(f, NULL);
+out:
return ctrl;
}
-EXPORT_SYMBOL_NS_GPL(nvme_ctrl_get_by_path, NVME_TARGET_PASSTHRU);
+EXPORT_SYMBOL_NS_GPL(nvme_ctrl_get_by_file, NVME_TARGET_PASSTHRU);
/*
* Check we didn't inadvertently grow the command structure sizes:
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 9fd45ff656da..2cb966653a33 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -835,7 +835,7 @@ static inline void nvme_hwmon_init(struct nvme_ctrl *ctrl) { }
u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
u8 opcode);
void nvme_execute_passthru_rq(struct request *rq);
-struct nvme_ctrl *nvme_ctrl_get_by_path(const char *path);
+struct nvme_ctrl *nvme_ctrl_get_by_file(struct file *f);
struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid);
void nvme_put_ns(struct nvme_ns *ns);
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 47ee3fb193bd..477439acb8e1 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -248,6 +248,7 @@ struct nvmet_subsys {
#ifdef CONFIG_NVME_TARGET_PASSTHRU
struct nvme_ctrl *passthru_ctrl;
char *passthru_ctrl_path;
+ struct file *passthru_ctrl_file;
struct config_group passthru_group;
#endif /* CONFIG_NVME_TARGET_PASSTHRU */
};
diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c
index 8bd7f656e240..84f9daea81db 100644
--- a/drivers/nvme/target/passthru.c
+++ b/drivers/nvme/target/passthru.c
@@ -473,12 +473,13 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req)
int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys)
{
+ const char *pt_path = subsys->passthru_ctrl_path;
struct nvme_ctrl *ctrl;
int ret = -EINVAL;
void *old;
mutex_lock(&subsys->lock);
- if (!subsys->passthru_ctrl_path)
+ if (!pt_path)
goto out_unlock;
if (subsys->passthru_ctrl)
goto out_unlock;
@@ -488,15 +489,22 @@ int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys)
goto out_unlock;
}
- ctrl = nvme_ctrl_get_by_path(subsys->passthru_ctrl_path);
+ subsys->passthru_ctrl_file = filp_open(pt_path, O_RDWR, 0);
+ if (IS_ERR(subsys->passthru_ctrl_file)) {
+ ret = PTR_ERR(subsys->passthru_ctrl_file);
+ goto out_unlock;
+ }
+
+ ctrl = nvme_ctrl_get_by_file(subsys->passthru_ctrl_file);
if (IS_ERR(ctrl)) {
ret = PTR_ERR(ctrl);
pr_err("failed to open nvme controller %s\n",
subsys->passthru_ctrl_path);
-
- goto out_unlock;
+ goto out_put_file;
}
+ nvme_get_ctrl(ctrl);
+
old = xa_cmpxchg(&passthru_subsystems, ctrl->cntlid, NULL,
subsys, GFP_KERNEL);
if (xa_is_err(old)) {
@@ -522,6 +530,8 @@ int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys)
out_put_ctrl:
nvme_put_ctrl(ctrl);
+out_put_file:
+ filp_close(subsys->passthru_ctrl_file, NULL);
out_unlock:
mutex_unlock(&subsys->lock);
return ret;
@@ -531,6 +541,7 @@ static void __nvmet_passthru_ctrl_disable(struct nvmet_subsys *subsys)
{
if (subsys->passthru_ctrl) {
xa_erase(&passthru_subsystems, subsys->passthru_ctrl->cntlid);
+ filp_close(subsys->passthru_ctrl_file, NULL);
nvme_put_ctrl(subsys->passthru_ctrl);
}
subsys->passthru_ctrl = NULL;
--
2.22.1
More information about the Linux-nvme
mailing list