diff options
author | Solganik Alexander <sashas@lightbitslabs.com> | 2016-10-30 09:35:15 +0100 |
---|---|---|
committer | Sagi Grimberg <sagi@grimberg.me> | 2016-12-06 09:17:03 +0100 |
commit | e4fcf07cca6a3b6c4be00df16f08be894325eaa3 (patch) | |
tree | fe89e5c2ba76c318026e6b708bc73060f9c4902f /drivers/nvme/target/nvmet.h | |
parent | nvme-fabrics: Fix a memory leak in an nvmf_create_ctrl() error path (diff) | |
download | linux-e4fcf07cca6a3b6c4be00df16f08be894325eaa3.tar.xz linux-e4fcf07cca6a3b6c4be00df16f08be894325eaa3.zip |
nvmet: Fix possible infinite loop triggered on hot namespace removal
When removing a namespace we delete it from the subsystem namespaces
list with list_del_init which allows us to know if it is enabled or
not.
The problem is that list_del_init initialize the list next and does
not respect the RCU list-traversal we do on the IO path for locating
a namespace. Instead we need to use list_del_rcu which is allowed to
run concurrently with the _rcu list-traversal primitives (keeps list
next intact) and guarantees concurrent nvmet_find_naespace forward
progress.
By changing that, we cannot rely on ns->dev_link for knowing if the
namspace is enabled, so add enabled indicator entry to nvmet_ns for
that.
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Solganik Alexander <sashas@lightbitslabs.com>
Cc: <stable@vger.kernel.org> # v4.8+
Diffstat (limited to 'drivers/nvme/target/nvmet.h')
-rw-r--r-- | drivers/nvme/target/nvmet.h | 6 |
1 files changed, 1 insertions, 5 deletions
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index f9c76441e8c9..23d5eb1c944f 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -47,6 +47,7 @@ struct nvmet_ns { loff_t size; u8 nguid[16]; + bool enabled; struct nvmet_subsys *subsys; const char *device_path; @@ -61,11 +62,6 @@ static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item) return container_of(to_config_group(item), struct nvmet_ns, group); } -static inline bool nvmet_ns_enabled(struct nvmet_ns *ns) -{ - return !list_empty_careful(&ns->dev_link); -} - struct nvmet_cq { u16 qid; u16 size; |