diff options
author | Dan Williams <dan.j.williams@intel.com> | 2016-09-30 18:28:27 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2016-10-07 12:22:53 -0400 |
commit | 98a29c39dc689298d2f834f40102cba752eb49c0 (patch) | |
tree | e1b3551216f9181641c35bbf4cd76f0562f45030 /drivers/nvdimm/namespace_devs.c | |
parent | 991d9020f3e0447ea00c7c7f11fed364d977320a (diff) |
libnvdimm, namespace: allow creation of multiple pmem-namespaces per region
Similar to BLK regions, publish new seed namespace devices to allow
unused PMEM region capacity to be consumed by additional namespaces.
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.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index fa51d751ccf7..3509cff68ef9 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c | |||
@@ -1860,16 +1860,58 @@ static struct device *nd_namespace_blk_create(struct nd_region *nd_region) | |||
1860 | return &nsblk->common.dev; | 1860 | return &nsblk->common.dev; |
1861 | } | 1861 | } |
1862 | 1862 | ||
1863 | void nd_region_create_blk_seed(struct nd_region *nd_region) | 1863 | static struct device *nd_namespace_pmem_create(struct nd_region *nd_region) |
1864 | { | ||
1865 | struct nd_namespace_pmem *nspm; | ||
1866 | struct resource *res; | ||
1867 | struct device *dev; | ||
1868 | |||
1869 | if (!is_nd_pmem(&nd_region->dev)) | ||
1870 | return NULL; | ||
1871 | |||
1872 | nspm = kzalloc(sizeof(*nspm), GFP_KERNEL); | ||
1873 | if (!nspm) | ||
1874 | return NULL; | ||
1875 | |||
1876 | dev = &nspm->nsio.common.dev; | ||
1877 | dev->type = &namespace_pmem_device_type; | ||
1878 | dev->parent = &nd_region->dev; | ||
1879 | res = &nspm->nsio.res; | ||
1880 | res->name = dev_name(&nd_region->dev); | ||
1881 | res->flags = IORESOURCE_MEM; | ||
1882 | |||
1883 | nspm->id = ida_simple_get(&nd_region->ns_ida, 0, 0, GFP_KERNEL); | ||
1884 | if (nspm->id < 0) { | ||
1885 | kfree(nspm); | ||
1886 | return NULL; | ||
1887 | } | ||
1888 | dev_set_name(dev, "namespace%d.%d", nd_region->id, nspm->id); | ||
1889 | dev->parent = &nd_region->dev; | ||
1890 | dev->groups = nd_namespace_attribute_groups; | ||
1891 | nd_namespace_pmem_set_resource(nd_region, nspm, 0); | ||
1892 | |||
1893 | return dev; | ||
1894 | } | ||
1895 | |||
1896 | void nd_region_create_ns_seed(struct nd_region *nd_region) | ||
1864 | { | 1897 | { |
1865 | WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev)); | 1898 | WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev)); |
1866 | nd_region->ns_seed = nd_namespace_blk_create(nd_region); | 1899 | |
1900 | if (nd_region_to_nstype(nd_region) == ND_DEVICE_NAMESPACE_IO) | ||
1901 | return; | ||
1902 | |||
1903 | if (is_nd_blk(&nd_region->dev)) | ||
1904 | nd_region->ns_seed = nd_namespace_blk_create(nd_region); | ||
1905 | else | ||
1906 | nd_region->ns_seed = nd_namespace_pmem_create(nd_region); | ||
1907 | |||
1867 | /* | 1908 | /* |
1868 | * Seed creation failures are not fatal, provisioning is simply | 1909 | * Seed creation failures are not fatal, provisioning is simply |
1869 | * disabled until memory becomes available | 1910 | * disabled until memory becomes available |
1870 | */ | 1911 | */ |
1871 | if (!nd_region->ns_seed) | 1912 | if (!nd_region->ns_seed) |
1872 | dev_err(&nd_region->dev, "failed to create blk namespace\n"); | 1913 | dev_err(&nd_region->dev, "failed to create %s namespace\n", |
1914 | is_nd_blk(&nd_region->dev) ? "blk" : "pmem"); | ||
1873 | else | 1915 | else |
1874 | nd_device_register(nd_region->ns_seed); | 1916 | nd_device_register(nd_region->ns_seed); |
1875 | } | 1917 | } |