diff options
| author | Richard Weinberger <richard@nod.at> | 2012-09-26 11:51:44 -0400 |
|---|---|---|
| committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2012-10-03 05:29:37 -0400 |
| commit | 00abf3041590da6ad7533bf592e8dd452820109f (patch) | |
| tree | 0fb880d525990bf34ecb029f9a70f05f8a3eb48c | |
| parent | a7306653705e456c8affeb4efe9542b9f6b757ad (diff) | |
UBI: Add self_check_eba()
self_check_eba() compares two ubi_attach_info objects.
Fastmap uses this function for self checks.
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
| -rw-r--r-- | drivers/mtd/ubi/eba.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 0910c2cece5e..d56ae1cf65e6 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
| @@ -1202,6 +1202,102 @@ static void print_rsvd_warning(struct ubi_device *ubi, | |||
| 1202 | } | 1202 | } |
| 1203 | 1203 | ||
| 1204 | /** | 1204 | /** |
| 1205 | * self_check_eba - run a self check on the EBA table constructed by fastmap. | ||
| 1206 | * @ubi: UBI device description object | ||
| 1207 | * @ai_fastmap: UBI attach info object created by fastmap | ||
| 1208 | * @ai_scan: UBI attach info object created by scanning | ||
| 1209 | * | ||
| 1210 | * Returns < 0 in case of an internal error, 0 otherwise. | ||
| 1211 | * If a bad EBA table entry was found it will be printed out and | ||
| 1212 | * ubi_assert() triggers. | ||
| 1213 | */ | ||
| 1214 | int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, | ||
| 1215 | struct ubi_attach_info *ai_scan) | ||
| 1216 | { | ||
| 1217 | int i, j, num_volumes, ret = 0; | ||
| 1218 | int **scan_eba, **fm_eba; | ||
| 1219 | struct ubi_ainf_volume *av; | ||
| 1220 | struct ubi_volume *vol; | ||
| 1221 | struct ubi_ainf_peb *aeb; | ||
| 1222 | struct rb_node *rb; | ||
| 1223 | |||
| 1224 | num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; | ||
| 1225 | |||
| 1226 | scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL); | ||
| 1227 | if (!scan_eba) | ||
| 1228 | return -ENOMEM; | ||
| 1229 | |||
| 1230 | fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL); | ||
| 1231 | if (!fm_eba) { | ||
| 1232 | kfree(scan_eba); | ||
| 1233 | return -ENOMEM; | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | for (i = 0; i < num_volumes; i++) { | ||
| 1237 | vol = ubi->volumes[i]; | ||
| 1238 | if (!vol) | ||
| 1239 | continue; | ||
| 1240 | |||
| 1241 | scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba), | ||
| 1242 | GFP_KERNEL); | ||
| 1243 | if (!scan_eba[i]) { | ||
| 1244 | ret = -ENOMEM; | ||
| 1245 | goto out_free; | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba), | ||
| 1249 | GFP_KERNEL); | ||
| 1250 | if (!fm_eba[i]) { | ||
| 1251 | ret = -ENOMEM; | ||
| 1252 | goto out_free; | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | for (j = 0; j < vol->reserved_pebs; j++) | ||
| 1256 | scan_eba[i][j] = fm_eba[i][j] = UBI_LEB_UNMAPPED; | ||
| 1257 | |||
| 1258 | av = ubi_find_av(ai_scan, idx2vol_id(ubi, i)); | ||
| 1259 | if (!av) | ||
| 1260 | continue; | ||
| 1261 | |||
| 1262 | ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) | ||
| 1263 | scan_eba[i][aeb->lnum] = aeb->pnum; | ||
| 1264 | |||
| 1265 | av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i)); | ||
| 1266 | if (!av) | ||
| 1267 | continue; | ||
| 1268 | |||
| 1269 | ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) | ||
| 1270 | fm_eba[i][aeb->lnum] = aeb->pnum; | ||
| 1271 | |||
| 1272 | for (j = 0; j < vol->reserved_pebs; j++) { | ||
| 1273 | if (scan_eba[i][j] != fm_eba[i][j]) { | ||
| 1274 | if (scan_eba[i][j] == UBI_LEB_UNMAPPED || | ||
| 1275 | fm_eba[i][j] == UBI_LEB_UNMAPPED) | ||
| 1276 | continue; | ||
| 1277 | |||
| 1278 | ubi_err("LEB:%i:%i is PEB:%i instead of %i!", | ||
| 1279 | vol->vol_id, i, fm_eba[i][j], | ||
| 1280 | scan_eba[i][j]); | ||
| 1281 | ubi_assert(0); | ||
| 1282 | } | ||
| 1283 | } | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | out_free: | ||
| 1287 | for (i = 0; i < num_volumes; i++) { | ||
| 1288 | if (!ubi->volumes[i]) | ||
| 1289 | continue; | ||
| 1290 | |||
| 1291 | kfree(scan_eba[i]); | ||
| 1292 | kfree(fm_eba[i]); | ||
| 1293 | } | ||
| 1294 | |||
| 1295 | kfree(scan_eba); | ||
| 1296 | kfree(fm_eba); | ||
| 1297 | return ret; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | /** | ||
| 1205 | * ubi_eba_init - initialize the EBA sub-system using attaching information. | 1301 | * ubi_eba_init - initialize the EBA sub-system using attaching information. |
| 1206 | * @ubi: UBI device description object | 1302 | * @ubi: UBI device description object |
| 1207 | * @ai: attaching information | 1303 | * @ai: attaching information |
