162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) International Business Machines Corp., 2006 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: Artem Bityutskiy (Битюцкий Артём) 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci/* 962306a36Sopenharmony_ci * UBI attaching sub-system. 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * This sub-system is responsible for attaching MTD devices and it also 1262306a36Sopenharmony_ci * implements flash media scanning. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * The attaching information is represented by a &struct ubi_attach_info' 1562306a36Sopenharmony_ci * object. Information about volumes is represented by &struct ubi_ainf_volume 1662306a36Sopenharmony_ci * objects which are kept in volume RB-tree with root at the @volumes field. 1762306a36Sopenharmony_ci * The RB-tree is indexed by the volume ID. 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * Logical eraseblocks are represented by &struct ubi_ainf_peb objects. These 2062306a36Sopenharmony_ci * objects are kept in per-volume RB-trees with the root at the corresponding 2162306a36Sopenharmony_ci * &struct ubi_ainf_volume object. To put it differently, we keep an RB-tree of 2262306a36Sopenharmony_ci * per-volume objects and each of these objects is the root of RB-tree of 2362306a36Sopenharmony_ci * per-LEB objects. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * Corrupted physical eraseblocks are put to the @corr list, free physical 2662306a36Sopenharmony_ci * eraseblocks are put to the @free list and the physical eraseblock to be 2762306a36Sopenharmony_ci * erased are put to the @erase list. 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * About corruptions 3062306a36Sopenharmony_ci * ~~~~~~~~~~~~~~~~~ 3162306a36Sopenharmony_ci * 3262306a36Sopenharmony_ci * UBI protects EC and VID headers with CRC-32 checksums, so it can detect 3362306a36Sopenharmony_ci * whether the headers are corrupted or not. Sometimes UBI also protects the 3462306a36Sopenharmony_ci * data with CRC-32, e.g., when it executes the atomic LEB change operation, or 3562306a36Sopenharmony_ci * when it moves the contents of a PEB for wear-leveling purposes. 3662306a36Sopenharmony_ci * 3762306a36Sopenharmony_ci * UBI tries to distinguish between 2 types of corruptions. 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * 1. Corruptions caused by power cuts. These are expected corruptions and UBI 4062306a36Sopenharmony_ci * tries to handle them gracefully, without printing too many warnings and 4162306a36Sopenharmony_ci * error messages. The idea is that we do not lose important data in these 4262306a36Sopenharmony_ci * cases - we may lose only the data which were being written to the media just 4362306a36Sopenharmony_ci * before the power cut happened, and the upper layers (e.g., UBIFS) are 4462306a36Sopenharmony_ci * supposed to handle such data losses (e.g., by using the FS journal). 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * When UBI detects a corruption (CRC-32 mismatch) in a PEB, and it looks like 4762306a36Sopenharmony_ci * the reason is a power cut, UBI puts this PEB to the @erase list, and all 4862306a36Sopenharmony_ci * PEBs in the @erase list are scheduled for erasure later. 4962306a36Sopenharmony_ci * 5062306a36Sopenharmony_ci * 2. Unexpected corruptions which are not caused by power cuts. During 5162306a36Sopenharmony_ci * attaching, such PEBs are put to the @corr list and UBI preserves them. 5262306a36Sopenharmony_ci * Obviously, this lessens the amount of available PEBs, and if at some point 5362306a36Sopenharmony_ci * UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly informs 5462306a36Sopenharmony_ci * about such PEBs every time the MTD device is attached. 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci * However, it is difficult to reliably distinguish between these types of 5762306a36Sopenharmony_ci * corruptions and UBI's strategy is as follows (in case of attaching by 5862306a36Sopenharmony_ci * scanning). UBI assumes corruption type 2 if the VID header is corrupted and 5962306a36Sopenharmony_ci * the data area does not contain all 0xFFs, and there were no bit-flips or 6062306a36Sopenharmony_ci * integrity errors (e.g., ECC errors in case of NAND) while reading the data 6162306a36Sopenharmony_ci * area. Otherwise UBI assumes corruption type 1. So the decision criteria 6262306a36Sopenharmony_ci * are as follows. 6362306a36Sopenharmony_ci * o If the data area contains only 0xFFs, there are no data, and it is safe 6462306a36Sopenharmony_ci * to just erase this PEB - this is corruption type 1. 6562306a36Sopenharmony_ci * o If the data area has bit-flips or data integrity errors (ECC errors on 6662306a36Sopenharmony_ci * NAND), it is probably a PEB which was being erased when power cut 6762306a36Sopenharmony_ci * happened, so this is corruption type 1. However, this is just a guess, 6862306a36Sopenharmony_ci * which might be wrong. 6962306a36Sopenharmony_ci * o Otherwise this is corruption type 2. 7062306a36Sopenharmony_ci */ 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#include <linux/err.h> 7362306a36Sopenharmony_ci#include <linux/slab.h> 7462306a36Sopenharmony_ci#include <linux/crc32.h> 7562306a36Sopenharmony_ci#include <linux/math64.h> 7662306a36Sopenharmony_ci#include <linux/random.h> 7762306a36Sopenharmony_ci#include "ubi.h" 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai); 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci#define AV_FIND BIT(0) 8262306a36Sopenharmony_ci#define AV_ADD BIT(1) 8362306a36Sopenharmony_ci#define AV_FIND_OR_ADD (AV_FIND | AV_ADD) 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/** 8662306a36Sopenharmony_ci * find_or_add_av - internal function to find a volume, add a volume or do 8762306a36Sopenharmony_ci * both (find and add if missing). 8862306a36Sopenharmony_ci * @ai: attaching information 8962306a36Sopenharmony_ci * @vol_id: the requested volume ID 9062306a36Sopenharmony_ci * @flags: a combination of the %AV_FIND and %AV_ADD flags describing the 9162306a36Sopenharmony_ci * expected operation. If only %AV_ADD is set, -EEXIST is returned 9262306a36Sopenharmony_ci * if the volume already exists. If only %AV_FIND is set, NULL is 9362306a36Sopenharmony_ci * returned if the volume does not exist. And if both flags are 9462306a36Sopenharmony_ci * set, the helper first tries to find an existing volume, and if 9562306a36Sopenharmony_ci * it does not exist it creates a new one. 9662306a36Sopenharmony_ci * @created: in value used to inform the caller whether it"s a newly created 9762306a36Sopenharmony_ci * volume or not. 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * This function returns a pointer to a volume description or an ERR_PTR if 10062306a36Sopenharmony_ci * the operation failed. It can also return NULL if only %AV_FIND is set and 10162306a36Sopenharmony_ci * the volume does not exist. 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_cistatic struct ubi_ainf_volume *find_or_add_av(struct ubi_attach_info *ai, 10462306a36Sopenharmony_ci int vol_id, unsigned int flags, 10562306a36Sopenharmony_ci bool *created) 10662306a36Sopenharmony_ci{ 10762306a36Sopenharmony_ci struct ubi_ainf_volume *av; 10862306a36Sopenharmony_ci struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /* Walk the volume RB-tree to look if this volume is already present */ 11162306a36Sopenharmony_ci while (*p) { 11262306a36Sopenharmony_ci parent = *p; 11362306a36Sopenharmony_ci av = rb_entry(parent, struct ubi_ainf_volume, rb); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci if (vol_id == av->vol_id) { 11662306a36Sopenharmony_ci *created = false; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci if (!(flags & AV_FIND)) 11962306a36Sopenharmony_ci return ERR_PTR(-EEXIST); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci return av; 12262306a36Sopenharmony_ci } 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci if (vol_id > av->vol_id) 12562306a36Sopenharmony_ci p = &(*p)->rb_left; 12662306a36Sopenharmony_ci else 12762306a36Sopenharmony_ci p = &(*p)->rb_right; 12862306a36Sopenharmony_ci } 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci if (!(flags & AV_ADD)) 13162306a36Sopenharmony_ci return NULL; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci /* The volume is absent - add it */ 13462306a36Sopenharmony_ci av = kzalloc(sizeof(*av), GFP_KERNEL); 13562306a36Sopenharmony_ci if (!av) 13662306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci av->vol_id = vol_id; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci if (vol_id > ai->highest_vol_id) 14162306a36Sopenharmony_ci ai->highest_vol_id = vol_id; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci rb_link_node(&av->rb, parent, p); 14462306a36Sopenharmony_ci rb_insert_color(&av->rb, &ai->volumes); 14562306a36Sopenharmony_ci ai->vols_found += 1; 14662306a36Sopenharmony_ci *created = true; 14762306a36Sopenharmony_ci dbg_bld("added volume %d", vol_id); 14862306a36Sopenharmony_ci return av; 14962306a36Sopenharmony_ci} 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci/** 15262306a36Sopenharmony_ci * ubi_find_or_add_av - search for a volume in the attaching information and 15362306a36Sopenharmony_ci * add one if it does not exist. 15462306a36Sopenharmony_ci * @ai: attaching information 15562306a36Sopenharmony_ci * @vol_id: the requested volume ID 15662306a36Sopenharmony_ci * @created: whether the volume has been created or not 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * This function returns a pointer to the new volume description or an 15962306a36Sopenharmony_ci * ERR_PTR if the operation failed. 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_cistatic struct ubi_ainf_volume *ubi_find_or_add_av(struct ubi_attach_info *ai, 16262306a36Sopenharmony_ci int vol_id, bool *created) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci return find_or_add_av(ai, vol_id, AV_FIND_OR_ADD, created); 16562306a36Sopenharmony_ci} 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci/** 16862306a36Sopenharmony_ci * ubi_alloc_aeb - allocate an aeb element 16962306a36Sopenharmony_ci * @ai: attaching information 17062306a36Sopenharmony_ci * @pnum: physical eraseblock number 17162306a36Sopenharmony_ci * @ec: erase counter of the physical eraseblock 17262306a36Sopenharmony_ci * 17362306a36Sopenharmony_ci * Allocate an aeb object and initialize the pnum and ec information. 17462306a36Sopenharmony_ci * vol_id and lnum are set to UBI_UNKNOWN, and the other fields are 17562306a36Sopenharmony_ci * initialized to zero. 17662306a36Sopenharmony_ci * Note that the element is not added in any list or RB tree. 17762306a36Sopenharmony_ci */ 17862306a36Sopenharmony_cistruct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum, 17962306a36Sopenharmony_ci int ec) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci struct ubi_ainf_peb *aeb; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci aeb = kmem_cache_zalloc(ai->aeb_slab_cache, GFP_KERNEL); 18462306a36Sopenharmony_ci if (!aeb) 18562306a36Sopenharmony_ci return NULL; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci aeb->pnum = pnum; 18862306a36Sopenharmony_ci aeb->ec = ec; 18962306a36Sopenharmony_ci aeb->vol_id = UBI_UNKNOWN; 19062306a36Sopenharmony_ci aeb->lnum = UBI_UNKNOWN; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci return aeb; 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci/** 19662306a36Sopenharmony_ci * ubi_free_aeb - free an aeb element 19762306a36Sopenharmony_ci * @ai: attaching information 19862306a36Sopenharmony_ci * @aeb: the element to free 19962306a36Sopenharmony_ci * 20062306a36Sopenharmony_ci * Free an aeb object. The caller must have removed the element from any list 20162306a36Sopenharmony_ci * or RB tree. 20262306a36Sopenharmony_ci */ 20362306a36Sopenharmony_civoid ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb) 20462306a36Sopenharmony_ci{ 20562306a36Sopenharmony_ci kmem_cache_free(ai->aeb_slab_cache, aeb); 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci/** 20962306a36Sopenharmony_ci * add_to_list - add physical eraseblock to a list. 21062306a36Sopenharmony_ci * @ai: attaching information 21162306a36Sopenharmony_ci * @pnum: physical eraseblock number to add 21262306a36Sopenharmony_ci * @vol_id: the last used volume id for the PEB 21362306a36Sopenharmony_ci * @lnum: the last used LEB number for the PEB 21462306a36Sopenharmony_ci * @ec: erase counter of the physical eraseblock 21562306a36Sopenharmony_ci * @to_head: if not zero, add to the head of the list 21662306a36Sopenharmony_ci * @list: the list to add to 21762306a36Sopenharmony_ci * 21862306a36Sopenharmony_ci * This function allocates a 'struct ubi_ainf_peb' object for physical 21962306a36Sopenharmony_ci * eraseblock @pnum and adds it to the "free", "erase", or "alien" lists. 22062306a36Sopenharmony_ci * It stores the @lnum and @vol_id alongside, which can both be 22162306a36Sopenharmony_ci * %UBI_UNKNOWN if they are not available, not readable, or not assigned. 22262306a36Sopenharmony_ci * If @to_head is not zero, PEB will be added to the head of the list, which 22362306a36Sopenharmony_ci * basically means it will be processed first later. E.g., we add corrupted 22462306a36Sopenharmony_ci * PEBs (corrupted due to power cuts) to the head of the erase list to make 22562306a36Sopenharmony_ci * sure we erase them first and get rid of corruptions ASAP. This function 22662306a36Sopenharmony_ci * returns zero in case of success and a negative error code in case of 22762306a36Sopenharmony_ci * failure. 22862306a36Sopenharmony_ci */ 22962306a36Sopenharmony_cistatic int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id, 23062306a36Sopenharmony_ci int lnum, int ec, int to_head, struct list_head *list) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci struct ubi_ainf_peb *aeb; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci if (list == &ai->free) { 23562306a36Sopenharmony_ci dbg_bld("add to free: PEB %d, EC %d", pnum, ec); 23662306a36Sopenharmony_ci } else if (list == &ai->erase) { 23762306a36Sopenharmony_ci dbg_bld("add to erase: PEB %d, EC %d", pnum, ec); 23862306a36Sopenharmony_ci } else if (list == &ai->alien) { 23962306a36Sopenharmony_ci dbg_bld("add to alien: PEB %d, EC %d", pnum, ec); 24062306a36Sopenharmony_ci ai->alien_peb_count += 1; 24162306a36Sopenharmony_ci } else 24262306a36Sopenharmony_ci BUG(); 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci aeb = ubi_alloc_aeb(ai, pnum, ec); 24562306a36Sopenharmony_ci if (!aeb) 24662306a36Sopenharmony_ci return -ENOMEM; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci aeb->vol_id = vol_id; 24962306a36Sopenharmony_ci aeb->lnum = lnum; 25062306a36Sopenharmony_ci if (to_head) 25162306a36Sopenharmony_ci list_add(&aeb->u.list, list); 25262306a36Sopenharmony_ci else 25362306a36Sopenharmony_ci list_add_tail(&aeb->u.list, list); 25462306a36Sopenharmony_ci return 0; 25562306a36Sopenharmony_ci} 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci/** 25862306a36Sopenharmony_ci * add_corrupted - add a corrupted physical eraseblock. 25962306a36Sopenharmony_ci * @ai: attaching information 26062306a36Sopenharmony_ci * @pnum: physical eraseblock number to add 26162306a36Sopenharmony_ci * @ec: erase counter of the physical eraseblock 26262306a36Sopenharmony_ci * 26362306a36Sopenharmony_ci * This function allocates a 'struct ubi_ainf_peb' object for a corrupted 26462306a36Sopenharmony_ci * physical eraseblock @pnum and adds it to the 'corr' list. The corruption 26562306a36Sopenharmony_ci * was presumably not caused by a power cut. Returns zero in case of success 26662306a36Sopenharmony_ci * and a negative error code in case of failure. 26762306a36Sopenharmony_ci */ 26862306a36Sopenharmony_cistatic int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci struct ubi_ainf_peb *aeb; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci aeb = ubi_alloc_aeb(ai, pnum, ec); 27562306a36Sopenharmony_ci if (!aeb) 27662306a36Sopenharmony_ci return -ENOMEM; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci ai->corr_peb_count += 1; 27962306a36Sopenharmony_ci list_add(&aeb->u.list, &ai->corr); 28062306a36Sopenharmony_ci return 0; 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci/** 28462306a36Sopenharmony_ci * add_fastmap - add a Fastmap related physical eraseblock. 28562306a36Sopenharmony_ci * @ai: attaching information 28662306a36Sopenharmony_ci * @pnum: physical eraseblock number the VID header came from 28762306a36Sopenharmony_ci * @vid_hdr: the volume identifier header 28862306a36Sopenharmony_ci * @ec: erase counter of the physical eraseblock 28962306a36Sopenharmony_ci * 29062306a36Sopenharmony_ci * This function allocates a 'struct ubi_ainf_peb' object for a Fastamp 29162306a36Sopenharmony_ci * physical eraseblock @pnum and adds it to the 'fastmap' list. 29262306a36Sopenharmony_ci * Such blocks can be Fastmap super and data blocks from both the most 29362306a36Sopenharmony_ci * recent Fastmap we're attaching from or from old Fastmaps which will 29462306a36Sopenharmony_ci * be erased. 29562306a36Sopenharmony_ci */ 29662306a36Sopenharmony_cistatic int add_fastmap(struct ubi_attach_info *ai, int pnum, 29762306a36Sopenharmony_ci struct ubi_vid_hdr *vid_hdr, int ec) 29862306a36Sopenharmony_ci{ 29962306a36Sopenharmony_ci struct ubi_ainf_peb *aeb; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci aeb = ubi_alloc_aeb(ai, pnum, ec); 30262306a36Sopenharmony_ci if (!aeb) 30362306a36Sopenharmony_ci return -ENOMEM; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci aeb->vol_id = be32_to_cpu(vid_hdr->vol_id); 30662306a36Sopenharmony_ci aeb->sqnum = be64_to_cpu(vid_hdr->sqnum); 30762306a36Sopenharmony_ci list_add(&aeb->u.list, &ai->fastmap); 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci dbg_bld("add to fastmap list: PEB %d, vol_id %d, sqnum: %llu", pnum, 31062306a36Sopenharmony_ci aeb->vol_id, aeb->sqnum); 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci return 0; 31362306a36Sopenharmony_ci} 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci/** 31662306a36Sopenharmony_ci * validate_vid_hdr - check volume identifier header. 31762306a36Sopenharmony_ci * @ubi: UBI device description object 31862306a36Sopenharmony_ci * @vid_hdr: the volume identifier header to check 31962306a36Sopenharmony_ci * @av: information about the volume this logical eraseblock belongs to 32062306a36Sopenharmony_ci * @pnum: physical eraseblock number the VID header came from 32162306a36Sopenharmony_ci * 32262306a36Sopenharmony_ci * This function checks that data stored in @vid_hdr is consistent. Returns 32362306a36Sopenharmony_ci * non-zero if an inconsistency was found and zero if not. 32462306a36Sopenharmony_ci * 32562306a36Sopenharmony_ci * Note, UBI does sanity check of everything it reads from the flash media. 32662306a36Sopenharmony_ci * Most of the checks are done in the I/O sub-system. Here we check that the 32762306a36Sopenharmony_ci * information in the VID header is consistent to the information in other VID 32862306a36Sopenharmony_ci * headers of the same volume. 32962306a36Sopenharmony_ci */ 33062306a36Sopenharmony_cistatic int validate_vid_hdr(const struct ubi_device *ubi, 33162306a36Sopenharmony_ci const struct ubi_vid_hdr *vid_hdr, 33262306a36Sopenharmony_ci const struct ubi_ainf_volume *av, int pnum) 33362306a36Sopenharmony_ci{ 33462306a36Sopenharmony_ci int vol_type = vid_hdr->vol_type; 33562306a36Sopenharmony_ci int vol_id = be32_to_cpu(vid_hdr->vol_id); 33662306a36Sopenharmony_ci int used_ebs = be32_to_cpu(vid_hdr->used_ebs); 33762306a36Sopenharmony_ci int data_pad = be32_to_cpu(vid_hdr->data_pad); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci if (av->leb_count != 0) { 34062306a36Sopenharmony_ci int av_vol_type; 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci /* 34362306a36Sopenharmony_ci * This is not the first logical eraseblock belonging to this 34462306a36Sopenharmony_ci * volume. Ensure that the data in its VID header is consistent 34562306a36Sopenharmony_ci * to the data in previous logical eraseblock headers. 34662306a36Sopenharmony_ci */ 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (vol_id != av->vol_id) { 34962306a36Sopenharmony_ci ubi_err(ubi, "inconsistent vol_id"); 35062306a36Sopenharmony_ci goto bad; 35162306a36Sopenharmony_ci } 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci if (av->vol_type == UBI_STATIC_VOLUME) 35462306a36Sopenharmony_ci av_vol_type = UBI_VID_STATIC; 35562306a36Sopenharmony_ci else 35662306a36Sopenharmony_ci av_vol_type = UBI_VID_DYNAMIC; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci if (vol_type != av_vol_type) { 35962306a36Sopenharmony_ci ubi_err(ubi, "inconsistent vol_type"); 36062306a36Sopenharmony_ci goto bad; 36162306a36Sopenharmony_ci } 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci if (used_ebs != av->used_ebs) { 36462306a36Sopenharmony_ci ubi_err(ubi, "inconsistent used_ebs"); 36562306a36Sopenharmony_ci goto bad; 36662306a36Sopenharmony_ci } 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci if (data_pad != av->data_pad) { 36962306a36Sopenharmony_ci ubi_err(ubi, "inconsistent data_pad"); 37062306a36Sopenharmony_ci goto bad; 37162306a36Sopenharmony_ci } 37262306a36Sopenharmony_ci } 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci return 0; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_cibad: 37762306a36Sopenharmony_ci ubi_err(ubi, "inconsistent VID header at PEB %d", pnum); 37862306a36Sopenharmony_ci ubi_dump_vid_hdr(vid_hdr); 37962306a36Sopenharmony_ci ubi_dump_av(av); 38062306a36Sopenharmony_ci return -EINVAL; 38162306a36Sopenharmony_ci} 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci/** 38462306a36Sopenharmony_ci * add_volume - add volume to the attaching information. 38562306a36Sopenharmony_ci * @ai: attaching information 38662306a36Sopenharmony_ci * @vol_id: ID of the volume to add 38762306a36Sopenharmony_ci * @pnum: physical eraseblock number 38862306a36Sopenharmony_ci * @vid_hdr: volume identifier header 38962306a36Sopenharmony_ci * 39062306a36Sopenharmony_ci * If the volume corresponding to the @vid_hdr logical eraseblock is already 39162306a36Sopenharmony_ci * present in the attaching information, this function does nothing. Otherwise 39262306a36Sopenharmony_ci * it adds corresponding volume to the attaching information. Returns a pointer 39362306a36Sopenharmony_ci * to the allocated "av" object in case of success and a negative error code in 39462306a36Sopenharmony_ci * case of failure. 39562306a36Sopenharmony_ci */ 39662306a36Sopenharmony_cistatic struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, 39762306a36Sopenharmony_ci int vol_id, int pnum, 39862306a36Sopenharmony_ci const struct ubi_vid_hdr *vid_hdr) 39962306a36Sopenharmony_ci{ 40062306a36Sopenharmony_ci struct ubi_ainf_volume *av; 40162306a36Sopenharmony_ci bool created; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id)); 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci av = ubi_find_or_add_av(ai, vol_id, &created); 40662306a36Sopenharmony_ci if (IS_ERR(av) || !created) 40762306a36Sopenharmony_ci return av; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci av->used_ebs = be32_to_cpu(vid_hdr->used_ebs); 41062306a36Sopenharmony_ci av->data_pad = be32_to_cpu(vid_hdr->data_pad); 41162306a36Sopenharmony_ci av->compat = vid_hdr->compat; 41262306a36Sopenharmony_ci av->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME 41362306a36Sopenharmony_ci : UBI_STATIC_VOLUME; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci return av; 41662306a36Sopenharmony_ci} 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci/** 41962306a36Sopenharmony_ci * ubi_compare_lebs - find out which logical eraseblock is newer. 42062306a36Sopenharmony_ci * @ubi: UBI device description object 42162306a36Sopenharmony_ci * @aeb: first logical eraseblock to compare 42262306a36Sopenharmony_ci * @pnum: physical eraseblock number of the second logical eraseblock to 42362306a36Sopenharmony_ci * compare 42462306a36Sopenharmony_ci * @vid_hdr: volume identifier header of the second logical eraseblock 42562306a36Sopenharmony_ci * 42662306a36Sopenharmony_ci * This function compares 2 copies of a LEB and informs which one is newer. In 42762306a36Sopenharmony_ci * case of success this function returns a positive value, in case of failure, a 42862306a36Sopenharmony_ci * negative error code is returned. The success return codes use the following 42962306a36Sopenharmony_ci * bits: 43062306a36Sopenharmony_ci * o bit 0 is cleared: the first PEB (described by @aeb) is newer than the 43162306a36Sopenharmony_ci * second PEB (described by @pnum and @vid_hdr); 43262306a36Sopenharmony_ci * o bit 0 is set: the second PEB is newer; 43362306a36Sopenharmony_ci * o bit 1 is cleared: no bit-flips were detected in the newer LEB; 43462306a36Sopenharmony_ci * o bit 1 is set: bit-flips were detected in the newer LEB; 43562306a36Sopenharmony_ci * o bit 2 is cleared: the older LEB is not corrupted; 43662306a36Sopenharmony_ci * o bit 2 is set: the older LEB is corrupted. 43762306a36Sopenharmony_ci */ 43862306a36Sopenharmony_ciint ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, 43962306a36Sopenharmony_ci int pnum, const struct ubi_vid_hdr *vid_hdr) 44062306a36Sopenharmony_ci{ 44162306a36Sopenharmony_ci int len, err, second_is_newer, bitflips = 0, corrupted = 0; 44262306a36Sopenharmony_ci uint32_t data_crc, crc; 44362306a36Sopenharmony_ci struct ubi_vid_io_buf *vidb = NULL; 44462306a36Sopenharmony_ci unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci if (sqnum2 == aeb->sqnum) { 44762306a36Sopenharmony_ci /* 44862306a36Sopenharmony_ci * This must be a really ancient UBI image which has been 44962306a36Sopenharmony_ci * created before sequence numbers support has been added. At 45062306a36Sopenharmony_ci * that times we used 32-bit LEB versions stored in logical 45162306a36Sopenharmony_ci * eraseblocks. That was before UBI got into mainline. We do not 45262306a36Sopenharmony_ci * support these images anymore. Well, those images still work, 45362306a36Sopenharmony_ci * but only if no unclean reboots happened. 45462306a36Sopenharmony_ci */ 45562306a36Sopenharmony_ci ubi_err(ubi, "unsupported on-flash UBI format"); 45662306a36Sopenharmony_ci return -EINVAL; 45762306a36Sopenharmony_ci } 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci /* Obviously the LEB with lower sequence counter is older */ 46062306a36Sopenharmony_ci second_is_newer = (sqnum2 > aeb->sqnum); 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci /* 46362306a36Sopenharmony_ci * Now we know which copy is newer. If the copy flag of the PEB with 46462306a36Sopenharmony_ci * newer version is not set, then we just return, otherwise we have to 46562306a36Sopenharmony_ci * check data CRC. For the second PEB we already have the VID header, 46662306a36Sopenharmony_ci * for the first one - we'll need to re-read it from flash. 46762306a36Sopenharmony_ci * 46862306a36Sopenharmony_ci * Note: this may be optimized so that we wouldn't read twice. 46962306a36Sopenharmony_ci */ 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci if (second_is_newer) { 47262306a36Sopenharmony_ci if (!vid_hdr->copy_flag) { 47362306a36Sopenharmony_ci /* It is not a copy, so it is newer */ 47462306a36Sopenharmony_ci dbg_bld("second PEB %d is newer, copy_flag is unset", 47562306a36Sopenharmony_ci pnum); 47662306a36Sopenharmony_ci return 1; 47762306a36Sopenharmony_ci } 47862306a36Sopenharmony_ci } else { 47962306a36Sopenharmony_ci if (!aeb->copy_flag) { 48062306a36Sopenharmony_ci /* It is not a copy, so it is newer */ 48162306a36Sopenharmony_ci dbg_bld("first PEB %d is newer, copy_flag is unset", 48262306a36Sopenharmony_ci pnum); 48362306a36Sopenharmony_ci return bitflips << 1; 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci vidb = ubi_alloc_vid_buf(ubi, GFP_KERNEL); 48762306a36Sopenharmony_ci if (!vidb) 48862306a36Sopenharmony_ci return -ENOMEM; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci pnum = aeb->pnum; 49162306a36Sopenharmony_ci err = ubi_io_read_vid_hdr(ubi, pnum, vidb, 0); 49262306a36Sopenharmony_ci if (err) { 49362306a36Sopenharmony_ci if (err == UBI_IO_BITFLIPS) 49462306a36Sopenharmony_ci bitflips = 1; 49562306a36Sopenharmony_ci else { 49662306a36Sopenharmony_ci ubi_err(ubi, "VID of PEB %d header is bad, but it was OK earlier, err %d", 49762306a36Sopenharmony_ci pnum, err); 49862306a36Sopenharmony_ci if (err > 0) 49962306a36Sopenharmony_ci err = -EIO; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci goto out_free_vidh; 50262306a36Sopenharmony_ci } 50362306a36Sopenharmony_ci } 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci vid_hdr = ubi_get_vid_hdr(vidb); 50662306a36Sopenharmony_ci } 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci /* Read the data of the copy and check the CRC */ 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci len = be32_to_cpu(vid_hdr->data_size); 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci mutex_lock(&ubi->buf_mutex); 51362306a36Sopenharmony_ci err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, len); 51462306a36Sopenharmony_ci if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err)) 51562306a36Sopenharmony_ci goto out_unlock; 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci data_crc = be32_to_cpu(vid_hdr->data_crc); 51862306a36Sopenharmony_ci crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, len); 51962306a36Sopenharmony_ci if (crc != data_crc) { 52062306a36Sopenharmony_ci dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", 52162306a36Sopenharmony_ci pnum, crc, data_crc); 52262306a36Sopenharmony_ci corrupted = 1; 52362306a36Sopenharmony_ci bitflips = 0; 52462306a36Sopenharmony_ci second_is_newer = !second_is_newer; 52562306a36Sopenharmony_ci } else { 52662306a36Sopenharmony_ci dbg_bld("PEB %d CRC is OK", pnum); 52762306a36Sopenharmony_ci bitflips |= !!err; 52862306a36Sopenharmony_ci } 52962306a36Sopenharmony_ci mutex_unlock(&ubi->buf_mutex); 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci ubi_free_vid_buf(vidb); 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci if (second_is_newer) 53462306a36Sopenharmony_ci dbg_bld("second PEB %d is newer, copy_flag is set", pnum); 53562306a36Sopenharmony_ci else 53662306a36Sopenharmony_ci dbg_bld("first PEB %d is newer, copy_flag is set", pnum); 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci return second_is_newer | (bitflips << 1) | (corrupted << 2); 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ciout_unlock: 54162306a36Sopenharmony_ci mutex_unlock(&ubi->buf_mutex); 54262306a36Sopenharmony_ciout_free_vidh: 54362306a36Sopenharmony_ci ubi_free_vid_buf(vidb); 54462306a36Sopenharmony_ci return err; 54562306a36Sopenharmony_ci} 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci/** 54862306a36Sopenharmony_ci * ubi_add_to_av - add used physical eraseblock to the attaching information. 54962306a36Sopenharmony_ci * @ubi: UBI device description object 55062306a36Sopenharmony_ci * @ai: attaching information 55162306a36Sopenharmony_ci * @pnum: the physical eraseblock number 55262306a36Sopenharmony_ci * @ec: erase counter 55362306a36Sopenharmony_ci * @vid_hdr: the volume identifier header 55462306a36Sopenharmony_ci * @bitflips: if bit-flips were detected when this physical eraseblock was read 55562306a36Sopenharmony_ci * 55662306a36Sopenharmony_ci * This function adds information about a used physical eraseblock to the 55762306a36Sopenharmony_ci * 'used' tree of the corresponding volume. The function is rather complex 55862306a36Sopenharmony_ci * because it has to handle cases when this is not the first physical 55962306a36Sopenharmony_ci * eraseblock belonging to the same logical eraseblock, and the newer one has 56062306a36Sopenharmony_ci * to be picked, while the older one has to be dropped. This function returns 56162306a36Sopenharmony_ci * zero in case of success and a negative error code in case of failure. 56262306a36Sopenharmony_ci */ 56362306a36Sopenharmony_ciint ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, 56462306a36Sopenharmony_ci int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips) 56562306a36Sopenharmony_ci{ 56662306a36Sopenharmony_ci int err, vol_id, lnum; 56762306a36Sopenharmony_ci unsigned long long sqnum; 56862306a36Sopenharmony_ci struct ubi_ainf_volume *av; 56962306a36Sopenharmony_ci struct ubi_ainf_peb *aeb; 57062306a36Sopenharmony_ci struct rb_node **p, *parent = NULL; 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci vol_id = be32_to_cpu(vid_hdr->vol_id); 57362306a36Sopenharmony_ci lnum = be32_to_cpu(vid_hdr->lnum); 57462306a36Sopenharmony_ci sqnum = be64_to_cpu(vid_hdr->sqnum); 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, bitflips %d", 57762306a36Sopenharmony_ci pnum, vol_id, lnum, ec, sqnum, bitflips); 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci av = add_volume(ai, vol_id, pnum, vid_hdr); 58062306a36Sopenharmony_ci if (IS_ERR(av)) 58162306a36Sopenharmony_ci return PTR_ERR(av); 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci if (ai->max_sqnum < sqnum) 58462306a36Sopenharmony_ci ai->max_sqnum = sqnum; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci /* 58762306a36Sopenharmony_ci * Walk the RB-tree of logical eraseblocks of volume @vol_id to look 58862306a36Sopenharmony_ci * if this is the first instance of this logical eraseblock or not. 58962306a36Sopenharmony_ci */ 59062306a36Sopenharmony_ci p = &av->root.rb_node; 59162306a36Sopenharmony_ci while (*p) { 59262306a36Sopenharmony_ci int cmp_res; 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci parent = *p; 59562306a36Sopenharmony_ci aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb); 59662306a36Sopenharmony_ci if (lnum != aeb->lnum) { 59762306a36Sopenharmony_ci if (lnum < aeb->lnum) 59862306a36Sopenharmony_ci p = &(*p)->rb_left; 59962306a36Sopenharmony_ci else 60062306a36Sopenharmony_ci p = &(*p)->rb_right; 60162306a36Sopenharmony_ci continue; 60262306a36Sopenharmony_ci } 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci /* 60562306a36Sopenharmony_ci * There is already a physical eraseblock describing the same 60662306a36Sopenharmony_ci * logical eraseblock present. 60762306a36Sopenharmony_ci */ 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci dbg_bld("this LEB already exists: PEB %d, sqnum %llu, EC %d", 61062306a36Sopenharmony_ci aeb->pnum, aeb->sqnum, aeb->ec); 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci /* 61362306a36Sopenharmony_ci * Make sure that the logical eraseblocks have different 61462306a36Sopenharmony_ci * sequence numbers. Otherwise the image is bad. 61562306a36Sopenharmony_ci * 61662306a36Sopenharmony_ci * However, if the sequence number is zero, we assume it must 61762306a36Sopenharmony_ci * be an ancient UBI image from the era when UBI did not have 61862306a36Sopenharmony_ci * sequence numbers. We still can attach these images, unless 61962306a36Sopenharmony_ci * there is a need to distinguish between old and new 62062306a36Sopenharmony_ci * eraseblocks, in which case we'll refuse the image in 62162306a36Sopenharmony_ci * 'ubi_compare_lebs()'. In other words, we attach old clean 62262306a36Sopenharmony_ci * images, but refuse attaching old images with duplicated 62362306a36Sopenharmony_ci * logical eraseblocks because there was an unclean reboot. 62462306a36Sopenharmony_ci */ 62562306a36Sopenharmony_ci if (aeb->sqnum == sqnum && sqnum != 0) { 62662306a36Sopenharmony_ci ubi_err(ubi, "two LEBs with same sequence number %llu", 62762306a36Sopenharmony_ci sqnum); 62862306a36Sopenharmony_ci ubi_dump_aeb(aeb, 0); 62962306a36Sopenharmony_ci ubi_dump_vid_hdr(vid_hdr); 63062306a36Sopenharmony_ci return -EINVAL; 63162306a36Sopenharmony_ci } 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci /* 63462306a36Sopenharmony_ci * Now we have to drop the older one and preserve the newer 63562306a36Sopenharmony_ci * one. 63662306a36Sopenharmony_ci */ 63762306a36Sopenharmony_ci cmp_res = ubi_compare_lebs(ubi, aeb, pnum, vid_hdr); 63862306a36Sopenharmony_ci if (cmp_res < 0) 63962306a36Sopenharmony_ci return cmp_res; 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci if (cmp_res & 1) { 64262306a36Sopenharmony_ci /* 64362306a36Sopenharmony_ci * This logical eraseblock is newer than the one 64462306a36Sopenharmony_ci * found earlier. 64562306a36Sopenharmony_ci */ 64662306a36Sopenharmony_ci err = validate_vid_hdr(ubi, vid_hdr, av, pnum); 64762306a36Sopenharmony_ci if (err) 64862306a36Sopenharmony_ci return err; 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci err = add_to_list(ai, aeb->pnum, aeb->vol_id, 65162306a36Sopenharmony_ci aeb->lnum, aeb->ec, cmp_res & 4, 65262306a36Sopenharmony_ci &ai->erase); 65362306a36Sopenharmony_ci if (err) 65462306a36Sopenharmony_ci return err; 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci aeb->ec = ec; 65762306a36Sopenharmony_ci aeb->pnum = pnum; 65862306a36Sopenharmony_ci aeb->vol_id = vol_id; 65962306a36Sopenharmony_ci aeb->lnum = lnum; 66062306a36Sopenharmony_ci aeb->scrub = ((cmp_res & 2) || bitflips); 66162306a36Sopenharmony_ci aeb->copy_flag = vid_hdr->copy_flag; 66262306a36Sopenharmony_ci aeb->sqnum = sqnum; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci if (av->highest_lnum == lnum) 66562306a36Sopenharmony_ci av->last_data_size = 66662306a36Sopenharmony_ci be32_to_cpu(vid_hdr->data_size); 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci return 0; 66962306a36Sopenharmony_ci } else { 67062306a36Sopenharmony_ci /* 67162306a36Sopenharmony_ci * This logical eraseblock is older than the one found 67262306a36Sopenharmony_ci * previously. 67362306a36Sopenharmony_ci */ 67462306a36Sopenharmony_ci return add_to_list(ai, pnum, vol_id, lnum, ec, 67562306a36Sopenharmony_ci cmp_res & 4, &ai->erase); 67662306a36Sopenharmony_ci } 67762306a36Sopenharmony_ci } 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci /* 68062306a36Sopenharmony_ci * We've met this logical eraseblock for the first time, add it to the 68162306a36Sopenharmony_ci * attaching information. 68262306a36Sopenharmony_ci */ 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci err = validate_vid_hdr(ubi, vid_hdr, av, pnum); 68562306a36Sopenharmony_ci if (err) 68662306a36Sopenharmony_ci return err; 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_ci aeb = ubi_alloc_aeb(ai, pnum, ec); 68962306a36Sopenharmony_ci if (!aeb) 69062306a36Sopenharmony_ci return -ENOMEM; 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ci aeb->vol_id = vol_id; 69362306a36Sopenharmony_ci aeb->lnum = lnum; 69462306a36Sopenharmony_ci aeb->scrub = bitflips; 69562306a36Sopenharmony_ci aeb->copy_flag = vid_hdr->copy_flag; 69662306a36Sopenharmony_ci aeb->sqnum = sqnum; 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci if (av->highest_lnum <= lnum) { 69962306a36Sopenharmony_ci av->highest_lnum = lnum; 70062306a36Sopenharmony_ci av->last_data_size = be32_to_cpu(vid_hdr->data_size); 70162306a36Sopenharmony_ci } 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci av->leb_count += 1; 70462306a36Sopenharmony_ci rb_link_node(&aeb->u.rb, parent, p); 70562306a36Sopenharmony_ci rb_insert_color(&aeb->u.rb, &av->root); 70662306a36Sopenharmony_ci return 0; 70762306a36Sopenharmony_ci} 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci/** 71062306a36Sopenharmony_ci * ubi_add_av - add volume to the attaching information. 71162306a36Sopenharmony_ci * @ai: attaching information 71262306a36Sopenharmony_ci * @vol_id: the requested volume ID 71362306a36Sopenharmony_ci * 71462306a36Sopenharmony_ci * This function returns a pointer to the new volume description or an 71562306a36Sopenharmony_ci * ERR_PTR if the operation failed. 71662306a36Sopenharmony_ci */ 71762306a36Sopenharmony_cistruct ubi_ainf_volume *ubi_add_av(struct ubi_attach_info *ai, int vol_id) 71862306a36Sopenharmony_ci{ 71962306a36Sopenharmony_ci bool created; 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci return find_or_add_av(ai, vol_id, AV_ADD, &created); 72262306a36Sopenharmony_ci} 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci/** 72562306a36Sopenharmony_ci * ubi_find_av - find volume in the attaching information. 72662306a36Sopenharmony_ci * @ai: attaching information 72762306a36Sopenharmony_ci * @vol_id: the requested volume ID 72862306a36Sopenharmony_ci * 72962306a36Sopenharmony_ci * This function returns a pointer to the volume description or %NULL if there 73062306a36Sopenharmony_ci * are no data about this volume in the attaching information. 73162306a36Sopenharmony_ci */ 73262306a36Sopenharmony_cistruct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, 73362306a36Sopenharmony_ci int vol_id) 73462306a36Sopenharmony_ci{ 73562306a36Sopenharmony_ci bool created; 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci return find_or_add_av((struct ubi_attach_info *)ai, vol_id, AV_FIND, 73862306a36Sopenharmony_ci &created); 73962306a36Sopenharmony_ci} 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_cistatic void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av, 74262306a36Sopenharmony_ci struct list_head *list); 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ci/** 74562306a36Sopenharmony_ci * ubi_remove_av - delete attaching information about a volume. 74662306a36Sopenharmony_ci * @ai: attaching information 74762306a36Sopenharmony_ci * @av: the volume attaching information to delete 74862306a36Sopenharmony_ci */ 74962306a36Sopenharmony_civoid ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) 75062306a36Sopenharmony_ci{ 75162306a36Sopenharmony_ci dbg_bld("remove attaching information about volume %d", av->vol_id); 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci rb_erase(&av->rb, &ai->volumes); 75462306a36Sopenharmony_ci destroy_av(ai, av, &ai->erase); 75562306a36Sopenharmony_ci ai->vols_found -= 1; 75662306a36Sopenharmony_ci} 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci/** 75962306a36Sopenharmony_ci * early_erase_peb - erase a physical eraseblock. 76062306a36Sopenharmony_ci * @ubi: UBI device description object 76162306a36Sopenharmony_ci * @ai: attaching information 76262306a36Sopenharmony_ci * @pnum: physical eraseblock number to erase; 76362306a36Sopenharmony_ci * @ec: erase counter value to write (%UBI_UNKNOWN if it is unknown) 76462306a36Sopenharmony_ci * 76562306a36Sopenharmony_ci * This function erases physical eraseblock 'pnum', and writes the erase 76662306a36Sopenharmony_ci * counter header to it. This function should only be used on UBI device 76762306a36Sopenharmony_ci * initialization stages, when the EBA sub-system had not been yet initialized. 76862306a36Sopenharmony_ci * This function returns zero in case of success and a negative error code in 76962306a36Sopenharmony_ci * case of failure. 77062306a36Sopenharmony_ci */ 77162306a36Sopenharmony_cistatic int early_erase_peb(struct ubi_device *ubi, 77262306a36Sopenharmony_ci const struct ubi_attach_info *ai, int pnum, int ec) 77362306a36Sopenharmony_ci{ 77462306a36Sopenharmony_ci int err; 77562306a36Sopenharmony_ci struct ubi_ec_hdr *ec_hdr; 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci if ((long long)ec >= UBI_MAX_ERASECOUNTER) { 77862306a36Sopenharmony_ci /* 77962306a36Sopenharmony_ci * Erase counter overflow. Upgrade UBI and use 64-bit 78062306a36Sopenharmony_ci * erase counters internally. 78162306a36Sopenharmony_ci */ 78262306a36Sopenharmony_ci ubi_err(ubi, "erase counter overflow at PEB %d, EC %d", 78362306a36Sopenharmony_ci pnum, ec); 78462306a36Sopenharmony_ci return -EINVAL; 78562306a36Sopenharmony_ci } 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); 78862306a36Sopenharmony_ci if (!ec_hdr) 78962306a36Sopenharmony_ci return -ENOMEM; 79062306a36Sopenharmony_ci 79162306a36Sopenharmony_ci ec_hdr->ec = cpu_to_be64(ec); 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci err = ubi_io_sync_erase(ubi, pnum, 0); 79462306a36Sopenharmony_ci if (err < 0) 79562306a36Sopenharmony_ci goto out_free; 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci err = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr); 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_ciout_free: 80062306a36Sopenharmony_ci kfree(ec_hdr); 80162306a36Sopenharmony_ci return err; 80262306a36Sopenharmony_ci} 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_ci/** 80562306a36Sopenharmony_ci * ubi_early_get_peb - get a free physical eraseblock. 80662306a36Sopenharmony_ci * @ubi: UBI device description object 80762306a36Sopenharmony_ci * @ai: attaching information 80862306a36Sopenharmony_ci * 80962306a36Sopenharmony_ci * This function returns a free physical eraseblock. It is supposed to be 81062306a36Sopenharmony_ci * called on the UBI initialization stages when the wear-leveling sub-system is 81162306a36Sopenharmony_ci * not initialized yet. This function picks a physical eraseblocks from one of 81262306a36Sopenharmony_ci * the lists, writes the EC header if it is needed, and removes it from the 81362306a36Sopenharmony_ci * list. 81462306a36Sopenharmony_ci * 81562306a36Sopenharmony_ci * This function returns a pointer to the "aeb" of the found free PEB in case 81662306a36Sopenharmony_ci * of success and an error code in case of failure. 81762306a36Sopenharmony_ci */ 81862306a36Sopenharmony_cistruct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, 81962306a36Sopenharmony_ci struct ubi_attach_info *ai) 82062306a36Sopenharmony_ci{ 82162306a36Sopenharmony_ci int err = 0; 82262306a36Sopenharmony_ci struct ubi_ainf_peb *aeb, *tmp_aeb; 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_ci if (!list_empty(&ai->free)) { 82562306a36Sopenharmony_ci aeb = list_entry(ai->free.next, struct ubi_ainf_peb, u.list); 82662306a36Sopenharmony_ci list_del(&aeb->u.list); 82762306a36Sopenharmony_ci dbg_bld("return free PEB %d, EC %d", aeb->pnum, aeb->ec); 82862306a36Sopenharmony_ci return aeb; 82962306a36Sopenharmony_ci } 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci /* 83262306a36Sopenharmony_ci * We try to erase the first physical eraseblock from the erase list 83362306a36Sopenharmony_ci * and pick it if we succeed, or try to erase the next one if not. And 83462306a36Sopenharmony_ci * so forth. We don't want to take care about bad eraseblocks here - 83562306a36Sopenharmony_ci * they'll be handled later. 83662306a36Sopenharmony_ci */ 83762306a36Sopenharmony_ci list_for_each_entry_safe(aeb, tmp_aeb, &ai->erase, u.list) { 83862306a36Sopenharmony_ci if (aeb->ec == UBI_UNKNOWN) 83962306a36Sopenharmony_ci aeb->ec = ai->mean_ec; 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci err = early_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1); 84262306a36Sopenharmony_ci if (err) 84362306a36Sopenharmony_ci continue; 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci aeb->ec += 1; 84662306a36Sopenharmony_ci list_del(&aeb->u.list); 84762306a36Sopenharmony_ci dbg_bld("return PEB %d, EC %d", aeb->pnum, aeb->ec); 84862306a36Sopenharmony_ci return aeb; 84962306a36Sopenharmony_ci } 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_ci ubi_err(ubi, "no free eraseblocks"); 85262306a36Sopenharmony_ci return ERR_PTR(-ENOSPC); 85362306a36Sopenharmony_ci} 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci/** 85662306a36Sopenharmony_ci * check_corruption - check the data area of PEB. 85762306a36Sopenharmony_ci * @ubi: UBI device description object 85862306a36Sopenharmony_ci * @vid_hdr: the (corrupted) VID header of this PEB 85962306a36Sopenharmony_ci * @pnum: the physical eraseblock number to check 86062306a36Sopenharmony_ci * 86162306a36Sopenharmony_ci * This is a helper function which is used to distinguish between VID header 86262306a36Sopenharmony_ci * corruptions caused by power cuts and other reasons. If the PEB contains only 86362306a36Sopenharmony_ci * 0xFF bytes in the data area, the VID header is most probably corrupted 86462306a36Sopenharmony_ci * because of a power cut (%0 is returned in this case). Otherwise, it was 86562306a36Sopenharmony_ci * probably corrupted for some other reasons (%1 is returned in this case). A 86662306a36Sopenharmony_ci * negative error code is returned if a read error occurred. 86762306a36Sopenharmony_ci * 86862306a36Sopenharmony_ci * If the corruption reason was a power cut, UBI can safely erase this PEB. 86962306a36Sopenharmony_ci * Otherwise, it should preserve it to avoid possibly destroying important 87062306a36Sopenharmony_ci * information. 87162306a36Sopenharmony_ci */ 87262306a36Sopenharmony_cistatic int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, 87362306a36Sopenharmony_ci int pnum) 87462306a36Sopenharmony_ci{ 87562306a36Sopenharmony_ci int err; 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_ci mutex_lock(&ubi->buf_mutex); 87862306a36Sopenharmony_ci memset(ubi->peb_buf, 0x00, ubi->leb_size); 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci err = ubi_io_read(ubi, ubi->peb_buf, pnum, ubi->leb_start, 88162306a36Sopenharmony_ci ubi->leb_size); 88262306a36Sopenharmony_ci if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err)) { 88362306a36Sopenharmony_ci /* 88462306a36Sopenharmony_ci * Bit-flips or integrity errors while reading the data area. 88562306a36Sopenharmony_ci * It is difficult to say for sure what type of corruption is 88662306a36Sopenharmony_ci * this, but presumably a power cut happened while this PEB was 88762306a36Sopenharmony_ci * erased, so it became unstable and corrupted, and should be 88862306a36Sopenharmony_ci * erased. 88962306a36Sopenharmony_ci */ 89062306a36Sopenharmony_ci err = 0; 89162306a36Sopenharmony_ci goto out_unlock; 89262306a36Sopenharmony_ci } 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci if (err) 89562306a36Sopenharmony_ci goto out_unlock; 89662306a36Sopenharmony_ci 89762306a36Sopenharmony_ci if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size)) 89862306a36Sopenharmony_ci goto out_unlock; 89962306a36Sopenharmony_ci 90062306a36Sopenharmony_ci ubi_err(ubi, "PEB %d contains corrupted VID header, and the data does not contain all 0xFF", 90162306a36Sopenharmony_ci pnum); 90262306a36Sopenharmony_ci ubi_err(ubi, "this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection"); 90362306a36Sopenharmony_ci ubi_dump_vid_hdr(vid_hdr); 90462306a36Sopenharmony_ci pr_err("hexdump of PEB %d offset %d, length %d", 90562306a36Sopenharmony_ci pnum, ubi->leb_start, ubi->leb_size); 90662306a36Sopenharmony_ci ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, 90762306a36Sopenharmony_ci ubi->peb_buf, ubi->leb_size, 1); 90862306a36Sopenharmony_ci err = 1; 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_ciout_unlock: 91162306a36Sopenharmony_ci mutex_unlock(&ubi->buf_mutex); 91262306a36Sopenharmony_ci return err; 91362306a36Sopenharmony_ci} 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_cistatic bool vol_ignored(int vol_id) 91662306a36Sopenharmony_ci{ 91762306a36Sopenharmony_ci switch (vol_id) { 91862306a36Sopenharmony_ci case UBI_LAYOUT_VOLUME_ID: 91962306a36Sopenharmony_ci return true; 92062306a36Sopenharmony_ci } 92162306a36Sopenharmony_ci 92262306a36Sopenharmony_ci#ifdef CONFIG_MTD_UBI_FASTMAP 92362306a36Sopenharmony_ci return ubi_is_fm_vol(vol_id); 92462306a36Sopenharmony_ci#else 92562306a36Sopenharmony_ci return false; 92662306a36Sopenharmony_ci#endif 92762306a36Sopenharmony_ci} 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci/** 93062306a36Sopenharmony_ci * scan_peb - scan and process UBI headers of a PEB. 93162306a36Sopenharmony_ci * @ubi: UBI device description object 93262306a36Sopenharmony_ci * @ai: attaching information 93362306a36Sopenharmony_ci * @pnum: the physical eraseblock number 93462306a36Sopenharmony_ci * @fast: true if we're scanning for a Fastmap 93562306a36Sopenharmony_ci * 93662306a36Sopenharmony_ci * This function reads UBI headers of PEB @pnum, checks them, and adds 93762306a36Sopenharmony_ci * information about this PEB to the corresponding list or RB-tree in the 93862306a36Sopenharmony_ci * "attaching info" structure. Returns zero if the physical eraseblock was 93962306a36Sopenharmony_ci * successfully handled and a negative error code in case of failure. 94062306a36Sopenharmony_ci */ 94162306a36Sopenharmony_cistatic int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, 94262306a36Sopenharmony_ci int pnum, bool fast) 94362306a36Sopenharmony_ci{ 94462306a36Sopenharmony_ci struct ubi_ec_hdr *ech = ai->ech; 94562306a36Sopenharmony_ci struct ubi_vid_io_buf *vidb = ai->vidb; 94662306a36Sopenharmony_ci struct ubi_vid_hdr *vidh = ubi_get_vid_hdr(vidb); 94762306a36Sopenharmony_ci long long ec; 94862306a36Sopenharmony_ci int err, bitflips = 0, vol_id = -1, ec_err = 0; 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci dbg_bld("scan PEB %d", pnum); 95162306a36Sopenharmony_ci 95262306a36Sopenharmony_ci /* Skip bad physical eraseblocks */ 95362306a36Sopenharmony_ci err = ubi_io_is_bad(ubi, pnum); 95462306a36Sopenharmony_ci if (err < 0) 95562306a36Sopenharmony_ci return err; 95662306a36Sopenharmony_ci else if (err) { 95762306a36Sopenharmony_ci ai->bad_peb_count += 1; 95862306a36Sopenharmony_ci return 0; 95962306a36Sopenharmony_ci } 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); 96262306a36Sopenharmony_ci if (err < 0) 96362306a36Sopenharmony_ci return err; 96462306a36Sopenharmony_ci switch (err) { 96562306a36Sopenharmony_ci case 0: 96662306a36Sopenharmony_ci break; 96762306a36Sopenharmony_ci case UBI_IO_BITFLIPS: 96862306a36Sopenharmony_ci bitflips = 1; 96962306a36Sopenharmony_ci break; 97062306a36Sopenharmony_ci case UBI_IO_FF: 97162306a36Sopenharmony_ci ai->empty_peb_count += 1; 97262306a36Sopenharmony_ci return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, 97362306a36Sopenharmony_ci UBI_UNKNOWN, 0, &ai->erase); 97462306a36Sopenharmony_ci case UBI_IO_FF_BITFLIPS: 97562306a36Sopenharmony_ci ai->empty_peb_count += 1; 97662306a36Sopenharmony_ci return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, 97762306a36Sopenharmony_ci UBI_UNKNOWN, 1, &ai->erase); 97862306a36Sopenharmony_ci case UBI_IO_BAD_HDR_EBADMSG: 97962306a36Sopenharmony_ci case UBI_IO_BAD_HDR: 98062306a36Sopenharmony_ci /* 98162306a36Sopenharmony_ci * We have to also look at the VID header, possibly it is not 98262306a36Sopenharmony_ci * corrupted. Set %bitflips flag in order to make this PEB be 98362306a36Sopenharmony_ci * moved and EC be re-created. 98462306a36Sopenharmony_ci */ 98562306a36Sopenharmony_ci ec_err = err; 98662306a36Sopenharmony_ci ec = UBI_UNKNOWN; 98762306a36Sopenharmony_ci bitflips = 1; 98862306a36Sopenharmony_ci break; 98962306a36Sopenharmony_ci default: 99062306a36Sopenharmony_ci ubi_err(ubi, "'ubi_io_read_ec_hdr()' returned unknown code %d", 99162306a36Sopenharmony_ci err); 99262306a36Sopenharmony_ci return -EINVAL; 99362306a36Sopenharmony_ci } 99462306a36Sopenharmony_ci 99562306a36Sopenharmony_ci if (!ec_err) { 99662306a36Sopenharmony_ci int image_seq; 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_ci /* Make sure UBI version is OK */ 99962306a36Sopenharmony_ci if (ech->version != UBI_VERSION) { 100062306a36Sopenharmony_ci ubi_err(ubi, "this UBI version is %d, image version is %d", 100162306a36Sopenharmony_ci UBI_VERSION, (int)ech->version); 100262306a36Sopenharmony_ci return -EINVAL; 100362306a36Sopenharmony_ci } 100462306a36Sopenharmony_ci 100562306a36Sopenharmony_ci ec = be64_to_cpu(ech->ec); 100662306a36Sopenharmony_ci if (ec > UBI_MAX_ERASECOUNTER) { 100762306a36Sopenharmony_ci /* 100862306a36Sopenharmony_ci * Erase counter overflow. The EC headers have 64 bits 100962306a36Sopenharmony_ci * reserved, but we anyway make use of only 31 bit 101062306a36Sopenharmony_ci * values, as this seems to be enough for any existing 101162306a36Sopenharmony_ci * flash. Upgrade UBI and use 64-bit erase counters 101262306a36Sopenharmony_ci * internally. 101362306a36Sopenharmony_ci */ 101462306a36Sopenharmony_ci ubi_err(ubi, "erase counter overflow, max is %d", 101562306a36Sopenharmony_ci UBI_MAX_ERASECOUNTER); 101662306a36Sopenharmony_ci ubi_dump_ec_hdr(ech); 101762306a36Sopenharmony_ci return -EINVAL; 101862306a36Sopenharmony_ci } 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ci /* 102162306a36Sopenharmony_ci * Make sure that all PEBs have the same image sequence number. 102262306a36Sopenharmony_ci * This allows us to detect situations when users flash UBI 102362306a36Sopenharmony_ci * images incorrectly, so that the flash has the new UBI image 102462306a36Sopenharmony_ci * and leftovers from the old one. This feature was added 102562306a36Sopenharmony_ci * relatively recently, and the sequence number was always 102662306a36Sopenharmony_ci * zero, because old UBI implementations always set it to zero. 102762306a36Sopenharmony_ci * For this reasons, we do not panic if some PEBs have zero 102862306a36Sopenharmony_ci * sequence number, while other PEBs have non-zero sequence 102962306a36Sopenharmony_ci * number. 103062306a36Sopenharmony_ci */ 103162306a36Sopenharmony_ci image_seq = be32_to_cpu(ech->image_seq); 103262306a36Sopenharmony_ci if (!ubi->image_seq) 103362306a36Sopenharmony_ci ubi->image_seq = image_seq; 103462306a36Sopenharmony_ci if (image_seq && ubi->image_seq != image_seq) { 103562306a36Sopenharmony_ci ubi_err(ubi, "bad image sequence number %d in PEB %d, expected %d", 103662306a36Sopenharmony_ci image_seq, pnum, ubi->image_seq); 103762306a36Sopenharmony_ci ubi_dump_ec_hdr(ech); 103862306a36Sopenharmony_ci return -EINVAL; 103962306a36Sopenharmony_ci } 104062306a36Sopenharmony_ci } 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ci /* OK, we've done with the EC header, let's look at the VID header */ 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ci err = ubi_io_read_vid_hdr(ubi, pnum, vidb, 0); 104562306a36Sopenharmony_ci if (err < 0) 104662306a36Sopenharmony_ci return err; 104762306a36Sopenharmony_ci switch (err) { 104862306a36Sopenharmony_ci case 0: 104962306a36Sopenharmony_ci break; 105062306a36Sopenharmony_ci case UBI_IO_BITFLIPS: 105162306a36Sopenharmony_ci bitflips = 1; 105262306a36Sopenharmony_ci break; 105362306a36Sopenharmony_ci case UBI_IO_BAD_HDR_EBADMSG: 105462306a36Sopenharmony_ci if (ec_err == UBI_IO_BAD_HDR_EBADMSG) 105562306a36Sopenharmony_ci /* 105662306a36Sopenharmony_ci * Both EC and VID headers are corrupted and were read 105762306a36Sopenharmony_ci * with data integrity error, probably this is a bad 105862306a36Sopenharmony_ci * PEB, bit it is not marked as bad yet. This may also 105962306a36Sopenharmony_ci * be a result of power cut during erasure. 106062306a36Sopenharmony_ci */ 106162306a36Sopenharmony_ci ai->maybe_bad_peb_count += 1; 106262306a36Sopenharmony_ci fallthrough; 106362306a36Sopenharmony_ci case UBI_IO_BAD_HDR: 106462306a36Sopenharmony_ci /* 106562306a36Sopenharmony_ci * If we're facing a bad VID header we have to drop *all* 106662306a36Sopenharmony_ci * Fastmap data structures we find. The most recent Fastmap 106762306a36Sopenharmony_ci * could be bad and therefore there is a chance that we attach 106862306a36Sopenharmony_ci * from an old one. On a fine MTD stack a PEB must not render 106962306a36Sopenharmony_ci * bad all of a sudden, but the reality is different. 107062306a36Sopenharmony_ci * So, let's be paranoid and help finding the root cause by 107162306a36Sopenharmony_ci * falling back to scanning mode instead of attaching with a 107262306a36Sopenharmony_ci * bad EBA table and cause data corruption which is hard to 107362306a36Sopenharmony_ci * analyze. 107462306a36Sopenharmony_ci */ 107562306a36Sopenharmony_ci if (fast) 107662306a36Sopenharmony_ci ai->force_full_scan = 1; 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_ci if (ec_err) 107962306a36Sopenharmony_ci /* 108062306a36Sopenharmony_ci * Both headers are corrupted. There is a possibility 108162306a36Sopenharmony_ci * that this a valid UBI PEB which has corresponding 108262306a36Sopenharmony_ci * LEB, but the headers are corrupted. However, it is 108362306a36Sopenharmony_ci * impossible to distinguish it from a PEB which just 108462306a36Sopenharmony_ci * contains garbage because of a power cut during erase 108562306a36Sopenharmony_ci * operation. So we just schedule this PEB for erasure. 108662306a36Sopenharmony_ci * 108762306a36Sopenharmony_ci * Besides, in case of NOR flash, we deliberately 108862306a36Sopenharmony_ci * corrupt both headers because NOR flash erasure is 108962306a36Sopenharmony_ci * slow and can start from the end. 109062306a36Sopenharmony_ci */ 109162306a36Sopenharmony_ci err = 0; 109262306a36Sopenharmony_ci else 109362306a36Sopenharmony_ci /* 109462306a36Sopenharmony_ci * The EC was OK, but the VID header is corrupted. We 109562306a36Sopenharmony_ci * have to check what is in the data area. 109662306a36Sopenharmony_ci */ 109762306a36Sopenharmony_ci err = check_corruption(ubi, vidh, pnum); 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_ci if (err < 0) 110062306a36Sopenharmony_ci return err; 110162306a36Sopenharmony_ci else if (!err) 110262306a36Sopenharmony_ci /* This corruption is caused by a power cut */ 110362306a36Sopenharmony_ci err = add_to_list(ai, pnum, UBI_UNKNOWN, 110462306a36Sopenharmony_ci UBI_UNKNOWN, ec, 1, &ai->erase); 110562306a36Sopenharmony_ci else 110662306a36Sopenharmony_ci /* This is an unexpected corruption */ 110762306a36Sopenharmony_ci err = add_corrupted(ai, pnum, ec); 110862306a36Sopenharmony_ci if (err) 110962306a36Sopenharmony_ci return err; 111062306a36Sopenharmony_ci goto adjust_mean_ec; 111162306a36Sopenharmony_ci case UBI_IO_FF_BITFLIPS: 111262306a36Sopenharmony_ci err = add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, 111362306a36Sopenharmony_ci ec, 1, &ai->erase); 111462306a36Sopenharmony_ci if (err) 111562306a36Sopenharmony_ci return err; 111662306a36Sopenharmony_ci goto adjust_mean_ec; 111762306a36Sopenharmony_ci case UBI_IO_FF: 111862306a36Sopenharmony_ci if (ec_err || bitflips) 111962306a36Sopenharmony_ci err = add_to_list(ai, pnum, UBI_UNKNOWN, 112062306a36Sopenharmony_ci UBI_UNKNOWN, ec, 1, &ai->erase); 112162306a36Sopenharmony_ci else 112262306a36Sopenharmony_ci err = add_to_list(ai, pnum, UBI_UNKNOWN, 112362306a36Sopenharmony_ci UBI_UNKNOWN, ec, 0, &ai->free); 112462306a36Sopenharmony_ci if (err) 112562306a36Sopenharmony_ci return err; 112662306a36Sopenharmony_ci goto adjust_mean_ec; 112762306a36Sopenharmony_ci default: 112862306a36Sopenharmony_ci ubi_err(ubi, "'ubi_io_read_vid_hdr()' returned unknown code %d", 112962306a36Sopenharmony_ci err); 113062306a36Sopenharmony_ci return -EINVAL; 113162306a36Sopenharmony_ci } 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_ci vol_id = be32_to_cpu(vidh->vol_id); 113462306a36Sopenharmony_ci if (vol_id > UBI_MAX_VOLUMES && !vol_ignored(vol_id)) { 113562306a36Sopenharmony_ci int lnum = be32_to_cpu(vidh->lnum); 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci /* Unsupported internal volume */ 113862306a36Sopenharmony_ci switch (vidh->compat) { 113962306a36Sopenharmony_ci case UBI_COMPAT_DELETE: 114062306a36Sopenharmony_ci ubi_msg(ubi, "\"delete\" compatible internal volume %d:%d found, will remove it", 114162306a36Sopenharmony_ci vol_id, lnum); 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci err = add_to_list(ai, pnum, vol_id, lnum, 114462306a36Sopenharmony_ci ec, 1, &ai->erase); 114562306a36Sopenharmony_ci if (err) 114662306a36Sopenharmony_ci return err; 114762306a36Sopenharmony_ci return 0; 114862306a36Sopenharmony_ci 114962306a36Sopenharmony_ci case UBI_COMPAT_RO: 115062306a36Sopenharmony_ci ubi_msg(ubi, "read-only compatible internal volume %d:%d found, switch to read-only mode", 115162306a36Sopenharmony_ci vol_id, lnum); 115262306a36Sopenharmony_ci ubi->ro_mode = 1; 115362306a36Sopenharmony_ci break; 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci case UBI_COMPAT_PRESERVE: 115662306a36Sopenharmony_ci ubi_msg(ubi, "\"preserve\" compatible internal volume %d:%d found", 115762306a36Sopenharmony_ci vol_id, lnum); 115862306a36Sopenharmony_ci err = add_to_list(ai, pnum, vol_id, lnum, 115962306a36Sopenharmony_ci ec, 0, &ai->alien); 116062306a36Sopenharmony_ci if (err) 116162306a36Sopenharmony_ci return err; 116262306a36Sopenharmony_ci return 0; 116362306a36Sopenharmony_ci 116462306a36Sopenharmony_ci case UBI_COMPAT_REJECT: 116562306a36Sopenharmony_ci ubi_err(ubi, "incompatible internal volume %d:%d found", 116662306a36Sopenharmony_ci vol_id, lnum); 116762306a36Sopenharmony_ci return -EINVAL; 116862306a36Sopenharmony_ci } 116962306a36Sopenharmony_ci } 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ci if (ec_err) 117262306a36Sopenharmony_ci ubi_warn(ubi, "valid VID header but corrupted EC header at PEB %d", 117362306a36Sopenharmony_ci pnum); 117462306a36Sopenharmony_ci 117562306a36Sopenharmony_ci if (ubi_is_fm_vol(vol_id)) 117662306a36Sopenharmony_ci err = add_fastmap(ai, pnum, vidh, ec); 117762306a36Sopenharmony_ci else 117862306a36Sopenharmony_ci err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips); 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci if (err) 118162306a36Sopenharmony_ci return err; 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ciadjust_mean_ec: 118462306a36Sopenharmony_ci if (!ec_err) { 118562306a36Sopenharmony_ci ai->ec_sum += ec; 118662306a36Sopenharmony_ci ai->ec_count += 1; 118762306a36Sopenharmony_ci if (ec > ai->max_ec) 118862306a36Sopenharmony_ci ai->max_ec = ec; 118962306a36Sopenharmony_ci if (ec < ai->min_ec) 119062306a36Sopenharmony_ci ai->min_ec = ec; 119162306a36Sopenharmony_ci } 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_ci return 0; 119462306a36Sopenharmony_ci} 119562306a36Sopenharmony_ci 119662306a36Sopenharmony_ci/** 119762306a36Sopenharmony_ci * late_analysis - analyze the overall situation with PEB. 119862306a36Sopenharmony_ci * @ubi: UBI device description object 119962306a36Sopenharmony_ci * @ai: attaching information 120062306a36Sopenharmony_ci * 120162306a36Sopenharmony_ci * This is a helper function which takes a look what PEBs we have after we 120262306a36Sopenharmony_ci * gather information about all of them ("ai" is compete). It decides whether 120362306a36Sopenharmony_ci * the flash is empty and should be formatted of whether there are too many 120462306a36Sopenharmony_ci * corrupted PEBs and we should not attach this MTD device. Returns zero if we 120562306a36Sopenharmony_ci * should proceed with attaching the MTD device, and %-EINVAL if we should not. 120662306a36Sopenharmony_ci */ 120762306a36Sopenharmony_cistatic int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) 120862306a36Sopenharmony_ci{ 120962306a36Sopenharmony_ci struct ubi_ainf_peb *aeb; 121062306a36Sopenharmony_ci int max_corr, peb_count; 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci peb_count = ubi->peb_count - ai->bad_peb_count - ai->alien_peb_count; 121362306a36Sopenharmony_ci max_corr = peb_count / 20 ?: 8; 121462306a36Sopenharmony_ci 121562306a36Sopenharmony_ci /* 121662306a36Sopenharmony_ci * Few corrupted PEBs is not a problem and may be just a result of 121762306a36Sopenharmony_ci * unclean reboots. However, many of them may indicate some problems 121862306a36Sopenharmony_ci * with the flash HW or driver. 121962306a36Sopenharmony_ci */ 122062306a36Sopenharmony_ci if (ai->corr_peb_count) { 122162306a36Sopenharmony_ci ubi_err(ubi, "%d PEBs are corrupted and preserved", 122262306a36Sopenharmony_ci ai->corr_peb_count); 122362306a36Sopenharmony_ci pr_err("Corrupted PEBs are:"); 122462306a36Sopenharmony_ci list_for_each_entry(aeb, &ai->corr, u.list) 122562306a36Sopenharmony_ci pr_cont(" %d", aeb->pnum); 122662306a36Sopenharmony_ci pr_cont("\n"); 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci /* 122962306a36Sopenharmony_ci * If too many PEBs are corrupted, we refuse attaching, 123062306a36Sopenharmony_ci * otherwise, only print a warning. 123162306a36Sopenharmony_ci */ 123262306a36Sopenharmony_ci if (ai->corr_peb_count >= max_corr) { 123362306a36Sopenharmony_ci ubi_err(ubi, "too many corrupted PEBs, refusing"); 123462306a36Sopenharmony_ci return -EINVAL; 123562306a36Sopenharmony_ci } 123662306a36Sopenharmony_ci } 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci if (ai->empty_peb_count + ai->maybe_bad_peb_count == peb_count) { 123962306a36Sopenharmony_ci /* 124062306a36Sopenharmony_ci * All PEBs are empty, or almost all - a couple PEBs look like 124162306a36Sopenharmony_ci * they may be bad PEBs which were not marked as bad yet. 124262306a36Sopenharmony_ci * 124362306a36Sopenharmony_ci * This piece of code basically tries to distinguish between 124462306a36Sopenharmony_ci * the following situations: 124562306a36Sopenharmony_ci * 124662306a36Sopenharmony_ci * 1. Flash is empty, but there are few bad PEBs, which are not 124762306a36Sopenharmony_ci * marked as bad so far, and which were read with error. We 124862306a36Sopenharmony_ci * want to go ahead and format this flash. While formatting, 124962306a36Sopenharmony_ci * the faulty PEBs will probably be marked as bad. 125062306a36Sopenharmony_ci * 125162306a36Sopenharmony_ci * 2. Flash contains non-UBI data and we do not want to format 125262306a36Sopenharmony_ci * it and destroy possibly important information. 125362306a36Sopenharmony_ci */ 125462306a36Sopenharmony_ci if (ai->maybe_bad_peb_count <= 2) { 125562306a36Sopenharmony_ci ai->is_empty = 1; 125662306a36Sopenharmony_ci ubi_msg(ubi, "empty MTD device detected"); 125762306a36Sopenharmony_ci get_random_bytes(&ubi->image_seq, 125862306a36Sopenharmony_ci sizeof(ubi->image_seq)); 125962306a36Sopenharmony_ci } else { 126062306a36Sopenharmony_ci ubi_err(ubi, "MTD device is not UBI-formatted and possibly contains non-UBI data - refusing it"); 126162306a36Sopenharmony_ci return -EINVAL; 126262306a36Sopenharmony_ci } 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_ci } 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_ci return 0; 126762306a36Sopenharmony_ci} 126862306a36Sopenharmony_ci 126962306a36Sopenharmony_ci/** 127062306a36Sopenharmony_ci * destroy_av - free volume attaching information. 127162306a36Sopenharmony_ci * @av: volume attaching information 127262306a36Sopenharmony_ci * @ai: attaching information 127362306a36Sopenharmony_ci * @list: put the aeb elements in there if !NULL, otherwise free them 127462306a36Sopenharmony_ci * 127562306a36Sopenharmony_ci * This function destroys the volume attaching information. 127662306a36Sopenharmony_ci */ 127762306a36Sopenharmony_cistatic void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av, 127862306a36Sopenharmony_ci struct list_head *list) 127962306a36Sopenharmony_ci{ 128062306a36Sopenharmony_ci struct ubi_ainf_peb *aeb; 128162306a36Sopenharmony_ci struct rb_node *this = av->root.rb_node; 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_ci while (this) { 128462306a36Sopenharmony_ci if (this->rb_left) 128562306a36Sopenharmony_ci this = this->rb_left; 128662306a36Sopenharmony_ci else if (this->rb_right) 128762306a36Sopenharmony_ci this = this->rb_right; 128862306a36Sopenharmony_ci else { 128962306a36Sopenharmony_ci aeb = rb_entry(this, struct ubi_ainf_peb, u.rb); 129062306a36Sopenharmony_ci this = rb_parent(this); 129162306a36Sopenharmony_ci if (this) { 129262306a36Sopenharmony_ci if (this->rb_left == &aeb->u.rb) 129362306a36Sopenharmony_ci this->rb_left = NULL; 129462306a36Sopenharmony_ci else 129562306a36Sopenharmony_ci this->rb_right = NULL; 129662306a36Sopenharmony_ci } 129762306a36Sopenharmony_ci 129862306a36Sopenharmony_ci if (list) 129962306a36Sopenharmony_ci list_add_tail(&aeb->u.list, list); 130062306a36Sopenharmony_ci else 130162306a36Sopenharmony_ci ubi_free_aeb(ai, aeb); 130262306a36Sopenharmony_ci } 130362306a36Sopenharmony_ci } 130462306a36Sopenharmony_ci kfree(av); 130562306a36Sopenharmony_ci} 130662306a36Sopenharmony_ci 130762306a36Sopenharmony_ci/** 130862306a36Sopenharmony_ci * destroy_ai - destroy attaching information. 130962306a36Sopenharmony_ci * @ai: attaching information 131062306a36Sopenharmony_ci */ 131162306a36Sopenharmony_cistatic void destroy_ai(struct ubi_attach_info *ai) 131262306a36Sopenharmony_ci{ 131362306a36Sopenharmony_ci struct ubi_ainf_peb *aeb, *aeb_tmp; 131462306a36Sopenharmony_ci struct ubi_ainf_volume *av; 131562306a36Sopenharmony_ci struct rb_node *rb; 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { 131862306a36Sopenharmony_ci list_del(&aeb->u.list); 131962306a36Sopenharmony_ci ubi_free_aeb(ai, aeb); 132062306a36Sopenharmony_ci } 132162306a36Sopenharmony_ci list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { 132262306a36Sopenharmony_ci list_del(&aeb->u.list); 132362306a36Sopenharmony_ci ubi_free_aeb(ai, aeb); 132462306a36Sopenharmony_ci } 132562306a36Sopenharmony_ci list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { 132662306a36Sopenharmony_ci list_del(&aeb->u.list); 132762306a36Sopenharmony_ci ubi_free_aeb(ai, aeb); 132862306a36Sopenharmony_ci } 132962306a36Sopenharmony_ci list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { 133062306a36Sopenharmony_ci list_del(&aeb->u.list); 133162306a36Sopenharmony_ci ubi_free_aeb(ai, aeb); 133262306a36Sopenharmony_ci } 133362306a36Sopenharmony_ci list_for_each_entry_safe(aeb, aeb_tmp, &ai->fastmap, u.list) { 133462306a36Sopenharmony_ci list_del(&aeb->u.list); 133562306a36Sopenharmony_ci ubi_free_aeb(ai, aeb); 133662306a36Sopenharmony_ci } 133762306a36Sopenharmony_ci 133862306a36Sopenharmony_ci /* Destroy the volume RB-tree */ 133962306a36Sopenharmony_ci rb = ai->volumes.rb_node; 134062306a36Sopenharmony_ci while (rb) { 134162306a36Sopenharmony_ci if (rb->rb_left) 134262306a36Sopenharmony_ci rb = rb->rb_left; 134362306a36Sopenharmony_ci else if (rb->rb_right) 134462306a36Sopenharmony_ci rb = rb->rb_right; 134562306a36Sopenharmony_ci else { 134662306a36Sopenharmony_ci av = rb_entry(rb, struct ubi_ainf_volume, rb); 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci rb = rb_parent(rb); 134962306a36Sopenharmony_ci if (rb) { 135062306a36Sopenharmony_ci if (rb->rb_left == &av->rb) 135162306a36Sopenharmony_ci rb->rb_left = NULL; 135262306a36Sopenharmony_ci else 135362306a36Sopenharmony_ci rb->rb_right = NULL; 135462306a36Sopenharmony_ci } 135562306a36Sopenharmony_ci 135662306a36Sopenharmony_ci destroy_av(ai, av, NULL); 135762306a36Sopenharmony_ci } 135862306a36Sopenharmony_ci } 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci kmem_cache_destroy(ai->aeb_slab_cache); 136162306a36Sopenharmony_ci kfree(ai); 136262306a36Sopenharmony_ci} 136362306a36Sopenharmony_ci 136462306a36Sopenharmony_ci/** 136562306a36Sopenharmony_ci * scan_all - scan entire MTD device. 136662306a36Sopenharmony_ci * @ubi: UBI device description object 136762306a36Sopenharmony_ci * @ai: attach info object 136862306a36Sopenharmony_ci * @start: start scanning at this PEB 136962306a36Sopenharmony_ci * 137062306a36Sopenharmony_ci * This function does full scanning of an MTD device and returns complete 137162306a36Sopenharmony_ci * information about it in form of a "struct ubi_attach_info" object. In case 137262306a36Sopenharmony_ci * of failure, an error code is returned. 137362306a36Sopenharmony_ci */ 137462306a36Sopenharmony_cistatic int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, 137562306a36Sopenharmony_ci int start) 137662306a36Sopenharmony_ci{ 137762306a36Sopenharmony_ci int err, pnum; 137862306a36Sopenharmony_ci struct rb_node *rb1, *rb2; 137962306a36Sopenharmony_ci struct ubi_ainf_volume *av; 138062306a36Sopenharmony_ci struct ubi_ainf_peb *aeb; 138162306a36Sopenharmony_ci 138262306a36Sopenharmony_ci err = -ENOMEM; 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci ai->ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); 138562306a36Sopenharmony_ci if (!ai->ech) 138662306a36Sopenharmony_ci return err; 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci ai->vidb = ubi_alloc_vid_buf(ubi, GFP_KERNEL); 138962306a36Sopenharmony_ci if (!ai->vidb) 139062306a36Sopenharmony_ci goto out_ech; 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci for (pnum = start; pnum < ubi->peb_count; pnum++) { 139362306a36Sopenharmony_ci cond_resched(); 139462306a36Sopenharmony_ci 139562306a36Sopenharmony_ci dbg_gen("process PEB %d", pnum); 139662306a36Sopenharmony_ci err = scan_peb(ubi, ai, pnum, false); 139762306a36Sopenharmony_ci if (err < 0) 139862306a36Sopenharmony_ci goto out_vidh; 139962306a36Sopenharmony_ci } 140062306a36Sopenharmony_ci 140162306a36Sopenharmony_ci ubi_msg(ubi, "scanning is finished"); 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci /* Calculate mean erase counter */ 140462306a36Sopenharmony_ci if (ai->ec_count) 140562306a36Sopenharmony_ci ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ci err = late_analysis(ubi, ai); 140862306a36Sopenharmony_ci if (err) 140962306a36Sopenharmony_ci goto out_vidh; 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci /* 141262306a36Sopenharmony_ci * In case of unknown erase counter we use the mean erase counter 141362306a36Sopenharmony_ci * value. 141462306a36Sopenharmony_ci */ 141562306a36Sopenharmony_ci ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { 141662306a36Sopenharmony_ci ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) 141762306a36Sopenharmony_ci if (aeb->ec == UBI_UNKNOWN) 141862306a36Sopenharmony_ci aeb->ec = ai->mean_ec; 141962306a36Sopenharmony_ci } 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci list_for_each_entry(aeb, &ai->free, u.list) { 142262306a36Sopenharmony_ci if (aeb->ec == UBI_UNKNOWN) 142362306a36Sopenharmony_ci aeb->ec = ai->mean_ec; 142462306a36Sopenharmony_ci } 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci list_for_each_entry(aeb, &ai->corr, u.list) 142762306a36Sopenharmony_ci if (aeb->ec == UBI_UNKNOWN) 142862306a36Sopenharmony_ci aeb->ec = ai->mean_ec; 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci list_for_each_entry(aeb, &ai->erase, u.list) 143162306a36Sopenharmony_ci if (aeb->ec == UBI_UNKNOWN) 143262306a36Sopenharmony_ci aeb->ec = ai->mean_ec; 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_ci err = self_check_ai(ubi, ai); 143562306a36Sopenharmony_ci if (err) 143662306a36Sopenharmony_ci goto out_vidh; 143762306a36Sopenharmony_ci 143862306a36Sopenharmony_ci ubi_free_vid_buf(ai->vidb); 143962306a36Sopenharmony_ci kfree(ai->ech); 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci return 0; 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ciout_vidh: 144462306a36Sopenharmony_ci ubi_free_vid_buf(ai->vidb); 144562306a36Sopenharmony_ciout_ech: 144662306a36Sopenharmony_ci kfree(ai->ech); 144762306a36Sopenharmony_ci return err; 144862306a36Sopenharmony_ci} 144962306a36Sopenharmony_ci 145062306a36Sopenharmony_cistatic struct ubi_attach_info *alloc_ai(void) 145162306a36Sopenharmony_ci{ 145262306a36Sopenharmony_ci struct ubi_attach_info *ai; 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); 145562306a36Sopenharmony_ci if (!ai) 145662306a36Sopenharmony_ci return ai; 145762306a36Sopenharmony_ci 145862306a36Sopenharmony_ci INIT_LIST_HEAD(&ai->corr); 145962306a36Sopenharmony_ci INIT_LIST_HEAD(&ai->free); 146062306a36Sopenharmony_ci INIT_LIST_HEAD(&ai->erase); 146162306a36Sopenharmony_ci INIT_LIST_HEAD(&ai->alien); 146262306a36Sopenharmony_ci INIT_LIST_HEAD(&ai->fastmap); 146362306a36Sopenharmony_ci ai->volumes = RB_ROOT; 146462306a36Sopenharmony_ci ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", 146562306a36Sopenharmony_ci sizeof(struct ubi_ainf_peb), 146662306a36Sopenharmony_ci 0, 0, NULL); 146762306a36Sopenharmony_ci if (!ai->aeb_slab_cache) { 146862306a36Sopenharmony_ci kfree(ai); 146962306a36Sopenharmony_ci ai = NULL; 147062306a36Sopenharmony_ci } 147162306a36Sopenharmony_ci 147262306a36Sopenharmony_ci return ai; 147362306a36Sopenharmony_ci} 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci#ifdef CONFIG_MTD_UBI_FASTMAP 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_ci/** 147862306a36Sopenharmony_ci * scan_fast - try to find a fastmap and attach from it. 147962306a36Sopenharmony_ci * @ubi: UBI device description object 148062306a36Sopenharmony_ci * @ai: attach info object 148162306a36Sopenharmony_ci * 148262306a36Sopenharmony_ci * Returns 0 on success, negative return values indicate an internal 148362306a36Sopenharmony_ci * error. 148462306a36Sopenharmony_ci * UBI_NO_FASTMAP denotes that no fastmap was found. 148562306a36Sopenharmony_ci * UBI_BAD_FASTMAP denotes that the found fastmap was invalid. 148662306a36Sopenharmony_ci */ 148762306a36Sopenharmony_cistatic int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai) 148862306a36Sopenharmony_ci{ 148962306a36Sopenharmony_ci int err, pnum; 149062306a36Sopenharmony_ci struct ubi_attach_info *scan_ai; 149162306a36Sopenharmony_ci 149262306a36Sopenharmony_ci err = -ENOMEM; 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci scan_ai = alloc_ai(); 149562306a36Sopenharmony_ci if (!scan_ai) 149662306a36Sopenharmony_ci goto out; 149762306a36Sopenharmony_ci 149862306a36Sopenharmony_ci scan_ai->ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); 149962306a36Sopenharmony_ci if (!scan_ai->ech) 150062306a36Sopenharmony_ci goto out_ai; 150162306a36Sopenharmony_ci 150262306a36Sopenharmony_ci scan_ai->vidb = ubi_alloc_vid_buf(ubi, GFP_KERNEL); 150362306a36Sopenharmony_ci if (!scan_ai->vidb) 150462306a36Sopenharmony_ci goto out_ech; 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci for (pnum = 0; pnum < UBI_FM_MAX_START; pnum++) { 150762306a36Sopenharmony_ci cond_resched(); 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ci dbg_gen("process PEB %d", pnum); 151062306a36Sopenharmony_ci err = scan_peb(ubi, scan_ai, pnum, true); 151162306a36Sopenharmony_ci if (err < 0) 151262306a36Sopenharmony_ci goto out_vidh; 151362306a36Sopenharmony_ci } 151462306a36Sopenharmony_ci 151562306a36Sopenharmony_ci ubi_free_vid_buf(scan_ai->vidb); 151662306a36Sopenharmony_ci kfree(scan_ai->ech); 151762306a36Sopenharmony_ci 151862306a36Sopenharmony_ci if (scan_ai->force_full_scan) 151962306a36Sopenharmony_ci err = UBI_NO_FASTMAP; 152062306a36Sopenharmony_ci else 152162306a36Sopenharmony_ci err = ubi_scan_fastmap(ubi, *ai, scan_ai); 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_ci if (err) { 152462306a36Sopenharmony_ci /* 152562306a36Sopenharmony_ci * Didn't attach via fastmap, do a full scan but reuse what 152662306a36Sopenharmony_ci * we've aready scanned. 152762306a36Sopenharmony_ci */ 152862306a36Sopenharmony_ci destroy_ai(*ai); 152962306a36Sopenharmony_ci *ai = scan_ai; 153062306a36Sopenharmony_ci } else 153162306a36Sopenharmony_ci destroy_ai(scan_ai); 153262306a36Sopenharmony_ci 153362306a36Sopenharmony_ci return err; 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ciout_vidh: 153662306a36Sopenharmony_ci ubi_free_vid_buf(scan_ai->vidb); 153762306a36Sopenharmony_ciout_ech: 153862306a36Sopenharmony_ci kfree(scan_ai->ech); 153962306a36Sopenharmony_ciout_ai: 154062306a36Sopenharmony_ci destroy_ai(scan_ai); 154162306a36Sopenharmony_ciout: 154262306a36Sopenharmony_ci return err; 154362306a36Sopenharmony_ci} 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci#endif 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_ci/** 154862306a36Sopenharmony_ci * ubi_attach - attach an MTD device. 154962306a36Sopenharmony_ci * @ubi: UBI device descriptor 155062306a36Sopenharmony_ci * @force_scan: if set to non-zero attach by scanning 155162306a36Sopenharmony_ci * 155262306a36Sopenharmony_ci * This function returns zero in case of success and a negative error code in 155362306a36Sopenharmony_ci * case of failure. 155462306a36Sopenharmony_ci */ 155562306a36Sopenharmony_ciint ubi_attach(struct ubi_device *ubi, int force_scan) 155662306a36Sopenharmony_ci{ 155762306a36Sopenharmony_ci int err; 155862306a36Sopenharmony_ci struct ubi_attach_info *ai; 155962306a36Sopenharmony_ci 156062306a36Sopenharmony_ci ai = alloc_ai(); 156162306a36Sopenharmony_ci if (!ai) 156262306a36Sopenharmony_ci return -ENOMEM; 156362306a36Sopenharmony_ci 156462306a36Sopenharmony_ci#ifdef CONFIG_MTD_UBI_FASTMAP 156562306a36Sopenharmony_ci /* On small flash devices we disable fastmap in any case. */ 156662306a36Sopenharmony_ci if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) { 156762306a36Sopenharmony_ci ubi->fm_disabled = 1; 156862306a36Sopenharmony_ci force_scan = 1; 156962306a36Sopenharmony_ci } 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci if (force_scan) 157262306a36Sopenharmony_ci err = scan_all(ubi, ai, 0); 157362306a36Sopenharmony_ci else { 157462306a36Sopenharmony_ci err = scan_fast(ubi, &ai); 157562306a36Sopenharmony_ci if (err > 0 || mtd_is_eccerr(err)) { 157662306a36Sopenharmony_ci if (err != UBI_NO_FASTMAP) { 157762306a36Sopenharmony_ci destroy_ai(ai); 157862306a36Sopenharmony_ci ai = alloc_ai(); 157962306a36Sopenharmony_ci if (!ai) 158062306a36Sopenharmony_ci return -ENOMEM; 158162306a36Sopenharmony_ci 158262306a36Sopenharmony_ci err = scan_all(ubi, ai, 0); 158362306a36Sopenharmony_ci } else { 158462306a36Sopenharmony_ci err = scan_all(ubi, ai, UBI_FM_MAX_START); 158562306a36Sopenharmony_ci } 158662306a36Sopenharmony_ci } 158762306a36Sopenharmony_ci } 158862306a36Sopenharmony_ci#else 158962306a36Sopenharmony_ci err = scan_all(ubi, ai, 0); 159062306a36Sopenharmony_ci#endif 159162306a36Sopenharmony_ci if (err) 159262306a36Sopenharmony_ci goto out_ai; 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci ubi->bad_peb_count = ai->bad_peb_count; 159562306a36Sopenharmony_ci ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; 159662306a36Sopenharmony_ci ubi->corr_peb_count = ai->corr_peb_count; 159762306a36Sopenharmony_ci ubi->max_ec = ai->max_ec; 159862306a36Sopenharmony_ci ubi->mean_ec = ai->mean_ec; 159962306a36Sopenharmony_ci dbg_gen("max. sequence number: %llu", ai->max_sqnum); 160062306a36Sopenharmony_ci 160162306a36Sopenharmony_ci err = ubi_read_volume_table(ubi, ai); 160262306a36Sopenharmony_ci if (err) 160362306a36Sopenharmony_ci goto out_ai; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci err = ubi_wl_init(ubi, ai); 160662306a36Sopenharmony_ci if (err) 160762306a36Sopenharmony_ci goto out_vtbl; 160862306a36Sopenharmony_ci 160962306a36Sopenharmony_ci err = ubi_eba_init(ubi, ai); 161062306a36Sopenharmony_ci if (err) 161162306a36Sopenharmony_ci goto out_wl; 161262306a36Sopenharmony_ci 161362306a36Sopenharmony_ci#ifdef CONFIG_MTD_UBI_FASTMAP 161462306a36Sopenharmony_ci if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) { 161562306a36Sopenharmony_ci struct ubi_attach_info *scan_ai; 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_ci scan_ai = alloc_ai(); 161862306a36Sopenharmony_ci if (!scan_ai) { 161962306a36Sopenharmony_ci err = -ENOMEM; 162062306a36Sopenharmony_ci goto out_wl; 162162306a36Sopenharmony_ci } 162262306a36Sopenharmony_ci 162362306a36Sopenharmony_ci err = scan_all(ubi, scan_ai, 0); 162462306a36Sopenharmony_ci if (err) { 162562306a36Sopenharmony_ci destroy_ai(scan_ai); 162662306a36Sopenharmony_ci goto out_wl; 162762306a36Sopenharmony_ci } 162862306a36Sopenharmony_ci 162962306a36Sopenharmony_ci err = self_check_eba(ubi, ai, scan_ai); 163062306a36Sopenharmony_ci destroy_ai(scan_ai); 163162306a36Sopenharmony_ci 163262306a36Sopenharmony_ci if (err) 163362306a36Sopenharmony_ci goto out_wl; 163462306a36Sopenharmony_ci } 163562306a36Sopenharmony_ci#endif 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_ci destroy_ai(ai); 163862306a36Sopenharmony_ci return 0; 163962306a36Sopenharmony_ci 164062306a36Sopenharmony_ciout_wl: 164162306a36Sopenharmony_ci ubi_wl_close(ubi); 164262306a36Sopenharmony_ciout_vtbl: 164362306a36Sopenharmony_ci ubi_free_all_volumes(ubi); 164462306a36Sopenharmony_ci vfree(ubi->vtbl); 164562306a36Sopenharmony_ciout_ai: 164662306a36Sopenharmony_ci destroy_ai(ai); 164762306a36Sopenharmony_ci return err; 164862306a36Sopenharmony_ci} 164962306a36Sopenharmony_ci 165062306a36Sopenharmony_ci/** 165162306a36Sopenharmony_ci * self_check_ai - check the attaching information. 165262306a36Sopenharmony_ci * @ubi: UBI device description object 165362306a36Sopenharmony_ci * @ai: attaching information 165462306a36Sopenharmony_ci * 165562306a36Sopenharmony_ci * This function returns zero if the attaching information is all right, and a 165662306a36Sopenharmony_ci * negative error code if not or if an error occurred. 165762306a36Sopenharmony_ci */ 165862306a36Sopenharmony_cistatic int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) 165962306a36Sopenharmony_ci{ 166062306a36Sopenharmony_ci struct ubi_vid_io_buf *vidb = ai->vidb; 166162306a36Sopenharmony_ci struct ubi_vid_hdr *vidh = ubi_get_vid_hdr(vidb); 166262306a36Sopenharmony_ci int pnum, err, vols_found = 0; 166362306a36Sopenharmony_ci struct rb_node *rb1, *rb2; 166462306a36Sopenharmony_ci struct ubi_ainf_volume *av; 166562306a36Sopenharmony_ci struct ubi_ainf_peb *aeb, *last_aeb; 166662306a36Sopenharmony_ci uint8_t *buf; 166762306a36Sopenharmony_ci 166862306a36Sopenharmony_ci if (!ubi_dbg_chk_gen(ubi)) 166962306a36Sopenharmony_ci return 0; 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci /* 167262306a36Sopenharmony_ci * At first, check that attaching information is OK. 167362306a36Sopenharmony_ci */ 167462306a36Sopenharmony_ci ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { 167562306a36Sopenharmony_ci int leb_count = 0; 167662306a36Sopenharmony_ci 167762306a36Sopenharmony_ci cond_resched(); 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci vols_found += 1; 168062306a36Sopenharmony_ci 168162306a36Sopenharmony_ci if (ai->is_empty) { 168262306a36Sopenharmony_ci ubi_err(ubi, "bad is_empty flag"); 168362306a36Sopenharmony_ci goto bad_av; 168462306a36Sopenharmony_ci } 168562306a36Sopenharmony_ci 168662306a36Sopenharmony_ci if (av->vol_id < 0 || av->highest_lnum < 0 || 168762306a36Sopenharmony_ci av->leb_count < 0 || av->vol_type < 0 || av->used_ebs < 0 || 168862306a36Sopenharmony_ci av->data_pad < 0 || av->last_data_size < 0) { 168962306a36Sopenharmony_ci ubi_err(ubi, "negative values"); 169062306a36Sopenharmony_ci goto bad_av; 169162306a36Sopenharmony_ci } 169262306a36Sopenharmony_ci 169362306a36Sopenharmony_ci if (av->vol_id >= UBI_MAX_VOLUMES && 169462306a36Sopenharmony_ci av->vol_id < UBI_INTERNAL_VOL_START) { 169562306a36Sopenharmony_ci ubi_err(ubi, "bad vol_id"); 169662306a36Sopenharmony_ci goto bad_av; 169762306a36Sopenharmony_ci } 169862306a36Sopenharmony_ci 169962306a36Sopenharmony_ci if (av->vol_id > ai->highest_vol_id) { 170062306a36Sopenharmony_ci ubi_err(ubi, "highest_vol_id is %d, but vol_id %d is there", 170162306a36Sopenharmony_ci ai->highest_vol_id, av->vol_id); 170262306a36Sopenharmony_ci goto out; 170362306a36Sopenharmony_ci } 170462306a36Sopenharmony_ci 170562306a36Sopenharmony_ci if (av->vol_type != UBI_DYNAMIC_VOLUME && 170662306a36Sopenharmony_ci av->vol_type != UBI_STATIC_VOLUME) { 170762306a36Sopenharmony_ci ubi_err(ubi, "bad vol_type"); 170862306a36Sopenharmony_ci goto bad_av; 170962306a36Sopenharmony_ci } 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_ci if (av->data_pad > ubi->leb_size / 2) { 171262306a36Sopenharmony_ci ubi_err(ubi, "bad data_pad"); 171362306a36Sopenharmony_ci goto bad_av; 171462306a36Sopenharmony_ci } 171562306a36Sopenharmony_ci 171662306a36Sopenharmony_ci last_aeb = NULL; 171762306a36Sopenharmony_ci ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) { 171862306a36Sopenharmony_ci cond_resched(); 171962306a36Sopenharmony_ci 172062306a36Sopenharmony_ci last_aeb = aeb; 172162306a36Sopenharmony_ci leb_count += 1; 172262306a36Sopenharmony_ci 172362306a36Sopenharmony_ci if (aeb->pnum < 0 || aeb->ec < 0) { 172462306a36Sopenharmony_ci ubi_err(ubi, "negative values"); 172562306a36Sopenharmony_ci goto bad_aeb; 172662306a36Sopenharmony_ci } 172762306a36Sopenharmony_ci 172862306a36Sopenharmony_ci if (aeb->ec < ai->min_ec) { 172962306a36Sopenharmony_ci ubi_err(ubi, "bad ai->min_ec (%d), %d found", 173062306a36Sopenharmony_ci ai->min_ec, aeb->ec); 173162306a36Sopenharmony_ci goto bad_aeb; 173262306a36Sopenharmony_ci } 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_ci if (aeb->ec > ai->max_ec) { 173562306a36Sopenharmony_ci ubi_err(ubi, "bad ai->max_ec (%d), %d found", 173662306a36Sopenharmony_ci ai->max_ec, aeb->ec); 173762306a36Sopenharmony_ci goto bad_aeb; 173862306a36Sopenharmony_ci } 173962306a36Sopenharmony_ci 174062306a36Sopenharmony_ci if (aeb->pnum >= ubi->peb_count) { 174162306a36Sopenharmony_ci ubi_err(ubi, "too high PEB number %d, total PEBs %d", 174262306a36Sopenharmony_ci aeb->pnum, ubi->peb_count); 174362306a36Sopenharmony_ci goto bad_aeb; 174462306a36Sopenharmony_ci } 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_ci if (av->vol_type == UBI_STATIC_VOLUME) { 174762306a36Sopenharmony_ci if (aeb->lnum >= av->used_ebs) { 174862306a36Sopenharmony_ci ubi_err(ubi, "bad lnum or used_ebs"); 174962306a36Sopenharmony_ci goto bad_aeb; 175062306a36Sopenharmony_ci } 175162306a36Sopenharmony_ci } else { 175262306a36Sopenharmony_ci if (av->used_ebs != 0) { 175362306a36Sopenharmony_ci ubi_err(ubi, "non-zero used_ebs"); 175462306a36Sopenharmony_ci goto bad_aeb; 175562306a36Sopenharmony_ci } 175662306a36Sopenharmony_ci } 175762306a36Sopenharmony_ci 175862306a36Sopenharmony_ci if (aeb->lnum > av->highest_lnum) { 175962306a36Sopenharmony_ci ubi_err(ubi, "incorrect highest_lnum or lnum"); 176062306a36Sopenharmony_ci goto bad_aeb; 176162306a36Sopenharmony_ci } 176262306a36Sopenharmony_ci } 176362306a36Sopenharmony_ci 176462306a36Sopenharmony_ci if (av->leb_count != leb_count) { 176562306a36Sopenharmony_ci ubi_err(ubi, "bad leb_count, %d objects in the tree", 176662306a36Sopenharmony_ci leb_count); 176762306a36Sopenharmony_ci goto bad_av; 176862306a36Sopenharmony_ci } 176962306a36Sopenharmony_ci 177062306a36Sopenharmony_ci if (!last_aeb) 177162306a36Sopenharmony_ci continue; 177262306a36Sopenharmony_ci 177362306a36Sopenharmony_ci aeb = last_aeb; 177462306a36Sopenharmony_ci 177562306a36Sopenharmony_ci if (aeb->lnum != av->highest_lnum) { 177662306a36Sopenharmony_ci ubi_err(ubi, "bad highest_lnum"); 177762306a36Sopenharmony_ci goto bad_aeb; 177862306a36Sopenharmony_ci } 177962306a36Sopenharmony_ci } 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_ci if (vols_found != ai->vols_found) { 178262306a36Sopenharmony_ci ubi_err(ubi, "bad ai->vols_found %d, should be %d", 178362306a36Sopenharmony_ci ai->vols_found, vols_found); 178462306a36Sopenharmony_ci goto out; 178562306a36Sopenharmony_ci } 178662306a36Sopenharmony_ci 178762306a36Sopenharmony_ci /* Check that attaching information is correct */ 178862306a36Sopenharmony_ci ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { 178962306a36Sopenharmony_ci last_aeb = NULL; 179062306a36Sopenharmony_ci ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) { 179162306a36Sopenharmony_ci int vol_type; 179262306a36Sopenharmony_ci 179362306a36Sopenharmony_ci cond_resched(); 179462306a36Sopenharmony_ci 179562306a36Sopenharmony_ci last_aeb = aeb; 179662306a36Sopenharmony_ci 179762306a36Sopenharmony_ci err = ubi_io_read_vid_hdr(ubi, aeb->pnum, vidb, 1); 179862306a36Sopenharmony_ci if (err && err != UBI_IO_BITFLIPS) { 179962306a36Sopenharmony_ci ubi_err(ubi, "VID header is not OK (%d)", 180062306a36Sopenharmony_ci err); 180162306a36Sopenharmony_ci if (err > 0) 180262306a36Sopenharmony_ci err = -EIO; 180362306a36Sopenharmony_ci return err; 180462306a36Sopenharmony_ci } 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_ci vol_type = vidh->vol_type == UBI_VID_DYNAMIC ? 180762306a36Sopenharmony_ci UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; 180862306a36Sopenharmony_ci if (av->vol_type != vol_type) { 180962306a36Sopenharmony_ci ubi_err(ubi, "bad vol_type"); 181062306a36Sopenharmony_ci goto bad_vid_hdr; 181162306a36Sopenharmony_ci } 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_ci if (aeb->sqnum != be64_to_cpu(vidh->sqnum)) { 181462306a36Sopenharmony_ci ubi_err(ubi, "bad sqnum %llu", aeb->sqnum); 181562306a36Sopenharmony_ci goto bad_vid_hdr; 181662306a36Sopenharmony_ci } 181762306a36Sopenharmony_ci 181862306a36Sopenharmony_ci if (av->vol_id != be32_to_cpu(vidh->vol_id)) { 181962306a36Sopenharmony_ci ubi_err(ubi, "bad vol_id %d", av->vol_id); 182062306a36Sopenharmony_ci goto bad_vid_hdr; 182162306a36Sopenharmony_ci } 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_ci if (av->compat != vidh->compat) { 182462306a36Sopenharmony_ci ubi_err(ubi, "bad compat %d", vidh->compat); 182562306a36Sopenharmony_ci goto bad_vid_hdr; 182662306a36Sopenharmony_ci } 182762306a36Sopenharmony_ci 182862306a36Sopenharmony_ci if (aeb->lnum != be32_to_cpu(vidh->lnum)) { 182962306a36Sopenharmony_ci ubi_err(ubi, "bad lnum %d", aeb->lnum); 183062306a36Sopenharmony_ci goto bad_vid_hdr; 183162306a36Sopenharmony_ci } 183262306a36Sopenharmony_ci 183362306a36Sopenharmony_ci if (av->used_ebs != be32_to_cpu(vidh->used_ebs)) { 183462306a36Sopenharmony_ci ubi_err(ubi, "bad used_ebs %d", av->used_ebs); 183562306a36Sopenharmony_ci goto bad_vid_hdr; 183662306a36Sopenharmony_ci } 183762306a36Sopenharmony_ci 183862306a36Sopenharmony_ci if (av->data_pad != be32_to_cpu(vidh->data_pad)) { 183962306a36Sopenharmony_ci ubi_err(ubi, "bad data_pad %d", av->data_pad); 184062306a36Sopenharmony_ci goto bad_vid_hdr; 184162306a36Sopenharmony_ci } 184262306a36Sopenharmony_ci } 184362306a36Sopenharmony_ci 184462306a36Sopenharmony_ci if (!last_aeb) 184562306a36Sopenharmony_ci continue; 184662306a36Sopenharmony_ci 184762306a36Sopenharmony_ci if (av->highest_lnum != be32_to_cpu(vidh->lnum)) { 184862306a36Sopenharmony_ci ubi_err(ubi, "bad highest_lnum %d", av->highest_lnum); 184962306a36Sopenharmony_ci goto bad_vid_hdr; 185062306a36Sopenharmony_ci } 185162306a36Sopenharmony_ci 185262306a36Sopenharmony_ci if (av->last_data_size != be32_to_cpu(vidh->data_size)) { 185362306a36Sopenharmony_ci ubi_err(ubi, "bad last_data_size %d", 185462306a36Sopenharmony_ci av->last_data_size); 185562306a36Sopenharmony_ci goto bad_vid_hdr; 185662306a36Sopenharmony_ci } 185762306a36Sopenharmony_ci } 185862306a36Sopenharmony_ci 185962306a36Sopenharmony_ci /* 186062306a36Sopenharmony_ci * Make sure that all the physical eraseblocks are in one of the lists 186162306a36Sopenharmony_ci * or trees. 186262306a36Sopenharmony_ci */ 186362306a36Sopenharmony_ci buf = kzalloc(ubi->peb_count, GFP_KERNEL); 186462306a36Sopenharmony_ci if (!buf) 186562306a36Sopenharmony_ci return -ENOMEM; 186662306a36Sopenharmony_ci 186762306a36Sopenharmony_ci for (pnum = 0; pnum < ubi->peb_count; pnum++) { 186862306a36Sopenharmony_ci err = ubi_io_is_bad(ubi, pnum); 186962306a36Sopenharmony_ci if (err < 0) { 187062306a36Sopenharmony_ci kfree(buf); 187162306a36Sopenharmony_ci return err; 187262306a36Sopenharmony_ci } else if (err) 187362306a36Sopenharmony_ci buf[pnum] = 1; 187462306a36Sopenharmony_ci } 187562306a36Sopenharmony_ci 187662306a36Sopenharmony_ci ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) 187762306a36Sopenharmony_ci ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) 187862306a36Sopenharmony_ci buf[aeb->pnum] = 1; 187962306a36Sopenharmony_ci 188062306a36Sopenharmony_ci list_for_each_entry(aeb, &ai->free, u.list) 188162306a36Sopenharmony_ci buf[aeb->pnum] = 1; 188262306a36Sopenharmony_ci 188362306a36Sopenharmony_ci list_for_each_entry(aeb, &ai->corr, u.list) 188462306a36Sopenharmony_ci buf[aeb->pnum] = 1; 188562306a36Sopenharmony_ci 188662306a36Sopenharmony_ci list_for_each_entry(aeb, &ai->erase, u.list) 188762306a36Sopenharmony_ci buf[aeb->pnum] = 1; 188862306a36Sopenharmony_ci 188962306a36Sopenharmony_ci list_for_each_entry(aeb, &ai->alien, u.list) 189062306a36Sopenharmony_ci buf[aeb->pnum] = 1; 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_ci err = 0; 189362306a36Sopenharmony_ci for (pnum = 0; pnum < ubi->peb_count; pnum++) 189462306a36Sopenharmony_ci if (!buf[pnum]) { 189562306a36Sopenharmony_ci ubi_err(ubi, "PEB %d is not referred", pnum); 189662306a36Sopenharmony_ci err = 1; 189762306a36Sopenharmony_ci } 189862306a36Sopenharmony_ci 189962306a36Sopenharmony_ci kfree(buf); 190062306a36Sopenharmony_ci if (err) 190162306a36Sopenharmony_ci goto out; 190262306a36Sopenharmony_ci return 0; 190362306a36Sopenharmony_ci 190462306a36Sopenharmony_cibad_aeb: 190562306a36Sopenharmony_ci ubi_err(ubi, "bad attaching information about LEB %d", aeb->lnum); 190662306a36Sopenharmony_ci ubi_dump_aeb(aeb, 0); 190762306a36Sopenharmony_ci ubi_dump_av(av); 190862306a36Sopenharmony_ci goto out; 190962306a36Sopenharmony_ci 191062306a36Sopenharmony_cibad_av: 191162306a36Sopenharmony_ci ubi_err(ubi, "bad attaching information about volume %d", av->vol_id); 191262306a36Sopenharmony_ci ubi_dump_av(av); 191362306a36Sopenharmony_ci goto out; 191462306a36Sopenharmony_ci 191562306a36Sopenharmony_cibad_vid_hdr: 191662306a36Sopenharmony_ci ubi_err(ubi, "bad attaching information about volume %d", av->vol_id); 191762306a36Sopenharmony_ci ubi_dump_av(av); 191862306a36Sopenharmony_ci ubi_dump_vid_hdr(vidh); 191962306a36Sopenharmony_ci 192062306a36Sopenharmony_ciout: 192162306a36Sopenharmony_ci dump_stack(); 192262306a36Sopenharmony_ci return -EINVAL; 192362306a36Sopenharmony_ci} 1924