diff options
Diffstat (limited to 'drivers/mtd/ubi')
| -rw-r--r-- | drivers/mtd/ubi/scan.c | 1605 | ||||
| -rw-r--r-- | drivers/mtd/ubi/scan.h | 174 |
2 files changed, 1779 insertions, 0 deletions
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c new file mode 100644 index 00000000000..a3a198f9b98 --- /dev/null +++ b/drivers/mtd/ubi/scan.c | |||
| @@ -0,0 +1,1605 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) International Business Machines Corp., 2006 | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
| 12 | * the GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | * | ||
| 18 | * Author: Artem Bityutskiy (Битюцкий Артём) | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * UBI scanning sub-system. | ||
| 23 | * | ||
| 24 | * This sub-system is responsible for scanning the flash media, checking UBI | ||
| 25 | * headers and providing complete information about the UBI flash image. | ||
| 26 | * | ||
| 27 | * The scanning information is represented by a &struct ubi_scan_info' object. | ||
| 28 | * Information about found volumes is represented by &struct ubi_scan_volume | ||
| 29 | * objects which are kept in volume RB-tree with root at the @volumes field. | ||
| 30 | * The RB-tree is indexed by the volume ID. | ||
| 31 | * | ||
| 32 | * Scanned logical eraseblocks are represented by &struct ubi_scan_leb objects. | ||
| 33 | * These objects are kept in per-volume RB-trees with the root at the | ||
| 34 | * corresponding &struct ubi_scan_volume object. To put it differently, we keep | ||
| 35 | * an RB-tree of per-volume objects and each of these objects is the root of | ||
| 36 | * RB-tree of per-eraseblock objects. | ||
| 37 | * | ||
| 38 | * Corrupted physical eraseblocks are put to the @corr list, free physical | ||
| 39 | * eraseblocks are put to the @free list and the physical eraseblock to be | ||
| 40 | * erased are put to the @erase list. | ||
| 41 | * | ||
| 42 | * About corruptions | ||
| 43 | * ~~~~~~~~~~~~~~~~~ | ||
| 44 | * | ||
| 45 | * UBI protects EC and VID headers with CRC-32 checksums, so it can detect | ||
| 46 | * whether the headers are corrupted or not. Sometimes UBI also protects the | ||
| 47 | * data with CRC-32, e.g., when it executes the atomic LEB change operation, or | ||
| 48 | * when it moves the contents of a PEB for wear-leveling purposes. | ||
| 49 | * | ||
| 50 | * UBI tries to distinguish between 2 types of corruptions. | ||
| 51 | * | ||
| 52 | * 1. Corruptions caused by power cuts. These are expected corruptions and UBI | ||
| 53 | * tries to handle them gracefully, without printing too many warnings and | ||
| 54 | * error messages. The idea is that we do not lose important data in these case | ||
| 55 | * - we may lose only the data which was being written to the media just before | ||
| 56 | * the power cut happened, and the upper layers (e.g., UBIFS) are supposed to | ||
| 57 | * handle such data losses (e.g., by using the FS journal). | ||
| 58 | * | ||
| 59 | * When UBI detects a corruption (CRC-32 mismatch) in a PEB, and it looks like | ||
| 60 | * the reason is a power cut, UBI puts this PEB to the @erase list, and all | ||
| 61 | * PEBs in the @erase list are scheduled for erasure later. | ||
| 62 | * | ||
| 63 | * 2. Unexpected corruptions which are not caused by power cuts. During | ||
| 64 | * scanning, such PEBs are put to the @corr list and UBI preserves them. | ||
| 65 | * Obviously, this lessens the amount of available PEBs, and if at some point | ||
| 66 | * UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly informs | ||
| 67 | * about such PEBs every time the MTD device is attached. | ||
| 68 | * | ||
| 69 | * However, it is difficult to reliably distinguish between these types of | ||
| 70 | * corruptions and UBI's strategy is as follows. UBI assumes corruption type 2 | ||
| 71 | * if the VID header is corrupted and the data area does not contain all 0xFFs, | ||
| 72 | * and there were no bit-flips or integrity errors while reading the data area. | ||
| 73 | * Otherwise UBI assumes corruption type 1. So the decision criteria are as | ||
| 74 | * follows. | ||
| 75 | * o If the data area contains only 0xFFs, there is no data, and it is safe | ||
| 76 | * to just erase this PEB - this is corruption type 1. | ||
| 77 | * o If the data area has bit-flips or data integrity errors (ECC errors on | ||
| 78 | * NAND), it is probably a PEB which was being erased when power cut | ||
| 79 | * happened, so this is corruption type 1. However, this is just a guess, | ||
| 80 | * which might be wrong. | ||
| 81 | * o Otherwise this it corruption type 2. | ||
| 82 | */ | ||
| 83 | |||
| 84 | #include <linux/err.h> | ||
| 85 | #include <linux/slab.h> | ||
| 86 | #include <linux/crc32.h> | ||
| 87 | #include <linux/math64.h> | ||
| 88 | #include <linux/random.h> | ||
| 89 | #include "ubi.h" | ||
| 90 | |||
| 91 | #ifdef CONFIG_MTD_UBI_DEBUG | ||
| 92 | static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); | ||
| 93 | #else | ||
| 94 | #define paranoid_check_si(ubi, si) 0 | ||
| 95 | #endif | ||
| 96 | |||
| 97 | /* Temporary variables used during scanning */ | ||
| 98 | static struct ubi_ec_hdr *ech; | ||
| 99 | static struct ubi_vid_hdr *vidh; | ||
| 100 | |||
| 101 | /** | ||
| 102 | * add_to_list - add physical eraseblock to a list. | ||
| 103 | * @si: scanning information | ||
| 104 | * @pnum: physical eraseblock number to add | ||
| 105 | * @ec: erase counter of the physical eraseblock | ||
| 106 | * @to_head: if not zero, add to the head of the list | ||
| 107 | * @list: the list to add to | ||
| 108 | * | ||
| 109 | * This function adds physical eraseblock @pnum to free, erase, or alien lists. | ||
| 110 | * If @to_head is not zero, PEB will be added to the head of the list, which | ||
| 111 | * basically means it will be processed first later. E.g., we add corrupted | ||
| 112 | * PEBs (corrupted due to power cuts) to the head of the erase list to make | ||
| 113 | * sure we erase them first and get rid of corruptions ASAP. This function | ||
| 114 | * returns zero in case of success and a negative error code in case of | ||
| 115 | * failure. | ||
| 116 | */ | ||
| 117 | static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head, | ||
| 118 | struct list_head *list) | ||
| 119 | { | ||
| 120 | struct ubi_scan_leb *seb; | ||
| 121 | |||
| 122 | if (list == &si->free) { | ||
| 123 | dbg_bld("add to free: PEB %d, EC %d", pnum, ec); | ||
| 124 | } else if (list == &si->erase) { | ||
| 125 | dbg_bld("add to erase: PEB %d, EC %d", pnum, ec); | ||
| 126 | } else if (list == &si->alien) { | ||
| 127 | dbg_bld("add to alien: PEB %d, EC %d", pnum, ec); | ||
| 128 | si->alien_peb_count += 1; | ||
| 129 | } else | ||
| 130 | BUG(); | ||
| 131 | |||
| 132 | seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); | ||
| 133 | if (!seb) | ||
| 134 | return -ENOMEM; | ||
| 135 | |||
| 136 | seb->pnum = pnum; | ||
| 137 | seb->ec = ec; | ||
| 138 | if (to_head) | ||
| 139 | list_add(&seb->u.list, list); | ||
| 140 | else | ||
| 141 | list_add_tail(&seb->u.list, list); | ||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | /** | ||
| 146 | * add_corrupted - add a corrupted physical eraseblock. | ||
| 147 | * @si: scanning information | ||
| 148 | * @pnum: physical eraseblock number to add | ||
| 149 | * @ec: erase counter of the physical eraseblock | ||
| 150 | * | ||
| 151 | * This function adds corrupted physical eraseblock @pnum to the 'corr' list. | ||
| 152 | * The corruption was presumably not caused by a power cut. Returns zero in | ||
| 153 | * case of success and a negative error code in case of failure. | ||
| 154 | */ | ||
| 155 | static int add_corrupted(struct ubi_scan_info *si, int pnum, int ec) | ||
| 156 | { | ||
| 157 | struct ubi_scan_leb *seb; | ||
| 158 | |||
| 159 | dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); | ||
| 160 | |||
| 161 | seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); | ||
| 162 | if (!seb) | ||
| 163 | return -ENOMEM; | ||
| 164 | |||
| 165 | si->corr_peb_count += 1; | ||
| 166 | seb->pnum = pnum; | ||
| 167 | seb->ec = ec; | ||
| 168 | list_add(&seb->u.list, &si->corr); | ||
| 169 | return 0; | ||
| 170 | } | ||
| 171 | |||
| 172 | /** | ||
| 173 | * validate_vid_hdr - check volume identifier header. | ||
| 174 | * @vid_hdr: the volume identifier header to check | ||
| 175 | * @sv: information about the volume this logical eraseblock belongs to | ||
| 176 | * @pnum: physical eraseblock number the VID header came from | ||
| 177 | * | ||
| 178 | * This function checks that data stored in @vid_hdr is consistent. Returns | ||
| 179 | * non-zero if an inconsistency was found and zero if not. | ||
| 180 | * | ||
| 181 | * Note, UBI does sanity check of everything it reads from the flash media. | ||
| 182 | * Most of the checks are done in the I/O sub-system. Here we check that the | ||
| 183 | * information in the VID header is consistent to the information in other VID | ||
| 184 | * headers of the same volume. | ||
| 185 | */ | ||
| 186 | static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, | ||
| 187 | const struct ubi_scan_volume *sv, int pnum) | ||
| 188 | { | ||
| 189 | int vol_type = vid_hdr->vol_type; | ||
| 190 | int vol_id = be32_to_cpu(vid_hdr->vol_id); | ||
| 191 | int used_ebs = be32_to_cpu(vid_hdr->used_ebs); | ||
| 192 | int data_pad = be32_to_cpu(vid_hdr->data_pad); | ||
| 193 | |||
| 194 | if (sv->leb_count != 0) { | ||
| 195 | int sv_vol_type; | ||
| 196 | |||
| 197 | /* | ||
| 198 | * This is not the first logical eraseblock belonging to this | ||
| 199 | * volume. Ensure that the data in its VID header is consistent | ||
| 200 | * to the data in previous logical eraseblock headers. | ||
| 201 | */ | ||
| 202 | |||
| 203 | if (vol_id != sv->vol_id) { | ||
| 204 | dbg_err("inconsistent vol_id"); | ||
| 205 | goto bad; | ||
| 206 | } | ||
| 207 | |||
| 208 | if (sv->vol_type == UBI_STATIC_VOLUME) | ||
| 209 | sv_vol_type = UBI_VID_STATIC; | ||
| 210 | else | ||
| 211 | sv_vol_type = UBI_VID_DYNAMIC; | ||
| 212 | |||
| 213 | if (vol_type != sv_vol_type) { | ||
| 214 | dbg_err("inconsistent vol_type"); | ||
| 215 | goto bad; | ||
| 216 | } | ||
| 217 | |||
