UBI: print a warning if too many PEBs are corrupted
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Sun, 19 Jul 2009 11:33:14 +0000 (14:33 +0300)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Fri, 14 Aug 2009 17:01:36 +0000 (20:01 +0300)
There was a bug report recently where UBI prints:

UBI error: ubi_attach_mtd_dev: failed to attach by scanning, error -22

error messages and refuses to attach a PEB. It turned out to be a
buggy flash driver which returned garbage to almost every UBI read.
This patch makes UBI print a better message in such cases. Namely,
if UBI finds 8 or more corrupted PEBs, it prints a warning and
lists the corrupted PEBs.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
drivers/mtd/ubi/scan.c
drivers/mtd/ubi/scan.h

index 93361eadab8d4ad6ce58b3c150e02b90b3ae7b98..e7161adc419dadd45f14be17b7750ce9ed0ed532 100644 (file)
@@ -75,9 +75,10 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec,
                dbg_bld("add to free: PEB %d, EC %d", pnum, ec);
        else if (list == &si->erase)
                dbg_bld("add to erase: PEB %d, EC %d", pnum, ec);
-       else if (list == &si->corr)
+       else if (list == &si->corr) {
                dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec);
-       else if (list == &si->alien)
+               si->corr_count += 1;
+       } else if (list == &si->alien)
                dbg_bld("add to alien: PEB %d, EC %d", pnum, ec);
        else
                BUG();
@@ -937,6 +938,19 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
        if (si->is_empty)
                ubi_msg("empty MTD device detected");
 
+       /*
+        * Few corrupted PEBs are not a problem and may be just a result of
+        * unclean reboots. However, many of them may indicate some problems
+        * with the flash HW or driver. Print a warning in this case.
+        */
+       if (si->corr_count >= 8 || si->corr_count >= ubi->peb_count / 4) {
+               ubi_warn("%d PEBs are corrupted", si->corr_count);
+               printk(KERN_WARNING "corrupted PEBs are:");
+               list_for_each_entry(seb, &si->corr, u.list)
+                       printk(KERN_CONT " %d", seb->pnum);
+               printk(KERN_CONT "\n");
+       }
+
        /*
         * In case of unknown erase counter we use the mean erase counter
         * value.
index 1017cf12def56253606168e3c2ad18af674b8eae..bab31695dacef14b9ec579b4b76af0562ac7b665 100644 (file)
@@ -102,6 +102,7 @@ struct ubi_scan_volume {
  * @mean_ec: mean erase counter value
  * @ec_sum: a temporary variable used when calculating @mean_ec
  * @ec_count: a temporary variable used when calculating @mean_ec
+ * @corr_count: count of corrupted PEBs
  * @image_seq_set: indicates @ubi->image_seq is known
  *
  * This data structure contains the result of scanning and may be used by other
@@ -125,6 +126,7 @@ struct ubi_scan_info {
        int mean_ec;
        uint64_t ec_sum;
        int ec_count;
+       int corr_count;
        int image_seq_set;
 };