]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
UBI: Add self_check_eba()
authorRichard Weinberger <richard@nod.at>
Wed, 26 Sep 2012 15:51:44 +0000 (17:51 +0200)
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Wed, 3 Oct 2012 09:29:37 +0000 (12:29 +0300)
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>
drivers/mtd/ubi/eba.c

index 0910c2cece5e5ee1c478446387f6f638d4a76bb5..d56ae1cf65e67bdc558b77c2100749d9d59e8f99 100644 (file)
@@ -1201,6 +1201,102 @@ static void print_rsvd_warning(struct ubi_device *ubi,
                         ubi->corr_peb_count);
 }
 
+/**
+ * self_check_eba - run a self check on the EBA table constructed by fastmap.
+ * @ubi: UBI device description object
+ * @ai_fastmap: UBI attach info object created by fastmap
+ * @ai_scan: UBI attach info object created by scanning
+ *
+ * Returns < 0 in case of an internal error, 0 otherwise.
+ * If a bad EBA table entry was found it will be printed out and
+ * ubi_assert() triggers.
+ */
+int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
+                  struct ubi_attach_info *ai_scan)
+{
+       int i, j, num_volumes, ret = 0;
+       int **scan_eba, **fm_eba;
+       struct ubi_ainf_volume *av;
+       struct ubi_volume *vol;
+       struct ubi_ainf_peb *aeb;
+       struct rb_node *rb;
+
+       num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT;
+
+       scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL);
+       if (!scan_eba)
+               return -ENOMEM;
+
+       fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL);
+       if (!fm_eba) {
+               kfree(scan_eba);
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < num_volumes; i++) {
+               vol = ubi->volumes[i];
+               if (!vol)
+                       continue;
+
+               scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba),
+                                     GFP_KERNEL);
+               if (!scan_eba[i]) {
+                       ret = -ENOMEM;
+                       goto out_free;
+               }
+
+               fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba),
+                                   GFP_KERNEL);
+               if (!fm_eba[i]) {
+                       ret = -ENOMEM;
+                       goto out_free;
+               }
+
+               for (j = 0; j < vol->reserved_pebs; j++)
+                       scan_eba[i][j] = fm_eba[i][j] = UBI_LEB_UNMAPPED;
+
+               av = ubi_find_av(ai_scan, idx2vol_id(ubi, i));
+               if (!av)
+                       continue;
+
+               ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
+                       scan_eba[i][aeb->lnum] = aeb->pnum;
+
+               av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i));
+               if (!av)
+                       continue;
+
+               ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
+                       fm_eba[i][aeb->lnum] = aeb->pnum;
+
+               for (j = 0; j < vol->reserved_pebs; j++) {
+                       if (scan_eba[i][j] != fm_eba[i][j]) {
+                               if (scan_eba[i][j] == UBI_LEB_UNMAPPED ||
+                                       fm_eba[i][j] == UBI_LEB_UNMAPPED)
+                                       continue;
+
+                               ubi_err("LEB:%i:%i is PEB:%i instead of %i!",
+                                       vol->vol_id, i, fm_eba[i][j],
+                                       scan_eba[i][j]);
+                               ubi_assert(0);
+                       }
+               }
+       }
+
+out_free:
+       for (i = 0; i < num_volumes; i++) {
+               if (!ubi->volumes[i])
+                       continue;
+
+               kfree(scan_eba[i]);
+               kfree(fm_eba[i]);
+       }
+
+       kfree(scan_eba);
+       kfree(fm_eba);
+       return ret;
+}
+
 /**
  * ubi_eba_init - initialize the EBA sub-system using attaching information.
  * @ubi: UBI device description object