[PATCH 1/3] nvme: decouple nvme_ctrl_get_by_path()
Chaitanya Kulkarni
chaitanya.kulkarni at wdc.com
Thu Sep 3 22:39:27 EDT 2020
Right now nvme_ctrl_get_by_path() accepts ctrl path, based on that it
opens a file and calls nvme_get_ctrl(). In order to take module
refcount it is important to distinguish the error between file_open()
and module file ops check so that we can unwind the code in the caller
nvmet_passthru_ctrl_enable() in the error path.
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.
Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni at wdc.com>
---
drivers/nvme/host/core.c | 10 ++--------
drivers/nvme/host/nvme.h | 2 +-
drivers/nvme/target/nvmet.h | 1 +
drivers/nvme/target/passthru.c | 17 +++++++++++++----
4 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 5702a3843746..fa7c0def9184 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4641,14 +4641,9 @@ 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);
@@ -4659,10 +4654,9 @@ struct nvme_ctrl *nvme_ctrl_get_by_path(const char *path)
nvme_get_ctrl(ctrl);
out_close:
- filp_close(f, NULL);
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 2910f6caab7d..590cc880834a 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -836,7 +836,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..14a842408035 100644
--- a/drivers/nvme/target/passthru.c
+++ b/drivers/nvme/target/passthru.c
@@ -473,6 +473,7 @@ 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;
@@ -480,7 +481,7 @@ int nvmet_passthru_ctrl_enable(struct nvmet_subsys *subsys)
mutex_lock(&subsys->lock);
if (!subsys->passthru_ctrl_path)
goto out_unlock;
- if (subsys->passthru_ctrl)
+ if (!pt_path)
goto out_unlock;
if (subsys->nr_namespaces) {
@@ -488,13 +489,18 @@ 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;
}
old = xa_cmpxchg(&passthru_subsystems, ctrl->cntlid, NULL,
@@ -522,6 +528,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 +539,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