@@ -968,326 +968,6 @@ static int __pmem_label_update(struct nd_region *nd_region,
968968 return rc ;
969969}
970970
971- static bool is_old_resource (struct resource * res , struct resource * * list , int n )
972- {
973- int i ;
974-
975- if (res -> flags & DPA_RESOURCE_ADJUSTED )
976- return false;
977- for (i = 0 ; i < n ; i ++ )
978- if (res == list [i ])
979- return true;
980- return false;
981- }
982-
983- static struct resource * to_resource (struct nvdimm_drvdata * ndd ,
984- struct nd_namespace_label * nd_label )
985- {
986- struct resource * res ;
987-
988- for_each_dpa_resource (ndd , res ) {
989- if (res -> start != nsl_get_dpa (ndd , nd_label ))
990- continue ;
991- if (resource_size (res ) != nsl_get_rawsize (ndd , nd_label ))
992- continue ;
993- return res ;
994- }
995-
996- return NULL ;
997- }
998-
999- /*
1000- * Use the presence of the type_guid as a flag to determine isetcookie
1001- * usage and nlabel + position policy for blk-aperture namespaces.
1002- */
1003- static void nsl_set_blk_isetcookie (struct nvdimm_drvdata * ndd ,
1004- struct nd_namespace_label * nd_label ,
1005- u64 isetcookie )
1006- {
1007- if (efi_namespace_label_has (ndd , type_guid )) {
1008- nsl_set_isetcookie (ndd , nd_label , isetcookie );
1009- return ;
1010- }
1011- nsl_set_isetcookie (ndd , nd_label , 0 ); /* N/A */
1012- }
1013-
1014- bool nsl_validate_blk_isetcookie (struct nvdimm_drvdata * ndd ,
1015- struct nd_namespace_label * nd_label ,
1016- u64 isetcookie )
1017- {
1018- if (!efi_namespace_label_has (ndd , type_guid ))
1019- return true;
1020-
1021- if (nsl_get_isetcookie (ndd , nd_label ) != isetcookie ) {
1022- dev_dbg (ndd -> dev , "expect cookie %#llx got %#llx\n" , isetcookie ,
1023- nsl_get_isetcookie (ndd , nd_label ));
1024- return false;
1025- }
1026-
1027- return true;
1028- }
1029-
1030- static void nsl_set_blk_nlabel (struct nvdimm_drvdata * ndd ,
1031- struct nd_namespace_label * nd_label , int nlabel ,
1032- bool first )
1033- {
1034- if (!efi_namespace_label_has (ndd , type_guid )) {
1035- nsl_set_nlabel (ndd , nd_label , 0 ); /* N/A */
1036- return ;
1037- }
1038- nsl_set_nlabel (ndd , nd_label , first ? nlabel : 0xffff );
1039- }
1040-
1041- static void nsl_set_blk_position (struct nvdimm_drvdata * ndd ,
1042- struct nd_namespace_label * nd_label ,
1043- bool first )
1044- {
1045- if (!efi_namespace_label_has (ndd , type_guid )) {
1046- nsl_set_position (ndd , nd_label , 0 );
1047- return ;
1048- }
1049- nsl_set_position (ndd , nd_label , first ? 0 : 0xffff );
1050- }
1051-
1052- /*
1053- * 1/ Account all the labels that can be freed after this update
1054- * 2/ Allocate and write the label to the staging (next) index
1055- * 3/ Record the resources in the namespace device
1056- */
1057- static int __blk_label_update (struct nd_region * nd_region ,
1058- struct nd_mapping * nd_mapping , struct nd_namespace_blk * nsblk ,
1059- int num_labels )
1060- {
1061- int i , alloc , victims , nfree , old_num_resources , nlabel , rc = - ENXIO ;
1062- struct nd_interleave_set * nd_set = nd_region -> nd_set ;
1063- struct nd_namespace_common * ndns = & nsblk -> common ;
1064- struct nvdimm_drvdata * ndd = to_ndd (nd_mapping );
1065- struct nd_namespace_label * nd_label ;
1066- struct nd_label_ent * label_ent , * e ;
1067- struct nd_namespace_index * nsindex ;
1068- unsigned long * free , * victim_map = NULL ;
1069- struct resource * res , * * old_res_list ;
1070- struct nd_label_id label_id ;
1071- int min_dpa_idx = 0 ;
1072- LIST_HEAD (list );
1073- u32 nslot , slot ;
1074-
1075- if (!preamble_next (ndd , & nsindex , & free , & nslot ))
1076- return - ENXIO ;
1077-
1078- old_res_list = nsblk -> res ;
1079- nfree = nd_label_nfree (ndd );
1080- old_num_resources = nsblk -> num_resources ;
1081- nd_label_gen_id (& label_id , nsblk -> uuid , NSLABEL_FLAG_LOCAL );
1082-
1083- /*
1084- * We need to loop over the old resources a few times, which seems a
1085- * bit inefficient, but we need to know that we have the label
1086- * space before we start mutating the tracking structures.
1087- * Otherwise the recovery method of last resort for userspace is
1088- * disable and re-enable the parent region.
1089- */
1090- alloc = 0 ;
1091- for_each_dpa_resource (ndd , res ) {
1092- if (strcmp (res -> name , label_id .id ) != 0 )
1093- continue ;
1094- if (!is_old_resource (res , old_res_list , old_num_resources ))
1095- alloc ++ ;
1096- }
1097-
1098- victims = 0 ;
1099- if (old_num_resources ) {
1100- /* convert old local-label-map to dimm-slot victim-map */
1101- victim_map = bitmap_zalloc (nslot , GFP_KERNEL );
1102- if (!victim_map )
1103- return - ENOMEM ;
1104-
1105- /* mark unused labels for garbage collection */
1106- for_each_clear_bit_le (slot , free , nslot ) {
1107- nd_label = to_label (ndd , slot );
1108- if (!nsl_uuid_equal (ndd , nd_label , nsblk -> uuid ))
1109- continue ;
1110- res = to_resource (ndd , nd_label );
1111- if (res && is_old_resource (res , old_res_list ,
1112- old_num_resources ))
1113- continue ;
1114- slot = to_slot (ndd , nd_label );
1115- set_bit (slot , victim_map );
1116- victims ++ ;
1117- }
1118- }
1119-
1120- /* don't allow updates that consume the last label */
1121- if (nfree - alloc < 0 || nfree - alloc + victims < 1 ) {
1122- dev_info (& nsblk -> common .dev , "insufficient label space\n" );
1123- bitmap_free (victim_map );
1124- return - ENOSPC ;
1125- }
1126- /* from here on we need to abort on error */
1127-
1128-
1129- /* assign all resources to the namespace before writing the labels */
1130- nsblk -> res = NULL ;
1131- nsblk -> num_resources = 0 ;
1132- for_each_dpa_resource (ndd , res ) {
1133- if (strcmp (res -> name , label_id .id ) != 0 )
1134- continue ;
1135- if (!nsblk_add_resource (nd_region , ndd , nsblk , res -> start )) {
1136- rc = - ENOMEM ;
1137- goto abort ;
1138- }
1139- }
1140-
1141- /* release slots associated with any invalidated UUIDs */
1142- mutex_lock (& nd_mapping -> lock );
1143- list_for_each_entry_safe (label_ent , e , & nd_mapping -> labels , list )
1144- if (test_and_clear_bit (ND_LABEL_REAP , & label_ent -> flags )) {
1145- reap_victim (nd_mapping , label_ent );
1146- list_move (& label_ent -> list , & list );
1147- }
1148- mutex_unlock (& nd_mapping -> lock );
1149-
1150- /*
1151- * Find the resource associated with the first label in the set
1152- * per the v1.2 namespace specification.
1153- */
1154- for (i = 0 ; i < nsblk -> num_resources ; i ++ ) {
1155- struct resource * min = nsblk -> res [min_dpa_idx ];
1156-
1157- res = nsblk -> res [i ];
1158- if (res -> start < min -> start )
1159- min_dpa_idx = i ;
1160- }
1161-
1162- for (i = 0 ; i < nsblk -> num_resources ; i ++ ) {
1163- size_t offset ;
1164-
1165- res = nsblk -> res [i ];
1166- if (is_old_resource (res , old_res_list , old_num_resources ))
1167- continue ; /* carry-over */
1168- slot = nd_label_alloc_slot (ndd );
1169- if (slot == UINT_MAX ) {
1170- rc = - ENXIO ;
1171- goto abort ;
1172- }
1173- dev_dbg (ndd -> dev , "allocated: %d\n" , slot );
1174-
1175- nd_label = to_label (ndd , slot );
1176- memset (nd_label , 0 , sizeof_namespace_label (ndd ));
1177- nsl_set_uuid (ndd , nd_label , nsblk -> uuid );
1178- nsl_set_name (ndd , nd_label , nsblk -> alt_name );
1179- nsl_set_flags (ndd , nd_label , NSLABEL_FLAG_LOCAL );
1180-
1181- nsl_set_blk_nlabel (ndd , nd_label , nsblk -> num_resources ,
1182- i == min_dpa_idx );
1183- nsl_set_blk_position (ndd , nd_label , i == min_dpa_idx );
1184- nsl_set_blk_isetcookie (ndd , nd_label , nd_set -> cookie2 );
1185-
1186- nsl_set_dpa (ndd , nd_label , res -> start );
1187- nsl_set_rawsize (ndd , nd_label , resource_size (res ));
1188- nsl_set_lbasize (ndd , nd_label , nsblk -> lbasize );
1189- nsl_set_slot (ndd , nd_label , slot );
1190- nsl_set_type_guid (ndd , nd_label , & nd_set -> type_guid );
1191- nsl_set_claim_class (ndd , nd_label , ndns -> claim_class );
1192- nsl_calculate_checksum (ndd , nd_label );
1193-
1194- /* update label */
1195- offset = nd_label_offset (ndd , nd_label );
1196- rc = nvdimm_set_config_data (ndd , offset , nd_label ,
1197- sizeof_namespace_label (ndd ));
1198- if (rc < 0 )
1199- goto abort ;
1200- }
1201-
1202- /* free up now unused slots in the new index */
1203- for_each_set_bit (slot , victim_map , victim_map ? nslot : 0 ) {
1204- dev_dbg (ndd -> dev , "free: %d\n" , slot );
1205- nd_label_free_slot (ndd , slot );
1206- }
1207-
1208- /* update index */
1209- rc = nd_label_write_index (ndd , ndd -> ns_next ,
1210- nd_inc_seq (__le32_to_cpu (nsindex -> seq )), 0 );
1211- if (rc )
1212- goto abort ;
1213-
1214- /*
1215- * Now that the on-dimm labels are up to date, fix up the tracking
1216- * entries in nd_mapping->labels
1217- */
1218- nlabel = 0 ;
1219- mutex_lock (& nd_mapping -> lock );
1220- list_for_each_entry_safe (label_ent , e , & nd_mapping -> labels , list ) {
1221- nd_label = label_ent -> label ;
1222- if (!nd_label )
1223- continue ;
1224- nlabel ++ ;
1225- if (!nsl_uuid_equal (ndd , nd_label , nsblk -> uuid ))
1226- continue ;
1227- nlabel -- ;
1228- list_move (& label_ent -> list , & list );
1229- label_ent -> label = NULL ;
1230- }
1231- list_splice_tail_init (& list , & nd_mapping -> labels );
1232- mutex_unlock (& nd_mapping -> lock );
1233-
1234- if (nlabel + nsblk -> num_resources > num_labels ) {
1235- /*
1236- * Bug, we can't end up with more resources than
1237- * available labels
1238- */
1239- WARN_ON_ONCE (1 );
1240- rc = - ENXIO ;
1241- goto out ;
1242- }
1243-
1244- mutex_lock (& nd_mapping -> lock );
1245- label_ent = list_first_entry_or_null (& nd_mapping -> labels ,
1246- typeof (* label_ent ), list );
1247- if (!label_ent ) {
1248- WARN_ON (1 );
1249- mutex_unlock (& nd_mapping -> lock );
1250- rc = - ENXIO ;
1251- goto out ;
1252- }
1253- for_each_clear_bit_le (slot , free , nslot ) {
1254- nd_label = to_label (ndd , slot );
1255- if (!nsl_uuid_equal (ndd , nd_label , nsblk -> uuid ))
1256- continue ;
1257- res = to_resource (ndd , nd_label );
1258- res -> flags &= ~DPA_RESOURCE_ADJUSTED ;
1259- dev_vdbg (& nsblk -> common .dev , "assign label slot: %d\n" , slot );
1260- list_for_each_entry_from (label_ent , & nd_mapping -> labels , list ) {
1261- if (label_ent -> label )
1262- continue ;
1263- label_ent -> label = nd_label ;
1264- nd_label = NULL ;
1265- break ;
1266- }
1267- if (nd_label )
1268- dev_WARN (& nsblk -> common .dev ,
1269- "failed to track label slot%d\n" , slot );
1270- }
1271- mutex_unlock (& nd_mapping -> lock );
1272-
1273- out :
1274- kfree (old_res_list );
1275- bitmap_free (victim_map );
1276- return rc ;
1277-
1278- abort :
1279- /*
1280- * 1/ repair the allocated label bitmap in the index
1281- * 2/ restore the resource list
1282- */
1283- nd_label_copy (ndd , nsindex , to_current_namespace_index (ndd ));
1284- kfree (nsblk -> res );
1285- nsblk -> res = old_res_list ;
1286- nsblk -> num_resources = old_num_resources ;
1287- old_res_list = NULL ;
1288- goto out ;
1289- }
1290-
1291971static int init_labels (struct nd_mapping * nd_mapping , int num_labels )
1292972{
1293973 int i , old_num_labels = 0 ;
@@ -1425,26 +1105,6 @@ int nd_pmem_namespace_label_update(struct nd_region *nd_region,
14251105 return 0 ;
14261106}
14271107
1428- int nd_blk_namespace_label_update (struct nd_region * nd_region ,
1429- struct nd_namespace_blk * nsblk , resource_size_t size )
1430- {
1431- struct nd_mapping * nd_mapping = & nd_region -> mapping [0 ];
1432- struct resource * res ;
1433- int count = 0 ;
1434-
1435- if (size == 0 )
1436- return del_labels (nd_mapping , nsblk -> uuid );
1437-
1438- for_each_dpa_resource (to_ndd (nd_mapping ), res )
1439- count ++ ;
1440-
1441- count = init_labels (nd_mapping , count );
1442- if (count < 0 )
1443- return count ;
1444-
1445- return __blk_label_update (nd_region , nd_mapping , nsblk , count );
1446- }
1447-
14481108int __init nd_label_init (void )
14491109{
14501110 WARN_ON (guid_parse (NVDIMM_BTT_GUID , & nvdimm_btt_guid ));
0 commit comments