@@ -29,7 +29,10 @@ static void namespace_io_release(struct device *dev)
29
29
static void namespace_pmem_release (struct device * dev )
30
30
{
31
31
struct nd_namespace_pmem * nspm = to_nd_namespace_pmem (dev );
32
+ struct nd_region * nd_region = to_nd_region (dev -> parent );
32
33
34
+ if (nspm -> id >= 0 )
35
+ ida_simple_remove (& nd_region -> ns_ida , nspm -> id );
33
36
kfree (nspm -> alt_name );
34
37
kfree (nspm -> uuid );
35
38
kfree (nspm );
@@ -833,13 +836,45 @@ static int grow_dpa_allocation(struct nd_region *nd_region,
833
836
return 0 ;
834
837
}
835
838
836
- static void nd_namespace_pmem_set_size (struct nd_region * nd_region ,
839
+ static void nd_namespace_pmem_set_resource (struct nd_region * nd_region ,
837
840
struct nd_namespace_pmem * nspm , resource_size_t size )
838
841
{
839
842
struct resource * res = & nspm -> nsio .res ;
843
+ resource_size_t offset = 0 ;
840
844
841
- res -> start = nd_region -> ndr_start ;
842
- res -> end = nd_region -> ndr_start + size - 1 ;
845
+ if (size && !nspm -> uuid ) {
846
+ WARN_ON_ONCE (1 );
847
+ size = 0 ;
848
+ }
849
+
850
+ if (size && nspm -> uuid ) {
851
+ struct nd_mapping * nd_mapping = & nd_region -> mapping [0 ];
852
+ struct nvdimm_drvdata * ndd = to_ndd (nd_mapping );
853
+ struct nd_label_id label_id ;
854
+ struct resource * res ;
855
+
856
+ if (!ndd ) {
857
+ size = 0 ;
858
+ goto out ;
859
+ }
860
+
861
+ nd_label_gen_id (& label_id , nspm -> uuid , 0 );
862
+
863
+ /* calculate a spa offset from the dpa allocation offset */
864
+ for_each_dpa_resource (ndd , res )
865
+ if (strcmp (res -> name , label_id .id ) == 0 ) {
866
+ offset = (res -> start - nd_mapping -> start )
867
+ * nd_region -> ndr_mappings ;
868
+ goto out ;
869
+ }
870
+
871
+ WARN_ON_ONCE (1 );
872
+ size = 0 ;
873
+ }
874
+
875
+ out :
876
+ res -> start = nd_region -> ndr_start + offset ;
877
+ res -> end = res -> start + size - 1 ;
843
878
}
844
879
845
880
static bool uuid_not_set (const u8 * uuid , struct device * dev , const char * where )
@@ -930,7 +965,7 @@ static ssize_t __size_store(struct device *dev, unsigned long long val)
930
965
if (is_namespace_pmem (dev )) {
931
966
struct nd_namespace_pmem * nspm = to_nd_namespace_pmem (dev );
932
967
933
- nd_namespace_pmem_set_size (nd_region , nspm ,
968
+ nd_namespace_pmem_set_resource (nd_region , nspm ,
934
969
val * nd_region -> ndr_mappings );
935
970
} else if (is_namespace_blk (dev )) {
936
971
struct nd_namespace_blk * nsblk = to_nd_namespace_blk (dev );
@@ -1546,6 +1581,7 @@ static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id)
1546
1581
1547
1582
for (i = 0 ; i < nd_region -> ndr_mappings ; i ++ ) {
1548
1583
struct nd_mapping * nd_mapping = & nd_region -> mapping [i ];
1584
+ struct nvdimm_drvdata * ndd = to_ndd (nd_mapping );
1549
1585
struct nd_namespace_label * nd_label = NULL ;
1550
1586
u64 hw_start , hw_end , pmem_start , pmem_end ;
1551
1587
struct nd_label_ent * label_ent ;
@@ -1573,10 +1609,14 @@ static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id)
1573
1609
hw_end = hw_start + nd_mapping -> size ;
1574
1610
pmem_start = __le64_to_cpu (nd_label -> dpa );
1575
1611
pmem_end = pmem_start + __le64_to_cpu (nd_label -> rawsize );
1576
- if (pmem_start == hw_start && pmem_end <= hw_end )
1612
+ if (pmem_start >= hw_start && pmem_start < hw_end
1613
+ && pmem_end <= hw_end && pmem_end > hw_start )
1577
1614
/* pass */ ;
1578
- else
1615
+ else {
1616
+ dev_dbg (& nd_region -> dev , "%s invalid label for %pUb\n" ,
1617
+ dev_name (ndd -> dev ), nd_label -> uuid );
1579
1618
return - EINVAL ;
1619
+ }
1580
1620
1581
1621
/* move recently validated label to the front of the list */
1582
1622
list_move (& label_ent -> list , & nd_mapping -> labels );
@@ -1618,6 +1658,7 @@ struct device *create_namespace_pmem(struct nd_region *nd_region,
1618
1658
if (!nspm )
1619
1659
return ERR_PTR (- ENOMEM );
1620
1660
1661
+ nspm -> id = -1 ;
1621
1662
dev = & nspm -> nsio .common .dev ;
1622
1663
dev -> type = & namespace_pmem_device_type ;
1623
1664
dev -> parent = & nd_region -> dev ;
@@ -1629,11 +1670,15 @@ struct device *create_namespace_pmem(struct nd_region *nd_region,
1629
1670
if (!has_uuid_at_pos (nd_region , nd_label -> uuid , cookie , i ))
1630
1671
break ;
1631
1672
if (i < nd_region -> ndr_mappings ) {
1673
+ struct nvdimm_drvdata * ndd = to_ndd (& nd_region -> mapping [i ]);
1674
+
1632
1675
/*
1633
1676
* Give up if we don't find an instance of a uuid at each
1634
1677
* position (from 0 to nd_region->ndr_mappings - 1), or if we
1635
1678
* find a dimm with two instances of the same uuid.
1636
1679
*/
1680
+ dev_err (& nd_region -> dev , "%s missing label for %pUb\n" ,
1681
+ dev_name (ndd -> dev ), nd_label -> uuid );
1637
1682
rc = - EINVAL ;
1638
1683
goto err ;
1639
1684
}
@@ -1679,7 +1724,7 @@ struct device *create_namespace_pmem(struct nd_region *nd_region,
1679
1724
goto err ;
1680
1725
}
1681
1726
1682
- nd_namespace_pmem_set_size (nd_region , nspm , size );
1727
+ nd_namespace_pmem_set_resource (nd_region , nspm , size );
1683
1728
1684
1729
return dev ;
1685
1730
err :
@@ -1961,23 +2006,31 @@ static struct device **scan_labels(struct nd_region *nd_region)
1961
2006
goto err ;
1962
2007
dev = & nspm -> nsio .common .dev ;
1963
2008
dev -> type = & namespace_pmem_device_type ;
1964
- nd_namespace_pmem_set_size (nd_region , nspm , 0 );
2009
+ nd_namespace_pmem_set_resource (nd_region , nspm , 0 );
1965
2010
}
1966
2011
dev -> parent = & nd_region -> dev ;
1967
2012
devs [count ++ ] = dev ;
1968
2013
} else if (is_nd_pmem (& nd_region -> dev )) {
1969
2014
/* clean unselected labels */
1970
2015
for (i = 0 ; i < nd_region -> ndr_mappings ; i ++ ) {
2016
+ struct list_head * l , * e ;
2017
+ LIST_HEAD (list );
2018
+ int j ;
2019
+
1971
2020
nd_mapping = & nd_region -> mapping [i ];
1972
2021
if (list_empty (& nd_mapping -> labels )) {
1973
2022
WARN_ON (1 );
1974
2023
continue ;
1975
2024
}
1976
- label_ent = list_first_entry (& nd_mapping -> labels ,
1977
- typeof (* label_ent ), list );
1978
- list_del (& label_ent -> list );
2025
+
2026
+ j = count ;
2027
+ list_for_each_safe (l , e , & nd_mapping -> labels ) {
2028
+ if (!j -- )
2029
+ break ;
2030
+ list_move_tail (l , & list );
2031
+ }
1979
2032
nd_mapping_free_labels (nd_mapping );
1980
- list_add ( & label_ent -> list , & nd_mapping -> labels );
2033
+ list_splice_init ( & list , & nd_mapping -> labels );
1981
2034
}
1982
2035
}
1983
2036
@@ -2117,6 +2170,13 @@ int nd_region_register_namespaces(struct nd_region *nd_region, int *err)
2117
2170
id = ida_simple_get (& nd_region -> ns_ida , 0 , 0 ,
2118
2171
GFP_KERNEL );
2119
2172
nsblk -> id = id ;
2173
+ } else if (type == ND_DEVICE_NAMESPACE_PMEM ) {
2174
+ struct nd_namespace_pmem * nspm ;
2175
+
2176
+ nspm = to_nd_namespace_pmem (dev );
2177
+ id = ida_simple_get (& nd_region -> ns_ida , 0 , 0 ,
2178
+ GFP_KERNEL );
2179
+ nspm -> id = id ;
2120
2180
} else
2121
2181
id = i ;
2122
2182
0 commit comments