aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2012-09-26 11:51:44 -0400
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-10-03 05:29:37 -0400
commit00abf3041590da6ad7533bf592e8dd452820109f (patch)
tree0fb880d525990bf34ecb029f9a70f05f8a3eb48c
parenta7306653705e456c8affeb4efe9542b9f6b757ad (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.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 0910c2cece5..d56ae1cf65e 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 */
1214int 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
1286out_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