Patch "nvmet: Fix possible infinite loop triggered on hot namespace removal" has been added to the 4.8-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
nvmet: Fix possible infinite loop triggered on hot namespace removal
to the 4.8-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
nvmet-fix-possible-infinite-loop-triggered-on-hot-namespace-removal.patch
and it can be found in the queue-4.8 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
e4fcf07cca6a3b6c4be00df16f08be894325eaa3Mon Sep 17 00:00:00 2001
From: Solganik Alexander <[email protected]>
Date: Sun, 30 Oct 2016 10:35:15 +0200
Subject: nvmet: Fix possible infinite loop triggered on hot namespace removal
From: Solganik Alexander <[email protected]>
commit e4fcf07cca6a3b6c4be00df16f08be894325eaa3 upstream.
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.
--- drivers/nvme/target/configfs.c | 6 +++--- drivers/nvme/target/core.c | 14 ++++++++------ drivers/nvme/target/nvmet.h | 6 +----- 3 files changed, 12 insertions(+), 14 deletions(-)
drivers/nvme/target/configfs.c +3 -3
@@ -271,7 +271,7 @@ static ssize_t nvmet_ns_device_path_stormutex_lock (&subsys->lock); ret = -EBUSY ; -if (nvmet_ns_enabled (ns)) +if (ns->enabled) goto out_unlock;kfree (ns->device_path);
@@ -307,7 +307,7 @@ static ssize_t nvmet_ns_device_nguid_stoint ret =0 ;mutex_lock (&subsys->lock); -if (nvmet_ns_enabled (ns)) { +if (ns->enabled) { ret = -EBUSY ; goto out_unlock; }
@@ -339,7 +339,7 @@ CONFIGFS_ATTR(nvmet_ns_, device_nguid);static ssize_t nvmet_ns_enable_show (struct config_item *item,char *page) { -return sprintf (page,"%d\n" ,nvmet_ns_enabled (to_nvmet_ns (item))); +return sprintf (page,"%d\n" ,to_nvmet_ns (item)->enabled); } static ssize_t nvmet_ns_enable_store(struct config_item *item,
drivers/nvme/target/core.c +8 -6
@@ -264,7 +264,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)int ret =0 ;mutex_lock (&subsys->lock); -if (!list_empty (&ns->dev_link)) +if (ns->enabled) goto out_unlock; ns->bdev = blkdev_get_by_path(ns->device_path, FMODE_READ | FMODE_WRITE,
@@ -309,6 +309,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)list_for_each_entry (ctrl, &subsys->ctrls, subsys_entry)nvmet_add_async_event (ctrl,NVME_AER_TYPE_NOTICE ,0 ,0 ); + ns->enabled = true; ret =0 ; out_unlock:mutex_unlock (&subsys->lock);
@@ -325,11 +326,11 @@ void nvmet_ns_disable(struct nvmet_ns *nstruct nvmet_ctrl *ctrl;mutex_lock (&subsys->lock); -if (list_empty (&ns->dev_link)) { -mutex_unlock (&subsys->lock); -return ; - } -list_del_init (&ns->dev_link); +if (!ns->enabled) + goto out_unlock; + + ns->enabled = false; +list_del_rcu (&ns->dev_link);mutex_unlock (&subsys->lock);/*
@@ -351,6 +352,7 @@ void nvmet_ns_disable(struct nvmet_ns *nif (ns->bdev)blkdev_put (ns->bdev,FMODE_WRITE |FMODE_READ ); +out_unlock:mutex_unlock (&subsys->lock); }
drivers/nvme/target/nvmet.h +1 -5
@@ -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_ 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;
Patches currently in stable-queue which might be from [email protected] are
queue-4.8/nvmet-fix-possible-infinite-loop-triggered-on-hot-namespace-removal.patch