diff options
author | Dan Williams <dan.j.williams@intel.com> | 2015-06-25 11:20:04 +0300 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2015-06-25 11:20:04 +0300 |
commit | 8c2f7e8658df1d3b7cbfa62706941d14c715823a (patch) | |
tree | ac93512841113f4d1d7a38d788ec73bb21e2d605 /drivers/nvdimm/region_devs.c | |
parent | 0ba1c634892b3590779803a701bcb82e8c32cc7a (diff) | |
download | linux-8c2f7e8658df1d3b7cbfa62706941d14c715823a.tar.xz |
libnvdimm: infrastructure for btt devices
NVDIMM namespaces, in addition to accepting "struct bio" based requests,
also have the capability to perform byte-aligned accesses. By default
only the bio/block interface is used. However, if another driver can
make effective use of the byte-aligned capability it can claim namespace
interface and use the byte-aligned ->rw_bytes() interface.
The BTT driver is the initial first consumer of this mechanism to allow
adding atomic sector update semantics to a pmem or blk namespace. This
patch is the sysfs infrastructure to allow configuring a BTT instance
for a namespace. Enabling that BTT and performing i/o is in a
subsequent patch.
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/region_devs.c')
-rw-r--r-- | drivers/nvdimm/region_devs.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index ac21ce419beb..4fd92389fa7e 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -296,10 +296,28 @@ static ssize_t namespace_seed_show(struct device *dev, } static DEVICE_ATTR_RO(namespace_seed); +static ssize_t btt_seed_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nd_region *nd_region = to_nd_region(dev); + ssize_t rc; + + nvdimm_bus_lock(dev); + if (nd_region->btt_seed) + rc = sprintf(buf, "%s\n", dev_name(nd_region->btt_seed)); + else + rc = sprintf(buf, "\n"); + nvdimm_bus_unlock(dev); + + return rc; +} +static DEVICE_ATTR_RO(btt_seed); + static struct attribute *nd_region_attributes[] = { &dev_attr_size.attr, &dev_attr_nstype.attr, &dev_attr_mappings.attr, + &dev_attr_btt_seed.attr, &dev_attr_set_cookie.attr, &dev_attr_available_size.attr, &dev_attr_namespace_seed.attr, @@ -345,15 +363,18 @@ u64 nd_region_interleave_set_cookie(struct nd_region *nd_region) /* * Upon successful probe/remove, take/release a reference on the - * associated interleave set (if present) + * associated interleave set (if present), and plant new btt + namespace + * seeds. */ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus, struct device *dev, bool probe) { + struct nd_region *nd_region; + if (!probe && (is_nd_pmem(dev) || is_nd_blk(dev))) { - struct nd_region *nd_region = to_nd_region(dev); int i; + nd_region = to_nd_region(dev); 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; @@ -365,14 +386,21 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus, nd_mapping->ndd = NULL; atomic_dec(&nvdimm->busy); } - } else if (dev->parent && is_nd_blk(dev->parent) && probe) { - struct nd_region *nd_region = to_nd_region(dev->parent); - + } + if (dev->parent && is_nd_blk(dev->parent) && probe) { + nd_region = to_nd_region(dev->parent); nvdimm_bus_lock(dev); if (nd_region->ns_seed == dev) nd_region_create_blk_seed(nd_region); nvdimm_bus_unlock(dev); } + if (is_nd_btt(dev) && probe) { + nd_region = to_nd_region(dev->parent); + nvdimm_bus_lock(dev); + if (nd_region->btt_seed == dev) + nd_region_create_btt_seed(nd_region); + nvdimm_bus_unlock(dev); + } } void nd_region_probe_success(struct nvdimm_bus *nvdimm_bus, struct device *dev) @@ -546,6 +574,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, nd_region->provider_data = ndr_desc->provider_data; nd_region->nd_set = ndr_desc->nd_set; ida_init(&nd_region->ns_ida); + ida_init(&nd_region->btt_ida); dev = &nd_region->dev; dev_set_name(dev, "region%d", nd_region->id); dev->parent = &nvdimm_bus->dev; |