summaryrefslogtreecommitdiff
path: root/drivers/nvdimm/namespace_devs.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2019-09-05 18:45:57 +0300
committerDan Williams <dan.j.williams@intel.com>2019-09-06 02:11:14 +0300
commita2d1c7a61db9b1e261410c7d9e2be2243040749b (patch)
tree8bd3f902d3ca26554d26eae97d3e1867d6b5009b /drivers/nvdimm/namespace_devs.c
parent7b60422cb796d40431337becf2129fd9944b2f05 (diff)
downloadlinux-a2d1c7a61db9b1e261410c7d9e2be2243040749b.tar.xz
libnvdimm/region: Rewrite _probe_success() to _advance_seeds()
The nd_region_probe_success() helper collides seed management with nvdimm->busy tracking. Given the 'busy' increment is handled internal to the nd_region driver 'probe' path move the decrement to the 'remove' path. With that cleanup the routine can be renamed to the more descriptive nd_region_advance_seeds(). The change is prompted by an incoming need to optionally advance the seeds on other events besides 'probe' success. Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Link: https://lore.kernel.org/r/20190905154603.10349-2-aneesh.kumar@linux.ibm.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/namespace_devs.c')
-rw-r--r--drivers/nvdimm/namespace_devs.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index a16e52251a30..3be81f7b9ed3 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -2462,6 +2462,27 @@ static struct device **create_namespaces(struct nd_region *nd_region)
return devs;
}
+static void deactivate_labels(void *region)
+{
+ struct nd_region *nd_region = region;
+ int i;
+
+ for (i = 0; i < nd_region->ndr_mappings; i++) {
+ struct nd_mapping *nd_mapping = &nd_region->mapping[i];
+ struct nvdimm_drvdata *ndd = nd_mapping->ndd;
+ struct nvdimm *nvdimm = nd_mapping->nvdimm;
+
+ mutex_lock(&nd_mapping->lock);
+ nd_mapping_free_labels(nd_mapping);
+ mutex_unlock(&nd_mapping->lock);
+
+ put_ndd(ndd);
+ nd_mapping->ndd = NULL;
+ if (ndd)
+ atomic_dec(&nvdimm->busy);
+ }
+}
+
static int init_active_labels(struct nd_region *nd_region)
{
int i;
@@ -2519,16 +2540,17 @@ static int init_active_labels(struct nd_region *nd_region)
mutex_unlock(&nd_mapping->lock);
}
- if (j >= count)
- continue;
+ if (j < count)
+ break;
+ }
- mutex_lock(&nd_mapping->lock);
- nd_mapping_free_labels(nd_mapping);
- mutex_unlock(&nd_mapping->lock);
+ if (i < nd_region->ndr_mappings) {
+ deactivate_labels(nd_region);
return -ENOMEM;
}
- return 0;
+ return devm_add_action_or_reset(&nd_region->dev, deactivate_labels,
+ nd_region);
}
int nd_region_register_namespaces(struct nd_region *nd_region, int *err)