aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/scan.c
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-10-20 04:54:58 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-10-21 04:20:37 -0400
commit45aafd32996e27bfc4862654ff31231bdddbe200 (patch)
treefd2dee47b52135e9532d479a0378a8ec52af6eba /drivers/mtd/ubi/scan.c
parentdf3fca4cdddfa6e1f51b65214d4342660649bd1f (diff)
UBI: tighten the corrupted PEB criteria
If we get a bit-flip of ECC error while reading the data area, do not add it to corrupted list, because it is possible that this is just unstable PEB with corruptions caused by unclean reboots. This patch also improves commentaries. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi/scan.c')
-rw-r--r--drivers/mtd/ubi/scan.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index e7b800b1d072..3c631863bf40 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -45,14 +45,26 @@
45 * many warnings and error messages. The idea is that we do not lose 45 * many warnings and error messages. The idea is that we do not lose
46 * important data in these case - we may lose only the data which was being 46 * important data in these case - we may lose only the data which was being
47 * written to the media just before the power cut happened, and the upper 47 * written to the media just before the power cut happened, and the upper
48 * layers are supposed to handle these situations. UBI puts these PEBs to 48 * layers (e.g., UBIFS) are supposed to handle these situations. UBI puts
49 * the head of the @erase list and they are scheduled for erasure. 49 * these PEBs to the head of the @erase list and they are scheduled for
50 * erasure.
50 * 51 *
51 * 2. Unexpected corruptions which are not caused by power cuts. During 52 * 2. Unexpected corruptions which are not caused by power cuts. During
52 * scanning, such PEBs are put to the @corr list and UBI preserves them. 53 * scanning, such PEBs are put to the @corr list and UBI preserves them.
53 * Obviously, this lessens the amount of available PEBs, and if at some 54 * Obviously, this lessens the amount of available PEBs, and if at some
54 * point UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly 55 * point UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly
55 * informs about such PEBs every time the MTD device is attached. 56 * informs about such PEBs every time the MTD device is attached.
57 *
58 * However, it is difficult to reliably distinguish between these types of
59 * corruptions and UBI's strategy is as follows. UBI assumes (2.) if the VID
60 * header is corrupted and the data area does not contain all 0xFFs, and there
61 * were not bit-flips or integrity errors while reading the data area. Otherwise
62 * UBI assumes (1.). The assumptions are:
63 * o if the data area contains only 0xFFs, there is no data, and it is safe
64 * to just erase this PEB.
65 * o if the data area has bit-flips and data integrity errors (ECC errors on
66 * NAND), it is probably a PEB which was being erased when power cut
67 * happened.
56 */ 68 */
57 69
58#include <linux/err.h> 70#include <linux/err.h>
@@ -741,24 +753,24 @@ struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi,
741} 753}
742 754
743/** 755/**
744 * check_data_ff - make sure PEB contains only 0xFF data. 756 * check_corruption - check the data area of PEB.
745 * @ubi: UBI device description object 757 * @ubi: UBI device description object
746 * @vid_hrd: the (corrupted) VID header of this PEB 758 * @vid_hrd: the (corrupted) VID header of this PEB
747 * @pnum: the physical eraseblock number to check 759 * @pnum: the physical eraseblock number to check
748 * 760 *
749 * This is a helper function which is used to distinguish between VID header 761 * This is a helper function which is used to distinguish between VID header
750 * corruptions caused by power cuts and other reasons. If the PEB contains only 762 * corruptions caused by power cuts and other reasons. If the PEB contains only
751 * 0xFF bytes at the data area, the VID header is most probably corrupted 763 * 0xFF bytes in the data area, the VID header is most probably corrupted
752 * because of a power cut (%0 is returned in this case). Otherwise, it was 764 * because of a power cut (%0 is returned in this case). Otherwise, it was
753 * corrupted for some other reasons (%1 is returned in this case). A negative 765 * probably corrupted for some other reasons (%1 is returned in this case). A
754 * error code is returned if a read error occurred. 766 * negative error code is returned if a read error occurred.
755 * 767 *
756 * If the corruption reason was a power cut, UBI can safely erase this PEB. 768 * If the corruption reason was a power cut, UBI can safely erase this PEB.
757 * Otherwise, it should preserve it to avoid possibly destroying important 769 * Otherwise, it should preserve it to avoid possibly destroying important
758 * information. 770 * information.
759 */ 771 */
760static int check_data_ff(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, 772static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
761 int pnum) 773 int pnum)
762{ 774{
763 int err; 775 int err;
764 776
@@ -767,7 +779,18 @@ static int check_data_ff(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
767 779
768 err = ubi_io_read(ubi, ubi->peb_buf1, pnum, ubi->leb_start, 780 err = ubi_io_read(ubi, ubi->peb_buf1, pnum, ubi->leb_start,
769 ubi->leb_size); 781 ubi->leb_size);
770 if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG) 782 if (err == UBI_IO_BITFLIPS || err == -EBADMSG) {
783 /*
784 * Bit-flips or integrity errors while reading the data area.
785 * It is difficult to say for sure what type of corruption is
786 * this, but presumably a power cut happened while this PEB was
787 * erased, so it became unstable and corrupted, and should be
788 * erased.
789 */
790 return 0;
791 }
792
793 if (err)
771 return err; 794 return err;
772 795
773 if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) { 796 if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) {
@@ -926,7 +949,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
926 * that this a valid UBI PEB which has corresponding 949 * that this a valid UBI PEB which has corresponding
927 * LEB, but the headers are corrupted. However, it is 950 * LEB, but the headers are corrupted. However, it is
928 * impossible to distinguish it from a PEB which just 951 * impossible to distinguish it from a PEB which just
929 * contains garbage because a power cut during erase 952 * contains garbage because of a power cut during erase
930 * operation. So we just schedule this PEB for erasure. 953 * operation. So we just schedule this PEB for erasure.
931 */ 954 */
932 err = 0; 955 err = 0;
@@ -935,7 +958,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
935 * The EC was OK, but the VID header is corrupted. We 958 * The EC was OK, but the VID header is corrupted. We
936 * have to check what is in the data area. 959 * have to check what is in the data area.
937 */ 960 */
938 err = check_data_ff(ubi, vidh, pnum); 961 err = check_corruption(ubi, vidh, pnum);
939 962
940 if (err < 0) 963 if (err < 0)
941 return err; 964 return err;