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+
This commit is contained in:

committed by
Sagi Grimberg

parent
f3116d8f1e
commit
e4fcf07cca
@@ -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;
|
||||
|
Reference in New Issue
Block a user