Merge commit 'v2.6.39-rc3' into for-2.6.39
[pandora-kernel.git] / drivers / mtd / ubi / scan.c
index 79ca304..d2d12ab 100644 (file)
  * eraseblocks are put to the @free list and the physical eraseblock to be
  * erased are put to the @erase list.
  *
+ * About corruptions
+ * ~~~~~~~~~~~~~~~~~
+ *
+ * UBI protects EC and VID headers with CRC-32 checksums, so it can detect
+ * whether the headers are corrupted or not. Sometimes UBI also protects the
+ * data with CRC-32, e.g., when it executes the atomic LEB change operation, or
+ * when it moves the contents of a PEB for wear-leveling purposes.
+ *
  * UBI tries to distinguish between 2 types of corruptions.
- * 1. Corruptions caused by power cuts. These are harmless and expected
- *    corruptions and UBI tries to handle them gracefully, without printing too
- *    many warnings and error messages. The idea is that we do not lose
- *    important data in these case - we may lose only the data which was being
- *    written to the media just before the power cut happened, and the upper
- *    layers (e.g., UBIFS) are supposed to handle these situations. UBI puts
- *    these PEBs to the head of the @erase list and they are scheduled for
- *    erasure.
+ *
+ * 1. Corruptions caused by power cuts. These are expected corruptions and UBI
+ * tries to handle them gracefully, without printing too many warnings and
+ * error messages. The idea is that we do not lose important data in these case
+ * - we may lose only the data which was being written to the media just before
+ * the power cut happened, and the upper layers (e.g., UBIFS) are supposed to
+ * handle such data losses (e.g., by using the FS journal).
+ *
+ * When UBI detects a corruption (CRC-32 mismatch) in a PEB, and it looks like
+ * the reason is a power cut, UBI puts this PEB to the @erase list, and all
+ * PEBs in the @erase list are scheduled for erasure later.
  *
  * 2. Unexpected corruptions which are not caused by power cuts. During
- *    scanning, such PEBs are put to the @corr list and UBI preserves them.
- *    Obviously, this lessens the amount of available PEBs, and if at some
- *    point UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly
- *    informs about such PEBs every time the MTD device is attached.
+ * scanning, such PEBs are put to the @corr list and UBI preserves them.
+ * Obviously, this lessens the amount of available PEBs, and if at some  point
+ * UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly informs
+ * about such PEBs every time the MTD device is attached.
  *
  * However, it is difficult to reliably distinguish between these types of
- * corruptions and UBI's strategy is as follows. UBI assumes (2.) if the VID
- * header is corrupted and the data area does not contain all 0xFFs, and there
- * were not bit-flips or integrity errors while reading the data area. Otherwise
- * UBI assumes (1.). The assumptions are:
- *   o if the data area contains only 0xFFs, there is no data, and it is safe
- *     to just erase this PEB.
- *   o if the data area has bit-flips and data integrity errors (ECC errors on
+ * corruptions and UBI's strategy is as follows. UBI assumes corruption type 2
+ * if the VID header is corrupted and the data area does not contain all 0xFFs,
+ * and there were no bit-flips or integrity errors while reading the data area.
+ * Otherwise UBI assumes corruption type 1. So the decision criteria are as
+ * follows.
+ *   o If the data area contains only 0xFFs, there is no data, and it is safe
+ *     to just erase this PEB - this is corruption type 1.
+ *   o If the data area has bit-flips or data integrity errors (ECC errors on
  *     NAND), it is probably a PEB which was being erased when power cut
- *     happened.
+ *     happened, so this is corruption type 1. However, this is just a guess,
+ *     which might be wrong.
+ *   o Otherwise this it corruption type 2.
  */
 
 #include <linux/err.h>
@@ -74,7 +88,7 @@
 #include <linux/random.h>
 #include "ubi.h"
 
-#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
+#ifdef CONFIG_MTD_UBI_DEBUG
 static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si);
 #else
 #define paranoid_check_si(ubi, si) 0
@@ -115,7 +129,7 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head,
        } else
                BUG();
 
-       seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL);
+       seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL);
        if (!seb)
                return -ENOMEM;
 
@@ -144,7 +158,7 @@ static int add_corrupted(struct ubi_scan_info *si, int pnum, int ec)
 
        dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec);
 
-       seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL);
+       seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL);
        if (!seb)
                return -ENOMEM;
 
@@ -553,7 +567,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
        if (err)
                return err;
 
-       seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL);
+       seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL);
        if (!seb)
                return -ENOMEM;
 
@@ -954,7 +968,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
                         * contains garbage because of a power cut during erase
                         * operation. So we just schedule this PEB for erasure.
                         *
-                        * Besides, in case of NOR flash, we deliberatly
+                        * Besides, in case of NOR flash, we deliberately
                         * corrupt both headers because NOR flash erasure is
                         * slow and can start from the end.
                         */
@@ -1152,9 +1166,15 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
        si->volumes = RB_ROOT;
 
        err = -ENOMEM;
+       si->scan_leb_slab = kmem_cache_create("ubi_scan_leb_slab",
+                                             sizeof(struct ubi_scan_leb),
+                                             0, 0, NULL);
+       if (!si->scan_leb_slab)
+               goto out_si;
+
        ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
        if (!ech)
-               goto out_si;
+               goto out_slab;
 
        vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
        if (!vidh)
@@ -1215,6 +1235,8 @@ out_vidh:
        ubi_free_vid_hdr(ubi, vidh);
 out_ech:
        kfree(ech);
+out_slab:
+       kmem_cache_destroy(si->scan_leb_slab);
 out_si:
        ubi_scan_destroy_si(si);
        return ERR_PTR(err);
@@ -1223,11 +1245,12 @@ out_si:
 /**
  * destroy_sv - free the scanning volume information
  * @sv: scanning volume information
+ * @si: scanning information
  *
  * This function destroys the volume RB-tree (@sv->root) and the scanning
  * volume information.
  */
-static void destroy_sv(struct ubi_scan_volume *sv)
+static void destroy_sv(struct ubi_scan_info *si, struct ubi_scan_volume *sv)
 {
        struct ubi_scan_leb *seb;
        struct rb_node *this = sv->root.rb_node;
@@ -1247,7 +1270,7 @@ static void destroy_sv(struct ubi_scan_volume *sv)
                                        this->rb_right = NULL;
                        }
 
-                       kfree(seb);
+                       kmem_cache_free(si->scan_leb_slab, seb);
                }
        }
        kfree(sv);
@@ -1265,19 +1288,19 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si)
 
        list_for_each_entry_safe(seb, seb_tmp, &si->alien, u.list) {
                list_del(&seb->u.list);
-               kfree(seb);
+               kmem_cache_free(si->scan_leb_slab, seb);
        }
        list_for_each_entry_safe(seb, seb_tmp, &si->erase, u.list) {
                list_del(&seb->u.list);
-               kfree(seb);
+               kmem_cache_free(si->scan_leb_slab, seb);
        }
        list_for_each_entry_safe(seb, seb_tmp, &si->corr, u.list) {
                list_del(&seb->u.list);
-               kfree(seb);
+               kmem_cache_free(si->scan_leb_slab, seb);
        }
        list_for_each_entry_safe(seb, seb_tmp, &si->free, u.list) {
                list_del(&seb->u.list);
-               kfree(seb);
+               kmem_cache_free(si->scan_leb_slab, seb);
        }
 
        /* Destroy the volume RB-tree */
@@ -1298,14 +1321,15 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si)
                                        rb->rb_right = NULL;
                        }
 
-                       destroy_sv(sv);
+                       destroy_sv(si, sv);
                }
        }
 
+       kmem_cache_destroy(si->scan_leb_slab);
        kfree(si);
 }
 
-#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
+#ifdef CONFIG_MTD_UBI_DEBUG
 
 /**
  * paranoid_check_si - check the scanning information.
@@ -1323,6 +1347,9 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si)
        struct ubi_scan_leb *seb, *last_seb;
        uint8_t *buf;
 
+       if (!(ubi_chk_flags & UBI_CHK_GEN))
+               return 0;
+
        /*
         * At first, check that scanning information is OK.
         */
@@ -1575,4 +1602,4 @@ out:
        return -EINVAL;
 }
 
-#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */
+#endif /* CONFIG_MTD_UBI_DEBUG */