aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/namespace_devs.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2015-05-30 12:36:02 -0400
committerDan Williams <dan.j.williams@intel.com>2015-06-24 21:24:10 -0400
commitf524bf271a5cf12a44253194abcf8b6688ff5b9d (patch)
treee477ae652183e73a6a3c6fc592046e255d2bfd15 /drivers/nvdimm/namespace_devs.c
parent1b40e09a1232de537b193fa1b6b3ef16d3a1e397 (diff)
libnvdimm: write pmem label set
After 'uuid', 'size', and optionally 'alt_name' have been set to valid values the labels on the dimms can be updated. Write procedure is: 1/ Allocate and write new labels in the "next" index 2/ Free the old labels in the working copy 3/ Write the bitmap and the label space on the dimm 4/ Write the index to make the update valid Label ranges directly mirror the dpa resource values for the given label_id of the namespace. Cc: Greg KH <gregkh@linuxfoundation.org> Cc: Neil Brown <neilb@suse.de> Acked-by: Christoph Hellwig <hch@lst.de> 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.c83
1 files changed, 72 insertions, 11 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index ad0ec09ca40f..546e77e122fd 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -149,20 +149,53 @@ static resource_size_t nd_namespace_blk_size(struct nd_namespace_blk *nsblk)
149 return size; 149 return size;
150} 150}
151 151
152static int nd_namespace_label_update(struct nd_region *nd_region,
153 struct device *dev)
154{
155 dev_WARN_ONCE(dev, dev->driver,
156 "namespace must be idle during label update\n");
157 if (dev->driver)
158 return 0;
159
160 /*
161 * Only allow label writes that will result in a valid namespace
162 * or deletion of an existing namespace.
163 */
164 if (is_namespace_pmem(dev)) {
165 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
166 struct resource *res = &nspm->nsio.res;
167 resource_size_t size = resource_size(res);
168
169 if (size == 0 && nspm->uuid)
170 /* delete allocation */;
171 else if (!nspm->uuid)
172 return 0;
173
174 return nd_pmem_namespace_label_update(nd_region, nspm, size);
175 } else if (is_namespace_blk(dev)) {
176 /* TODO: implement blk labels */
177 return 0;
178 } else
179 return -ENXIO;
180}
181
152static ssize_t alt_name_store(struct device *dev, 182static ssize_t alt_name_store(struct device *dev,
153 struct device_attribute *attr, const char *buf, size_t len) 183 struct device_attribute *attr, const char *buf, size_t len)
154{ 184{
185 struct nd_region *nd_region = to_nd_region(dev->parent);
155 ssize_t rc; 186 ssize_t rc;
156 187
157 device_lock(dev); 188 device_lock(dev);
158 nvdimm_bus_lock(dev); 189 nvdimm_bus_lock(dev);
159 wait_nvdimm_bus_probe_idle(dev); 190 wait_nvdimm_bus_probe_idle(dev);
160 rc = __alt_name_store(dev, buf, len); 191 rc = __alt_name_store(dev, buf, len);
192 if (rc >= 0)
193 rc = nd_namespace_label_update(nd_region, dev);
161 dev_dbg(dev, "%s: %s(%zd)\n", __func__, rc < 0 ? "fail " : "", rc); 194 dev_dbg(dev, "%s: %s(%zd)\n", __func__, rc < 0 ? "fail " : "", rc);
162 nvdimm_bus_unlock(dev); 195 nvdimm_bus_unlock(dev);
163 device_unlock(dev); 196 device_unlock(dev);
164 197
165 return rc; 198 return rc < 0 ? rc : len;
166} 199}
167 200
168static ssize_t alt_name_show(struct device *dev, 201static ssize_t alt_name_show(struct device *dev,
@@ -709,6 +742,7 @@ static ssize_t __size_store(struct device *dev, unsigned long long val)
709static ssize_t size_store(struct device *dev, 742static ssize_t size_store(struct device *dev,
710 struct device_attribute *attr, const char *buf, size_t len) 743 struct device_attribute *attr, const char *buf, size_t len)
711{ 744{
745 struct nd_region *nd_region = to_nd_region(dev->parent);
712 unsigned long long val; 746 unsigned long long val;
713 u8 **uuid = NULL; 747 u8 **uuid = NULL;
714 int rc; 748 int rc;
@@ -721,6 +755,8 @@ static ssize_t size_store(struct device *dev,
721 nvdimm_bus_lock(dev); 755 nvdimm_bus_lock(dev);
722 wait_nvdimm_bus_probe_idle(dev); 756 wait_nvdimm_bus_probe_idle(dev);
723 rc = __size_store(dev, val); 757 rc = __size_store(dev, val);
758 if (rc >= 0)
759 rc = nd_namespace_label_update(nd_region, dev);
724 760
725 if (is_namespace_pmem(dev)) { 761 if (is_namespace_pmem(dev)) {
726 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev); 762 struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
@@ -744,7 +780,7 @@ static ssize_t size_store(struct device *dev,
744 nvdimm_bus_unlock(dev); 780 nvdimm_bus_unlock(dev);
745 device_unlock(dev); 781 device_unlock(dev);
746 782
747 return rc ? rc : len; 783 return rc < 0 ? rc : len;
748} 784}
749 785
750static ssize_t size_show(struct device *dev, 786static ssize_t size_show(struct device *dev,
@@ -804,17 +840,34 @@ static int namespace_update_uuid(struct nd_region *nd_region,
804 u32 flags = is_namespace_blk(dev) ? NSLABEL_FLAG_LOCAL : 0; 840 u32 flags = is_namespace_blk(dev) ? NSLABEL_FLAG_LOCAL : 0;
805 struct nd_label_id old_label_id; 841 struct nd_label_id old_label_id;
806 struct nd_label_id new_label_id; 842 struct nd_label_id new_label_id;
807 int i, rc; 843 int i;
808 844
809 rc = nd_is_uuid_unique(dev, new_uuid) ? 0 : -EINVAL; 845 if (!nd_is_uuid_unique(dev, new_uuid))
810 if (rc) { 846 return -EINVAL;
811 kfree(new_uuid);
812 return rc;
813 }
814 847
815 if (*old_uuid == NULL) 848 if (*old_uuid == NULL)
816 goto out; 849 goto out;
817 850
851 /*
852 * If we've already written a label with this uuid, then it's
853 * too late to rename because we can't reliably update the uuid
854 * without losing the old namespace. Userspace must delete this
855 * namespace to abandon the old uuid.
856 */
857 for (i = 0; i < nd_region->ndr_mappings; i++) {
858 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
859
860 /*
861 * This check by itself is sufficient because old_uuid
862 * would be NULL above if this uuid did not exist in the
863 * currently written set.
864 *
865 * FIXME: can we delete uuid with zero dpa allocated?
866 */
867 if (nd_mapping->labels)
868 return -EBUSY;
869 }
870
818 nd_label_gen_id(&old_label_id, *old_uuid, flags); 871 nd_label_gen_id(&old_label_id, *old_uuid, flags);
819 nd_label_gen_id(&new_label_id, new_uuid, flags); 872 nd_label_gen_id(&new_label_id, new_uuid, flags);
820 for (i = 0; i < nd_region->ndr_mappings; i++) { 873 for (i = 0; i < nd_region->ndr_mappings; i++) {
@@ -858,12 +911,16 @@ static ssize_t uuid_store(struct device *dev,
858 rc = nd_uuid_store(dev, &uuid, buf, len); 911 rc = nd_uuid_store(dev, &uuid, buf, len);
859 if (rc >= 0) 912 if (rc >= 0)
860 rc = namespace_update_uuid(nd_region, dev, uuid, ns_uuid); 913 rc = namespace_update_uuid(nd_region, dev, uuid, ns_uuid);
914 if (rc >= 0)
915 rc = nd_namespace_label_update(nd_region, dev);
916 else
917 kfree(uuid);
861 dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, 918 dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__,
862 rc, buf, buf[len - 1] == '\n' ? "" : "\n"); 919 rc, buf, buf[len - 1] == '\n' ? "" : "\n");
863 nvdimm_bus_unlock(dev); 920 nvdimm_bus_unlock(dev);
864 device_unlock(dev); 921 device_unlock(dev);
865 922
866 return rc ? rc : len; 923 return rc < 0 ? rc : len;
867} 924}
868static DEVICE_ATTR_RW(uuid); 925static DEVICE_ATTR_RW(uuid);
869 926
@@ -907,6 +964,7 @@ static ssize_t sector_size_store(struct device *dev,
907 struct device_attribute *attr, const char *buf, size_t len) 964 struct device_attribute *attr, const char *buf, size_t len)
908{ 965{
909 struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev); 966 struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
967 struct nd_region *nd_region = to_nd_region(dev->parent);
910 ssize_t rc; 968 ssize_t rc;
911 969
912 if (!is_namespace_blk(dev)) 970 if (!is_namespace_blk(dev))
@@ -916,8 +974,11 @@ static ssize_t sector_size_store(struct device *dev,
916 nvdimm_bus_lock(dev); 974 nvdimm_bus_lock(dev);
917 rc = nd_sector_size_store(dev, buf, &nsblk->lbasize, 975 rc = nd_sector_size_store(dev, buf, &nsblk->lbasize,
918 ns_lbasize_supported); 976 ns_lbasize_supported);
919 dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, 977 if (rc >= 0)
920 rc, buf, buf[len - 1] == '\n' ? "" : "\n"); 978 rc = nd_namespace_label_update(nd_region, dev);
979 dev_dbg(dev, "%s: result: %zd %s: %s%s", __func__,
980 rc, rc < 0 ? "tried" : "wrote", buf,
981 buf[len - 1] == '\n' ? "" : "\n");
921 nvdimm_bus_unlock(dev); 982 nvdimm_bus_unlock(dev);
922 device_unlock(dev); 983 device_unlock(dev);
923 984