1925 lines · 51.5 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* * Copyright (c) International Business Machines Corp., 2006 * * Author: Artem Bityutskiy (Битюцкий Артём) */ /* * UBI attaching sub-system. * * This sub-system is responsible for attaching MTD devices and it also * implements flash media scanning. * * The attaching information is represented by a &struct ubi_attach_info' * object. Information about volumes is represented by &struct ubi_ainf_volume * objects which are kept in volume RB-tree with root at the @volumes field. * The RB-tree is indexed by the volume ID. * * Logical eraseblocks are represented by &struct ubi_ainf_peb objects. These * objects are kept in per-volume RB-trees with the root at the corresponding * &struct ubi_ainf_volume object. To put it differently, we keep an RB-tree of * per-volume objects and each of these objects is the root of RB-tree of * per-LEB objects. * * Corrupted physical eraseblocks are put to the @corr list, free physical * eraseblocks are put to the @free list and the physical eraseblock to be * erased are put to the @erase list. * * About corruptions * ~~~~~~~~~~~~~~~~~ * * UBI protects EC and VID headers with CRC-32 checksums, so it can detect * whether the headers are corrupted or not. Sometimes UBI also protects the * data with CRC-32, e.g., when it executes the atomic LEB change operation, or * when it moves the contents of a PEB for wear-leveling purposes. * * UBI tries to distinguish between 2 types of corruptions. * * 1. Corruptions caused by power cuts. These are expected corruptions and UBI * tries to handle them gracefully, without printing too many warnings and * error messages. The idea is that we do not lose important data in these * cases - we may lose only the data which were being written to the media just * before the power cut happened, and the upper layers (e.g., UBIFS) are * supposed to handle such data losses (e.g., by using the FS journal). * * When UBI detects a corruption (CRC-32 mismatch) in a PEB, and it looks like * the reason is a power cut, UBI puts this PEB to the @erase list, and all * PEBs in the @erase list are scheduled for erasure later. * * 2. Unexpected corruptions which are not caused by power cuts. During * attaching, such PEBs are put to the @corr list and UBI preserves them. * Obviously, this lessens the amount of available PEBs, and if at some  point * UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly informs * about such PEBs every time the MTD device is attached. * * However, it is difficult to reliably distinguish between these types of * corruptions and UBI's strategy is as follows (in case of attaching by * scanning). UBI assumes corruption type 2 if the VID header is corrupted and * the data area does not contain all 0xFFs, and there were no bit-flips or * integrity errors (e.g., ECC errors in case of NAND) while reading the data * area.  Otherwise UBI assumes corruption type 1. So the decision criteria * are as follows. *   o If the data area contains only 0xFFs, there are no data, and it is safe *     to just erase this PEB - this is corruption type 1. *   o If the data area has bit-flips or data integrity errors (ECC errors on *     NAND), it is probably a PEB which was being erased when power cut *     happened, so this is corruption type 1. However, this is just a guess, *     which might be wrong. *   o Otherwise this is corruption type 2. */ #include <linux/err.h>#include <linux/slab.h>#include <linux/crc32.h>#include <linux/math64.h>#include <linux/random.h>#include "ubi.h" static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai); #define AV_FIND		BIT(0)#define AV_ADD		BIT(1)#define AV_FIND_OR_ADD	(AV_FIND | AV_ADD) /** * find_or_add_av - internal function to find a volume, add a volume or do *		    both (find and add if missing). * @ai: attaching information * @vol_id: the requested volume ID * @flags: a combination of the %AV_FIND and %AV_ADD flags describing the *	   expected operation. If only %AV_ADD is set, -EEXIST is returned *	   if the volume already exists. If only %AV_FIND is set, NULL is *	   returned if the volume does not exist. And if both flags are *	   set, the helper first tries to find an existing volume, and if *	   it does not exist it creates a new one. * @created: in value used to inform the caller whether it"s a newly created *	     volume or not. * * This function returns a pointer to a volume description or an ERR_PTR if * the operation failed. It can also return NULL if only %AV_FIND is set and * the volume does not exist. */static struct ubi_ainf_volume *find_or_add_av(struct ubi_attach_info *ai,					      int vol_id, unsigned int flags,					      bool *created){	struct ubi_ainf_volume *av;	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; 	/* Walk the volume RB-tree to look if this volume is already present */	while (*p) {		parent = *p;		av = rb_entry(parent, struct ubi_ainf_volume, rb); 		if (vol_id == av->vol_id) {			*created = false; 			if (!(flags & AV_FIND))				return ERR_PTR(-EEXIST); 			return av;		} 		if (vol_id > av->vol_id)			p = &(*p)->rb_left;		else			p = &(*p)->rb_right;	} 	if (!(flags & AV_ADD))		return NULL; 	/* The volume is absent - add it */	av = kzalloc_obj(*av);	if (!av)		return ERR_PTR(-ENOMEM); 	av->vol_id = vol_id; 	if (vol_id > ai->highest_vol_id)		ai->highest_vol_id = vol_id; 	rb_link_node(&av->rb, parent, p);	rb_insert_color(&av->rb, &ai->volumes);	ai->vols_found += 1;	*created = true;	dbg_bld("added volume %d", vol_id);	return av;} /** * ubi_find_or_add_av - search for a volume in the attaching information and *			add one if it does not exist. * @ai: attaching information * @vol_id: the requested volume ID * @created: whether the volume has been created or not * * This function returns a pointer to the new volume description or an * ERR_PTR if the operation failed. */static struct ubi_ainf_volume *ubi_find_or_add_av(struct ubi_attach_info *ai,						  int vol_id, bool *created){	return find_or_add_av(ai, vol_id, AV_FIND_OR_ADD, created);} /** * ubi_alloc_aeb - allocate an aeb element * @ai: attaching information * @pnum: physical eraseblock number * @ec: erase counter of the physical eraseblock * * Allocate an aeb object and initialize the pnum and ec information. * vol_id and lnum are set to UBI_UNKNOWN, and the other fields are * initialized to zero. * Note that the element is not added in any list or RB tree. */struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum,				   int ec){	struct ubi_ainf_peb *aeb; 	aeb = kmem_cache_zalloc(ai->aeb_slab_cache, GFP_KERNEL);	if (!aeb)		return NULL; 	aeb->pnum = pnum;	aeb->ec = ec;	aeb->vol_id = UBI_UNKNOWN;	aeb->lnum = UBI_UNKNOWN; 	return aeb;} /** * ubi_free_aeb - free an aeb element * @ai: attaching information * @aeb: the element to free * * Free an aeb object. The caller must have removed the element from any list * or RB tree. */void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb){	kmem_cache_free(ai->aeb_slab_cache, aeb);} /** * add_to_list - add physical eraseblock to a list. * @ai: attaching information * @pnum: physical eraseblock number to add * @vol_id: the last used volume id for the PEB * @lnum: the last used LEB number for the PEB * @ec: erase counter of the physical eraseblock * @to_head: if not zero, add to the head of the list * @list: the list to add to * * This function allocates a 'struct ubi_ainf_peb' object for physical * eraseblock @pnum and adds it to the "free", "erase", or "alien" lists. * It stores the @lnum and @vol_id alongside, which can both be * %UBI_UNKNOWN if they are not available, not readable, or not assigned. * If @to_head is not zero, PEB will be added to the head of the list, which * basically means it will be processed first later. E.g., we add corrupted * PEBs (corrupted due to power cuts) to the head of the erase list to make * sure we erase them first and get rid of corruptions ASAP. This function * returns zero in case of success and a negative error code in case of * failure. */static int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id,		       int lnum, int ec, int to_head, struct list_head *list){	struct ubi_ainf_peb *aeb; 	if (list == &ai->free) {		dbg_bld("add to free: PEB %d, EC %d", pnum, ec);	} else if (list == &ai->erase) {		dbg_bld("add to erase: PEB %d, EC %d", pnum, ec);	} else if (list == &ai->alien) {		dbg_bld("add to alien: PEB %d, EC %d", pnum, ec);		ai->alien_peb_count += 1;	} else		BUG(); 	aeb = ubi_alloc_aeb(ai, pnum, ec);	if (!aeb)		return -ENOMEM; 	aeb->vol_id = vol_id;	aeb->lnum = lnum;	if (to_head)		list_add(&aeb->u.list, list);	else		list_add_tail(&aeb->u.list, list);	return 0;} /** * add_corrupted - add a corrupted physical eraseblock. * @ai: attaching information * @pnum: physical eraseblock number to add * @ec: erase counter of the physical eraseblock * * This function allocates a 'struct ubi_ainf_peb' object for a corrupted * physical eraseblock @pnum and adds it to the 'corr' list.  The corruption * was presumably not caused by a power cut. Returns zero in case of success * and a negative error code in case of failure. */static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec){	struct ubi_ainf_peb *aeb; 	dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); 	aeb = ubi_alloc_aeb(ai, pnum, ec);	if (!aeb)		return -ENOMEM; 	ai->corr_peb_count += 1;	list_add(&aeb->u.list, &ai->corr);	return 0;} /** * add_fastmap - add a Fastmap related physical eraseblock. * @ai: attaching information * @pnum: physical eraseblock number the VID header came from * @vid_hdr: the volume identifier header * @ec: erase counter of the physical eraseblock * * This function allocates a 'struct ubi_ainf_peb' object for a Fastamp * physical eraseblock @pnum and adds it to the 'fastmap' list. * Such blocks can be Fastmap super and data blocks from both the most * recent Fastmap we're attaching from or from old Fastmaps which will * be erased. */static int add_fastmap(struct ubi_attach_info *ai, int pnum,		       struct ubi_vid_hdr *vid_hdr, int ec){	struct ubi_ainf_peb *aeb; 	aeb = ubi_alloc_aeb(ai, pnum, ec);	if (!aeb)		return -ENOMEM; 	aeb->vol_id = be32_to_cpu(vid_hdr->vol_id);	aeb->sqnum = be64_to_cpu(vid_hdr->sqnum);	list_add(&aeb->u.list, &ai->fastmap); 	dbg_bld("add to fastmap list: PEB %d, vol_id %d, sqnum: %llu", pnum,		aeb->vol_id, aeb->sqnum); 	return 0;} /** * validate_vid_hdr - check volume identifier header. * @ubi: UBI device description object * @vid_hdr: the volume identifier header to check * @av: information about the volume this logical eraseblock belongs to * @pnum: physical eraseblock number the VID header came from * * This function checks that data stored in @vid_hdr is consistent. Returns * non-zero if an inconsistency was found and zero if not. * * Note, UBI does sanity check of everything it reads from the flash media. * Most of the checks are done in the I/O sub-system. Here we check that the * information in the VID header is consistent to the information in other VID * headers of the same volume. */static int validate_vid_hdr(const struct ubi_device *ubi,			    const struct ubi_vid_hdr *vid_hdr,			    const struct ubi_ainf_volume *av, int pnum){	int vol_type = vid_hdr->vol_type;	int vol_id = be32_to_cpu(vid_hdr->vol_id);	int used_ebs = be32_to_cpu(vid_hdr->used_ebs);	int data_pad = be32_to_cpu(vid_hdr->data_pad); 	if (av->leb_count != 0) {		int av_vol_type; 		/*		 * This is not the first logical eraseblock belonging to this		 * volume. Ensure that the data in its VID header is consistent		 * to the data in previous logical eraseblock headers.		 */ 		if (vol_id != av->vol_id) {			ubi_err(ubi, "inconsistent vol_id");			goto bad;		} 		if (av->vol_type == UBI_STATIC_VOLUME)			av_vol_type = UBI_VID_STATIC;		else			av_vol_type = UBI_VID_DYNAMIC; 		if (vol_type != av_vol_type) {			ubi_err(ubi, "inconsistent vol_type");			goto bad;		} 		if (used_ebs != av->used_ebs) {			ubi_err(ubi, "inconsistent used_ebs");			goto bad;		} 		if (data_pad != av->data_pad) {			ubi_err(ubi, "inconsistent data_pad");			goto bad;		}	} 	return 0; bad:	ubi_err(ubi, "inconsistent VID header at PEB %d", pnum);	ubi_dump_vid_hdr(vid_hdr);	ubi_dump_av(av);	return -EINVAL;} /** * add_volume - add volume to the attaching information. * @ai: attaching information * @vol_id: ID of the volume to add * @pnum: physical eraseblock number * @vid_hdr: volume identifier header * * If the volume corresponding to the @vid_hdr logical eraseblock is already * present in the attaching information, this function does nothing. Otherwise * it adds corresponding volume to the attaching information. Returns a pointer * to the allocated "av" object in case of success and a negative error code in * case of failure. */static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai,					  int vol_id, int pnum,					  const struct ubi_vid_hdr *vid_hdr){	struct ubi_ainf_volume *av;	bool created; 	ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id)); 	av = ubi_find_or_add_av(ai, vol_id, &created);	if (IS_ERR(av) || !created)		return av; 	av->used_ebs = be32_to_cpu(vid_hdr->used_ebs);	av->data_pad = be32_to_cpu(vid_hdr->data_pad);	av->compat = vid_hdr->compat;	av->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME							    : UBI_STATIC_VOLUME; 	return av;} /** * ubi_compare_lebs - find out which logical eraseblock is newer. * @ubi: UBI device description object * @aeb: first logical eraseblock to compare * @pnum: physical eraseblock number of the second logical eraseblock to * compare * @vid_hdr: volume identifier header of the second logical eraseblock * * This function compares 2 copies of a LEB and informs which one is newer. In * case of success this function returns a positive value, in case of failure, a * negative error code is returned. The success return codes use the following * bits: *     o bit 0 is cleared: the first PEB (described by @aeb) is newer than the *       second PEB (described by @pnum and @vid_hdr); *     o bit 0 is set: the second PEB is newer; *     o bit 1 is cleared: no bit-flips were detected in the newer LEB; *     o bit 1 is set: bit-flips were detected in the newer LEB; *     o bit 2 is cleared: the older LEB is not corrupted; *     o bit 2 is set: the older LEB is corrupted. */int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,			int pnum, const struct ubi_vid_hdr *vid_hdr){	int len, err, second_is_newer, bitflips = 0, corrupted = 0;	uint32_t data_crc, crc;	struct ubi_vid_io_buf *vidb = NULL;	unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); 	if (sqnum2 == aeb->sqnum) {		/*		 * This must be a really ancient UBI image which has been		 * created before sequence numbers support has been added. At		 * that times we used 32-bit LEB versions stored in logical		 * eraseblocks. That was before UBI got into mainline. We do not		 * support these images anymore. Well, those images still work,		 * but only if no unclean reboots happened.		 */		ubi_err(ubi, "unsupported on-flash UBI format");		return -EINVAL;	} 	/* Obviously the LEB with lower sequence counter is older */	second_is_newer = (sqnum2 > aeb->sqnum); 	/*	 * Now we know which copy is newer. If the copy flag of the PEB with	 * newer version is not set, then we just return, otherwise we have to	 * check data CRC. For the second PEB we already have the VID header,	 * for the first one - we'll need to re-read it from flash.	 *	 * Note: this may be optimized so that we wouldn't read twice.	 */ 	if (second_is_newer) {		if (!vid_hdr->copy_flag) {			/* It is not a copy, so it is newer */			dbg_bld("second PEB %d is newer, copy_flag is unset",				pnum);			return 1;		}	} else {		if (!aeb->copy_flag) {			/* It is not a copy, so it is newer */			dbg_bld("first PEB %d is newer, copy_flag is unset",				pnum);			return bitflips << 1;		} 		vidb = ubi_alloc_vid_buf(ubi, GFP_KERNEL);		if (!vidb)			return -ENOMEM; 		pnum = aeb->pnum;		err = ubi_io_read_vid_hdr(ubi, pnum, vidb, 0);		if (err) {			if (err == UBI_IO_BITFLIPS)				bitflips = 1;			else {				ubi_err(ubi, "VID of PEB %d header is bad, but it was OK earlier, err %d",					pnum, err);				if (err > 0)					err = -EIO; 

Lines 1–500 of 1925.