/*
 * Copyright (c) 2012 Linutronix GmbH
 * Author: Richard Weinberger <richard@nod.at>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
 * the GNU General Public License for more details.
 *
 */

#include <linux/crc32.h>
#include "ubi.h"

/**
 * ubi_calc_fm_size - calculates the fastmap size in bytes for an UBI device.
 * @ubi: UBI device description object
 */
size_t ubi_calc_fm_size(struct ubi_device *ubi)
{
	size_t size;

	size = sizeof(struct ubi_fm_hdr) + \
		sizeof(struct ubi_fm_scan_pool) + \
		sizeof(struct ubi_fm_scan_pool) + \
		(ubi->peb_count * sizeof(struct ubi_fm_ec)) + \
		(sizeof(struct ubi_fm_eba) + \
		(ubi->peb_count * sizeof(__be32))) + \
		sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
	return roundup(size, ubi->leb_size);
}


/**
 * new_fm_vhdr - allocate a new volume header for fastmap usage.
 * @ubi: UBI device description object
 * @vol_id: the VID of the new header
 *
 * Returns a new struct ubi_vid_hdr on success.
 * NULL indicates out of memory.
 */
static struct ubi_vid_hdr *new_fm_vhdr(struct ubi_device *ubi, int vol_id)
{
	struct ubi_vid_hdr *new;

	new = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
	if (!new)
		goto out;

	new->vol_type = UBI_VID_DYNAMIC;
	new->vol_id = cpu_to_be32(vol_id);

	/* UBI implementations without fastmap support have to delete the
	 * fastmap.
	 */
	new->compat = UBI_COMPAT_DELETE;

out:
	return new;
}

/**
 * add_aeb - create and add a attach erase block to a given list.
 * @ai: UBI attach info object
 * @list: the target list
 * @pnum: PEB number of the new attach erase block
 * @ec: erease counter of the new LEB
 * @scrub: scrub this PEB after attaching
 *
 * Returns 0 on success, < 0 indicates an internal error.
 */
static int add_aeb(struct ubi_attach_info *ai, struct list_head *list,
		   int pnum, int ec, int scrub)
{
	struct ubi_ainf_peb *aeb;

	aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
	if (!aeb)
		return -ENOMEM;

	aeb->pnum = pnum;
	aeb->ec = ec;
	aeb->lnum = -1;
	aeb->scrub = scrub;
	aeb->copy_flag = aeb->sqnum = 0;

	ai->ec_sum += aeb->ec;
	ai->ec_count++;

	if (ai->max_ec < aeb->ec)
		ai->max_ec = aeb->ec;

	if (ai->min_ec > aeb->ec)
		ai->min_ec = aeb->ec;

	list_add_tail(&aeb->u.list, list);

	return 0;
}

/**
 * add_vol - create and add a new volume to ubi_attach_info.
 * @ai: ubi_attach_info object
 * @vol_id: VID of the new volume
 * @used_ebs: number of used EBS
 * @data_pad: data padding value of the new volume
 * @vol_type: volume type
 * @last_eb_bytes: number of bytes in the last LEB
 *
 * Returns the new struct ubi_ainf_volume on success.
 * NULL indicates an error.
 */
static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id,
				       int used_ebs, int data_pad, u8 vol_type,
				       int last_eb_bytes)
{
	struct ubi_ainf_volume *av;
	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;

	while (*p) {
		parent = *p;
		av = rb_entry(parent, struct ubi_ainf_volume, rb);

		if (vol_id < av->vol_id)
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}

	av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL);
	if (!av)
		goto out;

	av->highest_lnum = av->leb_count = 0;
	av->vol_id = vol_id;
	av->used_ebs = used_ebs;
	av->data_pad = data_pad;
	av->last_data_size = last_eb_bytes;
	av->compat = 0;
	av->vol_type = vol_type;
	av->root = RB_ROOT;

	dbg_bld("found volume (ID %i)", vol_id);

	rb_link_node(&av->rb, parent, p);
	rb_insert_color(&av->rb, &ai->volumes);

out:
	return av;
}

/**
 * assign_aeb_to_av - assigns a SEB to a given ainf_volume and removes it
 * from it's original list.
 * @ai: ubi_attach_info object
 * @aeb: the to be assigned SEB
 * @av: target scan volume
 */
static void assign_aeb_to_av(struct ubi_attach_info *ai,
			     struct ubi_ainf_peb *aeb,
			     struct ubi_ainf_volume *av)
{
	struct ubi_ainf_peb *tmp_aeb;
	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;

	p = &av->root.rb_node;
	while (*p) {
		parent = *p;

		tmp_aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb);
		if (aeb->lnum != tmp_aeb->lnum) {
			if (aeb->lnum < tmp_aeb->lnum)
				p = &(*p)->rb_left;
			else
				p = &(*p)->rb_right;

			continue;
		} else
			break;
	}

	list_del(&aeb->u.list);
	av->leb_count++;

	rb_link_node(&aeb->u.rb, parent, p);
	rb_insert_color(&aeb->u.rb, &av->root);
}

/**
 * update_vol - inserts or updates a LEB which was found a pool.
 * @ubi: the UBI device object
 * @ai: attach info object
 * @av: the volume this LEB belongs to
 * @new_vh: the volume header derived from new_aeb
 * @new_aeb: the AEB to be examined
 *
 * Returns 0 on success, < 0 indicates an internal error.
 */
static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
		      struct ubi_ainf_volume *av, struct ubi_vid_hdr *new_vh,
		      struct ubi_ainf_peb *new_aeb)
{
	struct rb_node **p = &av->root.rb_node, *parent = NULL;
	struct ubi_ainf_peb *aeb, *victim;
	int cmp_res;

	while (*p) {
		parent = *p;
		aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb);

		if (be32_to_cpu(new_vh->lnum) != aeb->lnum) {
			if (be32_to_cpu(new_vh->lnum) < aeb->lnum)
				p = &(*p)->rb_left;
			else
				p = &(*p)->rb_right;

			continue;
		}

		/* This case can happen if the fastmap gets written
		 * because of a volume change (creation, deletion, ..).
		 * Then a PEB can be within the persistent EBA and the pool.
		 */
		if (aeb->pnum == new_aeb->pnum) {
			ubi_assert(aeb->lnum == new_aeb->lnum);
			kmem_cache_free(ai->aeb_slab_cache, new_aeb);

			return 0;
		}

		cmp_res = ubi_compare_lebs(ubi, aeb, new_aeb->pnum, new_vh);
		if (cmp_res < 0)
			return cmp_res;

		/* new_aeb is newer */
		if (cmp_res & 1) {
			victim = kmem_cache_alloc(ai->aeb_slab_cache,
				GFP_KERNEL);
			if (!victim)
				return -ENOMEM;

			victim->ec = aeb->ec;
			victim->pnum = aeb->pnum;
			list_add_tail(&victim->u.list, &ai->erase);

			if (av->highest_lnum == be32_to_cpu(new_vh->lnum))
				av->last_data_size = \
					be32_to_cpu(new_vh->data_size);

			dbg_bld("vol %i: AEB %i's PEB %i is the newer",
				av->vol_id, aeb->lnum, new_aeb->pnum);

			aeb->ec = new_aeb->ec;
			aeb->pnum = new_aeb->pnum;
			aeb->copy_flag = new_vh->copy_flag;
			aeb->scrub = new_aeb->scrub;
			kmem_cache_free(ai->aeb_slab_cache, new_aeb);

		/* new_aeb is older */
		} else {
			dbg_bld("vol %i: AEB %i's PEB %i is old, dropping it",
				av->vol_id, aeb->lnum, new_aeb->pnum);
			list_add_tail(&new_aeb->u.list, &ai->erase);
		}

		return 0;
	}
	/* This LEB is new, let's add it to the volume */

	if (av->highest_lnum <= be32_to_cpu(new_vh->lnum)) {
		av->highest_lnum = be32_to_cpu(new_vh->lnum);
		av->last_data_size = be32_to_cpu(new_vh->data_size);
	}

	if (av->vol_type == UBI_STATIC_VOLUME)
		av->used_ebs = be32_to_cpu(new_vh->used_ebs);

	av->leb_count++;

	rb_link_node(&new_aeb->u.rb, parent, p);
	rb_insert_color(&new_aeb->u.rb, &av->root);

	return 0;
}

/**
 * process_pool_aeb - we found a non-empty PEB in a pool.
 * @ubi: UBI device object
 * @ai: attach info object
 * @new_vh: the volume header derived from new_aeb
 * @new_aeb: the AEB to be examined
 *
 * Returns 0 on success, < 0 indicates an internal error.
 */
static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai,
			    struct ubi_vid_hdr *new_vh,
			    struct ubi_ainf_peb *new_aeb)
{
	struct ubi_ainf_volume *av, *tmp_av = NULL;
	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
	int found = 0;

	if (be32_to_cpu(new_vh->vol_id) == UBI_FM_SB_VOLUME_ID ||
		be32_to_cpu(new_vh->vol_id) == UBI_FM_DATA_VOLUME_ID) {
		kmem_cache_free(ai->aeb_slab_cache, new_aeb);

		return 0;
	}

	/* Find the volume this SEB belongs to */
	while (*p) {
		parent = *p;
		tmp_av = rb_entry(parent, struct ubi_ainf_volume, rb);

		if (be32_to_cpu(new_vh->vol_id) > tmp_av->vol_id)
			p = &(*p)->rb_left;
		else if (be32_to_cpu(new_vh->vol_id) < tmp_av->vol_id)
			p = &(*p)->rb_right;
		else {
			found = 1;
			break;
		}
	}

	if (found)
		av = tmp_av;
	else {
		ubi_err("orphaned volume in fastmap pool!");
		return UBI_BAD_FASTMAP;
	}

	ubi_assert(be32_to_cpu(new_vh->vol_id) == av->vol_id);

	return update_vol(ubi, ai, av, new_vh, new_aeb);
}

/**
 * unmap_peb - unmap a PEB.
 * If fastmap detects a free PEB in the pool it has to check whether
 * this PEB has been unmapped after writing the fastmap.
 *
 * @ai: UBI attach info object
 * @pnum: The PEB to be unmapped
 */
static void unmap_peb(struct ubi_attach_info *ai, int pnum)
{
	struct ubi_ainf_volume *av;
	struct rb_node *node, *node2;
	struct ubi_ainf_peb *aeb;

	for (node = rb_first(&ai->volumes); node; node = rb_next(node)) {
		av = rb_entry(node, struct ubi_ainf_volume, rb);

		for (node2 = rb_first(&av->root); node2;
		     node2 = rb_next(node2)) {
			aeb = rb_entry(node2, struct ubi_ainf_peb, u.rb);
			if (aeb->pnum == pnum) {
				rb_erase(&aeb->u.rb, &av->root);
				kmem_cache_free(ai->aeb_slab_cache, aeb);
				return;
			}
		}
	}
}

/**
 * scan_pool - scans a pool for changed (no longer empty PEBs).
 * @ubi: UBI device object
 * @ai: attach info object
 * @pebs: an array of all PEB numbers in the to be scanned pool
 * @pool_size: size of the pool (number of entries in @pebs)
 * @max_sqnum: pointer to the maximal sequence number
 * @eba_orphans: list of PEBs which need to be scanned
 * @free: list of PEBs which are most likely free (and go into @ai->free)
 *
 * Returns 0 on success, if the pool is unusable UBI_BAD_FASTMAP is returned.
 * < 0 indicates an internal error.
 */
static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
		     int *pebs, int pool_size, unsigned long long *max_sqnum,
		     struct list_head *eba_orphans, struct list_head *free)
{
	struct ubi_vid_hdr *vh;
	struct ubi_ec_hdr *ech;
	struct ubi_ainf_peb *new_aeb, *tmp_aeb;
	int i, pnum, err, found_orphan, ret = 0;

	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
	if (!ech)
		return -ENOMEM;

	vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
	if (!vh) {
		kfree(ech);
		return -ENOMEM;
	}

	dbg_bld("scanning fastmap pool: size = %i", pool_size);

	/*
	 * Now scan all PEBs in the pool to find changes which have been made
	 * after the creation of the fastmap
	 */
	for (i = 0; i < pool_size; i++) {
		int scrub = 0;
		int image_seq;

		pnum = be32_to_cpu(pebs[i]);

		if (ubi_io_is_bad(ubi, pnum)) {
			ubi_err("bad PEB in fastmap pool!");
			ret = UBI_BAD_FASTMAP;
			goto out;
		}

		err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
		if (err && err != UBI_IO_BITFLIPS) {
			ubi_err("unable to read EC header! PEB:%i err:%i",
				pnum, err);
			ret = err > 0 ? UBI_BAD_FASTMAP : err;
			goto out;
		} else if (ret == UBI_IO_BITFLIPS)
			scrub = 1;

		/*
		 * Older UBI implementations have image_seq set to zero, so
		 * we shouldn't fail if image_seq == 0.
		 */
		image_seq = be32_to_cpu(ech->image_seq);

		if (image_seq && (image_seq != ubi->image_seq)) {
			ubi_err("bad image seq: 0x%x, expected: 0x%x",
				be32_to_cpu(ech->image_seq), ubi->image_seq);
			ret = UBI_BAD_FASTMAP;
			goto out;
		}

		err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
		if (err == UBI_IO_FF || err == UBI_IO_FF_BITFLIPS) {
			unsigned long long ec = be64_to_cpu(ech->ec);
			unmap_peb(ai, pnum);
			dbg_bld("Adding PEB to free: %i", pnum);
			if (err == UBI_IO_FF_BITFLIPS)
				add_aeb(ai, free, pnum, ec, 1);
			else
				add_aeb(ai, free, pnum, ec, 0);
			continue;
		} else if (err == 0 || err == UBI_IO_BITFLIPS) {
			dbg_bld("Found non empty PEB:%i in pool", pnum);

			if (err == UBI_IO_BITFLIPS)
				scrub = 1;

			found_orphan = 0;
			list_for_each_entry(tmp_aeb, eba_orphans, u.list) {
				if (tmp_aeb->pnum == pnum) {
					found_orphan = 1;
					break;
				}
			}
			if (found_orphan) {
				list_del(&tmp_aeb->u.list);
				kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
			}

			new_aeb = kmem_cache_alloc(ai->aeb_slab_cache,
						   GFP_KERNEL);
			if (!new_aeb) {
				ret = -ENOMEM;
				goto out;
			}

			new_aeb->ec = be64_to_cpu(ech->ec);
			new_aeb->pnum = pnum;
			new_aeb->lnum = be32_to_cpu(vh->lnum);
			new_aeb->sqnum = be64_to_cpu(vh->sqnum);
			new_aeb->copy_flag = vh->copy_flag;
			new_aeb->scrub = scrub;

			if (*max_sqnum < new_aeb->sqnum)
				*max_sqnum = new_aeb->sqnum;

			err = process_pool_aeb(ubi, ai, vh, new_aeb);
			if (err) {
				ret = err > 0 ? UBI_BAD_FASTMAP : err;
				goto out;
			}
		} else {
			/* We are paranoid and fall back to scanning mode */
			ubi_err("fastmap pool PEBs contains damaged PEBs!");
			ret = err > 0 ? UBI_BAD_FASTMAP : err;
			goto out;
		}

	}

out:
	ubi_free_vid_hdr(ubi, vh);
	kfree(ech);
	return ret;
}

/**
 * count_fastmap_pebs - Counts the PEBs found by fastmap.
 * @ai: The UBI attach info object
 */
static int count_fastmap_pebs(struct ubi_attach_info *ai)
{
	struct ubi_ainf_peb *aeb;
	struct ubi_ainf_volume *av;
	struct rb_node *rb1, *rb2;
	int n = 0;

	list_for_each_entry(aeb, &ai->erase, u.list)
		n++;

	list_for_each_entry(aeb, &ai->free, u.list)
		n++;

	 ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb)
		ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb)
			n++;

	return n;
}

/**
 * ubi_attach_fastmap - creates ubi_attach_info from a fastmap.
 * @ubi: UBI device object
 * @ai: UBI attach info object
 * @fm: the fastmap to be attached
 *
 * Returns 0 on success, UBI_BAD_FASTMAP if the found fastmap was unusable.
 * < 0 indicates an internal error.
 */
static int ubi_attach_fastmap(struct ubi_device *ubi,
			      struct ubi_attach_info *ai,
			      struct ubi_fastmap_layout *fm)
{
	struct list_head used, eba_orphans, free;
	struct ubi_ainf_volume *av;
	struct ubi_ainf_peb *aeb, *tmp_aeb, *_tmp_aeb;
	struct ubi_ec_hdr *ech;
	struct ubi_fm_sb *fmsb;
	struct ubi_fm_hdr *fmhdr;
	struct ubi_fm_scan_pool *fmpl1, *fmpl2;
	struct ubi_fm_ec *fmec;
	struct ubi_fm_volhdr *fmvhdr;
	struct ubi_fm_eba *fm_eba;
	int ret, i, j, pool_size, wl_pool_size;
	size_t fm_pos = 0, fm_size = ubi->fm_size;
	unsigned long long max_sqnum = 0;
	void *fm_raw = ubi->fm_buf;

	INIT_LIST_HEAD(&used);
	INIT_LIST_HEAD(&free);
	INIT_LIST_HEAD(&eba_orphans);
	INIT_LIST_HEAD(&ai->corr);
	INIT_LIST_HEAD(&ai->free);
	INIT_LIST_HEAD(&ai->erase);
	INIT_LIST_HEAD(&ai->alien);
	ai->volumes = RB_ROOT;
	ai->min_ec = UBI_MAX_ERASECOUNTER;

	ai->aeb_slab_cache = kmem_cache_create("ubi_ainf_peb_slab",
					       sizeof(struct ubi_ainf_peb),
					       0, 0, NULL);
	if (!ai->aeb_slab_cache) {
		ret = -ENOMEM;
		goto fail;
	}

	fmsb = (struct ubi_fm_sb *)(fm_raw);
	ai->max_sqnum = fmsb->sqnum;
	fm_pos += sizeof(struct ubi_fm_sb);
	if (fm_pos >= fm_size)
		goto fail_bad;

	fmhdr = (struct ubi_fm_hdr *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmhdr);
	if (fm_pos >= fm_size)
		goto fail_bad;

	if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) {
		ubi_err("bad fastmap header magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC);
		goto fail_bad;
	}

	fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl1);
	if (fm_pos >= fm_size)
		goto fail_bad;
	if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) {
		ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC);
		goto fail_bad;
	}

	fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl2);
	if (fm_pos >= fm_size)
		goto fail_bad;
	if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) {
		ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC);
		goto fail_bad;
	}

	pool_size = be16_to_cpu(fmpl1->size);
	wl_pool_size = be16_to_cpu(fmpl2->size);
	fm->max_pool_size = be16_to_cpu(fmpl1->max_size);
	fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size);

	if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) {
		ubi_err("bad pool size: %i", pool_size);
		goto fail_bad;
	}

	if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) {
		ubi_err("bad WL pool size: %i", wl_pool_size);
		goto fail_bad;
	}


	if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE ||
	    fm->max_pool_size < 0) {
		ubi_err("bad maximal pool size: %i", fm->max_pool_size);
		goto fail_bad;
	}

	if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE ||
	    fm->max_wl_pool_size < 0) {
		ubi_err("bad maximal WL pool size: %i", fm->max_wl_pool_size);
		goto fail_bad;
	}

	/* read EC values from free list */
	for (i = 0; i < be32_to_cpu(fmhdr->free_peb_count); i++) {
		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmec);
		if (fm_pos >= fm_size)
			goto fail_bad;

		add_aeb(ai, &ai->free, be32_to_cpu(fmec->pnum),
			be32_to_cpu(fmec->ec), 0);
	}

	/* read EC values from used list */
	for (i = 0; i < be32_to_cpu(fmhdr->used_peb_count); i++) {
		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmec);
		if (fm_pos >= fm_size)
			goto fail_bad;

		add_aeb(ai, &used, be32_to_cpu(fmec->pnum),
			be32_to_cpu(fmec->ec), 0);
	}

	/* read EC values from scrub list */
	for (i = 0; i < be32_to_cpu(fmhdr->scrub_peb_count); i++) {
		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmec);
		if (fm_pos >= fm_size)
			goto fail_bad;

		add_aeb(ai, &used, be32_to_cpu(fmec->pnum),
			be32_to_cpu(fmec->ec), 1);
	}

	/* read EC values from erase list */
	for (i = 0; i < be32_to_cpu(fmhdr->erase_peb_count); i++) {
		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmec);
		if (fm_pos >= fm_size)
			goto fail_bad;

		add_aeb(ai, &ai->erase, be32_to_cpu(fmec->pnum),
			be32_to_cpu(fmec->ec), 1);
	}

	ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count);
	ai->bad_peb_count = be32_to_cpu(fmhdr->bad_peb_count);

	/* Iterate over all volumes and read their EBA table */
	for (i = 0; i < be32_to_cpu(fmhdr->vol_count); i++) {
		fmvhdr = (struct ubi_fm_volhdr *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fmvhdr);
		if (fm_pos >= fm_size)
			goto fail_bad;

		if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) {
			ubi_err("bad fastmap vol header magic: 0x%x, " \
				"expected: 0x%x",
				be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC);
			goto fail_bad;
		}

		av = add_vol(ai, be32_to_cpu(fmvhdr->vol_id),
			     be32_to_cpu(fmvhdr->used_ebs),
			     be32_to_cpu(fmvhdr->data_pad),
			     fmvhdr->vol_type,
			     be32_to_cpu(fmvhdr->last_eb_bytes));

		if (!av)
			goto fail_bad;

		ai->vols_found++;
		if (ai->highest_vol_id < be32_to_cpu(fmvhdr->vol_id))
			ai->highest_vol_id = be32_to_cpu(fmvhdr->vol_id);

		fm_eba = (struct ubi_fm_eba *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fm_eba);
		fm_pos += (sizeof(__be32) * be32_to_cpu(fm_eba->reserved_pebs));
		if (fm_pos >= fm_size)
			goto fail_bad;

		if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) {
			ubi_err("bad fastmap EBA header magic: 0x%x, " \
				"expected: 0x%x",
				be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC);
			goto fail_bad;
		}

		for (j = 0; j < be32_to_cpu(fm_eba->reserved_pebs); j++) {
			int pnum = be32_to_cpu(fm_eba->pnum[j]);

			if ((int)be32_to_cpu(fm_eba->pnum[j]) < 0)
				continue;

			aeb = NULL;
			list_for_each_entry(tmp_aeb, &used, u.list) {
				if (tmp_aeb->pnum == pnum) {
					aeb = tmp_aeb;
					break;
				}
			}

			/* This can happen if a PEB is already in an EBA known
			 * by this fastmap but the PEB itself is not in the used
			 * list.
			 * In this case the PEB can be within the fastmap pool
			 * or while writing the fastmap it was in the protection
			 * queue.
			 */
			if (!aeb) {
				aeb = kmem_cache_alloc(ai->aeb_slab_cache,
						       GFP_KERNEL);
				if (!aeb) {
					ret = -ENOMEM;

					goto fail;
				}

				aeb->lnum = j;
				aeb->pnum = be32_to_cpu(fm_eba->pnum[j]);
				aeb->ec = -1;
				aeb->scrub = aeb->copy_flag = aeb->sqnum = 0;
				list_add_tail(&aeb->u.list, &eba_orphans);
				continue;
			}

			aeb->lnum = j;

			if (av->highest_lnum <= aeb->lnum)
				av->highest_lnum = aeb->lnum;

			assign_aeb_to_av(ai, aeb, av);

			dbg_bld("inserting PEB:%i (LEB %i) to vol %i",
				aeb->pnum, aeb->lnum, av->vol_id);
		}

		ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
		if (!ech) {
			ret = -ENOMEM;
			goto fail;
		}

		list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans,
					 u.list) {
			int err;

			if (ubi_io_is_bad(ubi, tmp_aeb->pnum)) {
				ubi_err("bad PEB in fastmap EBA orphan list");
				ret = UBI_BAD_FASTMAP;
				kfree(ech);
				goto fail;
			}

			err = ubi_io_read_ec_hdr(ubi, tmp_aeb->pnum, ech, 0);
			if (err && err != UBI_IO_BITFLIPS) {
				ubi_err("unable to read EC header! PEB:%i " \
					"err:%i", tmp_aeb->pnum, err);
				ret = err > 0 ? UBI_BAD_FASTMAP : err;
				kfree(ech);

				goto fail;
			} else if (err == UBI_IO_BITFLIPS)
				tmp_aeb->scrub = 1;

			tmp_aeb->ec = be64_to_cpu(ech->ec);
			assign_aeb_to_av(ai, tmp_aeb, av);
		}

		kfree(ech);
	}

	ret = scan_pool(ubi, ai, fmpl1->pebs, pool_size, &max_sqnum,
			&eba_orphans, &free);
	if (ret)
		goto fail;

	ret = scan_pool(ubi, ai, fmpl2->pebs, wl_pool_size, &max_sqnum,
			&eba_orphans, &free);
	if (ret)
		goto fail;

	if (max_sqnum > ai->max_sqnum)
		ai->max_sqnum = max_sqnum;

	list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list)
		list_move_tail(&tmp_aeb->u.list, &ai->free);

	ubi_assert(list_empty(&used));
	ubi_assert(list_empty(&eba_orphans));
	ubi_assert(list_empty(&free));

	/*
	 * If fastmap is leaking PEBs (must not happen), raise a
	 * fat warning and fall back to scanning mode.
	 * We do this here because in ubi_wl_init() it's too late
	 * and we cannot fall back to scanning.
	 */
	if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count -
		    ai->bad_peb_count - fm->used_blocks))
		goto fail_bad;

	return 0;

fail_bad:
	ret = UBI_BAD_FASTMAP;
fail:
	list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) {
		list_del(&tmp_aeb->u.list);
		kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
	}
	list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, u.list) {
		list_del(&tmp_aeb->u.list);
		kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
	}
	list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
		list_del(&tmp_aeb->u.list);
		kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
	}

	return ret;
}

/**
 * ubi_scan_fastmap - scan the fastmap.
 * @ubi: UBI device object
 * @ai: UBI attach info to be filled
 * @fm_anchor: The fastmap starts at this PEB
 *
 * Returns 0 on success, UBI_NO_FASTMAP if no fastmap was found,
 * UBI_BAD_FASTMAP if one was found but is not usable.
 * < 0 indicates an internal error.
 */
int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
		     int fm_anchor)
{
	struct ubi_fm_sb *fmsb, *fmsb2;
	struct ubi_vid_hdr *vh;
	struct ubi_ec_hdr *ech;
	struct ubi_fastmap_layout *fm;
	int i, used_blocks, pnum, ret = 0;
	size_t fm_size;
	__be32 crc, tmp_crc;
	unsigned long long sqnum = 0;

	mutex_lock(&ubi->fm_mutex);
	memset(ubi->fm_buf, 0, ubi->fm_size);

	fmsb = kmalloc(sizeof(*fmsb), GFP_KERNEL);
	if (!fmsb) {
		ret = -ENOMEM;
		goto out;
	}

	fm = kzalloc(sizeof(*fm), GFP_KERNEL);
	if (!fm) {
		ret = -ENOMEM;
		kfree(fmsb);
		goto out;
	}

	ret = ubi_io_read(ubi, fmsb, fm_anchor, ubi->leb_start, sizeof(*fmsb));
	if (ret && ret != UBI_IO_BITFLIPS)
		goto free_fm_sb;
	else if (ret == UBI_IO_BITFLIPS)
		fm->to_be_tortured[0] = 1;

	if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) {
		ubi_err("bad super block magic: 0x%x, expected: 0x%x",
			be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC);
		ret = UBI_BAD_FASTMAP;
		goto free_fm_sb;
	}

	if (fmsb->version != UBI_FM_FMT_VERSION) {
		ubi_err("bad fastmap version: %i, expected: %i",
			fmsb->version, UBI_FM_FMT_VERSION);
		ret = UBI_BAD_FASTMAP;
		goto free_fm_sb;
	}

	used_blocks = be32_to_cpu(fmsb->used_blocks);
	if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) {
		ubi_err("number of fastmap blocks is invalid: %i", used_blocks);
		ret = UBI_BAD_FASTMAP;
		goto free_fm_sb;
	}

	fm_size = ubi->leb_size * used_blocks;
	if (fm_size != ubi->fm_size) {
		ubi_err("bad fastmap size: %zi, expected: %zi", fm_size,
			ubi->fm_size);
		ret = UBI_BAD_FASTMAP;
		goto free_fm_sb;
	}

	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
	if (!ech) {
		ret = -ENOMEM;
		goto free_fm_sb;
	}

	vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
	if (!vh) {
		ret = -ENOMEM;
		goto free_hdr;
	}

	for (i = 0; i < used_blocks; i++) {
		int image_seq;

		pnum = be32_to_cpu(fmsb->block_loc[i]);

		if (ubi_io_is_bad(ubi, pnum)) {
			ret = UBI_BAD_FASTMAP;
			goto free_hdr;
		}

		ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
		if (ret && ret != UBI_IO_BITFLIPS) {
			ubi_err("unable to read fastmap block# %i EC (PEB: %i)",
				i, pnum);
			if (ret > 0)
				ret = UBI_BAD_FASTMAP;
			goto free_hdr;
		} else if (ret == UBI_IO_BITFLIPS)
			fm->to_be_tortured[i] = 1;

		image_seq = be32_to_cpu(ech->image_seq);
		if (!ubi->image_seq)
			ubi->image_seq = image_seq;

		/*
		 * Older UBI implementations have image_seq set to zero, so
		 * we shouldn't fail if image_seq == 0.
		 */
		if (image_seq && (image_seq != ubi->image_seq)) {
			ubi_err("wrong image seq:%d instead of %d",
				be32_to_cpu(ech->image_seq), ubi->image_seq);
			ret = UBI_BAD_FASTMAP;
			goto free_hdr;
		}

		ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
		if (ret && ret != UBI_IO_BITFLIPS) {
			ubi_err("unable to read fastmap block# %i (PEB: %i)",
				i, pnum);
			goto free_hdr;
		}

		if (i == 0) {
			if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) {
				ubi_err("bad fastmap anchor vol_id: 0x%x," \
					" expected: 0x%x",
					be32_to_cpu(vh->vol_id),
					UBI_FM_SB_VOLUME_ID);
				ret = UBI_BAD_FASTMAP;
				goto free_hdr;
			}
		} else {
			if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) {
				ubi_err("bad fastmap data vol_id: 0x%x," \
					" expected: 0x%x",
					be32_to_cpu(vh->vol_id),
					UBI_FM_DATA_VOLUME_ID);
				ret = UBI_BAD_FASTMAP;
				goto free_hdr;
			}
		}

		if (sqnum < be64_to_cpu(vh->sqnum))
			sqnum = be64_to_cpu(vh->sqnum);

		ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum,
				  ubi->leb_start, ubi->leb_size);
		if (ret && ret != UBI_IO_BITFLIPS) {
			ubi_err("unable to read fastmap block# %i (PEB: %i, " \
				"err: %i)", i, pnum, ret);
			goto free_hdr;
		}
	}

	kfree(fmsb);
	fmsb = NULL;

	fmsb2 = (struct ubi_fm_sb *)(ubi->fm_buf);
	tmp_crc = be32_to_cpu(fmsb2->data_crc);
	fmsb2->data_crc = 0;
	crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size);
	if (crc != tmp_crc) {
		ubi_err("fastmap data CRC is invalid");
		ubi_err("CRC should be: 0x%x, calc: 0x%x", tmp_crc, crc);
		ret = UBI_BAD_FASTMAP;
		goto free_hdr;
	}

	fmsb2->sqnum = sqnum;

	fm->used_blocks = used_blocks;

	ret = ubi_attach_fastmap(ubi, ai, fm);
	if (ret) {
		if (ret > 0)
			ret = UBI_BAD_FASTMAP;
		goto free_hdr;
	}

	for (i = 0; i < used_blocks; i++) {
		struct ubi_wl_entry *e;

		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
		if (!e) {
			while (i--)
				kfree(fm->e[i]);

			ret = -ENOMEM;
			goto free_hdr;
		}

		e->pnum = be32_to_cpu(fmsb2->block_loc[i]);
		e->ec = be32_to_cpu(fmsb2->block_ec[i]);
		fm->e[i] = e;
	}

	ubi->fm = fm;
	ubi->fm_pool.max_size = ubi->fm->max_pool_size;
	ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size;
	ubi_msg("attached by fastmap");
	ubi_msg("fastmap pool size: %d", ubi->fm_pool.max_size);
	ubi_msg("fastmap WL pool size: %d", ubi->fm_wl_pool.max_size);
	ubi->fm_disabled = 0;

	ubi_free_vid_hdr(ubi, vh);
	kfree(ech);
out:
	mutex_unlock(&ubi->fm_mutex);
	if (ret == UBI_BAD_FASTMAP)
		ubi_err("Attach by fastmap failed, doing a full scan!");
	return ret;

free_hdr:
	ubi_free_vid_hdr(ubi, vh);
	kfree(ech);
free_fm_sb:
	kfree(fmsb);
	kfree(fm);
	goto out;
}

/**
 * ubi_write_fastmap - writes a fastmap.
 * @ubi: UBI device object
 * @new_fm: the to be written fastmap
 *
 * Returns 0 on success, < 0 indicates an internal error.
 */
static int ubi_write_fastmap(struct ubi_device *ubi,
			     struct ubi_fastmap_layout *new_fm)
{
	size_t fm_pos = 0;
	void *fm_raw;
	struct ubi_fm_sb *fmsb;
	struct ubi_fm_hdr *fmh;
	struct ubi_fm_scan_pool *fmpl1, *fmpl2;
	struct ubi_fm_ec *fec;
	struct ubi_fm_volhdr *fvh;
	struct ubi_fm_eba *feba;
	struct rb_node *node;
	struct ubi_wl_entry *wl_e;
	struct ubi_volume *vol;
	struct ubi_vid_hdr *avhdr, *dvhdr;
	struct ubi_work *ubi_wrk;
	int ret, i, j, free_peb_count, used_peb_count, vol_count;
	int scrub_peb_count, erase_peb_count;

	fm_raw = ubi->fm_buf;
	memset(ubi->fm_buf, 0, ubi->fm_size);

	avhdr = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID);
	if (!avhdr) {
		ret = -ENOMEM;
		goto out;
	}

	dvhdr = new_fm_vhdr(ubi, UBI_FM_DATA_VOLUME_ID);
	if (!dvhdr) {
		ret = -ENOMEM;
		goto out_kfree;
	}

	spin_lock(&ubi->volumes_lock);
	spin_lock(&ubi->wl_lock);

	fmsb = (struct ubi_fm_sb *)fm_raw;
	fm_pos += sizeof(*fmsb);
	ubi_assert(fm_pos <= ubi->fm_size);

	fmh = (struct ubi_fm_hdr *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmh);
	ubi_assert(fm_pos <= ubi->fm_size);

	fmsb->magic = cpu_to_be32(UBI_FM_SB_MAGIC);
	fmsb->version = UBI_FM_FMT_VERSION;
	fmsb->used_blocks = cpu_to_be32(new_fm->used_blocks);
	/* the max sqnum will be filled in while *reading* the fastmap */
	fmsb->sqnum = 0;

	fmh->magic = cpu_to_be32(UBI_FM_HDR_MAGIC);
	free_peb_count = 0;
	used_peb_count = 0;
	scrub_peb_count = 0;
	erase_peb_count = 0;
	vol_count = 0;

	fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl1);
	fmpl1->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
	fmpl1->size = cpu_to_be16(ubi->fm_pool.size);
	fmpl1->max_size = cpu_to_be16(ubi->fm_pool.max_size);

	for (i = 0; i < ubi->fm_pool.size; i++)
		fmpl1->pebs[i] = cpu_to_be32(ubi->fm_pool.pebs[i]);

	fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
	fm_pos += sizeof(*fmpl2);
	fmpl2->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
	fmpl2->size = cpu_to_be16(ubi->fm_wl_pool.size);
	fmpl2->max_size = cpu_to_be16(ubi->fm_wl_pool.max_size);

	for (i = 0; i < ubi->fm_wl_pool.size; i++)
		fmpl2->pebs[i] = cpu_to_be32(ubi->fm_wl_pool.pebs[i]);

	for (node = rb_first(&ubi->free); node; node = rb_next(node)) {
		wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
		fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);

		fec->pnum = cpu_to_be32(wl_e->pnum);
		fec->ec = cpu_to_be32(wl_e->ec);

		free_peb_count++;
		fm_pos += sizeof(*fec);
		ubi_assert(fm_pos <= ubi->fm_size);
	}
	fmh->free_peb_count = cpu_to_be32(free_peb_count);

	for (node = rb_first(&ubi->used); node; node = rb_next(node)) {
		wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
		fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);

		fec->pnum = cpu_to_be32(wl_e->pnum);
		fec->ec = cpu_to_be32(wl_e->ec);

		used_peb_count++;
		fm_pos += sizeof(*fec);
		ubi_assert(fm_pos <= ubi->fm_size);
	}
	fmh->used_peb_count = cpu_to_be32(used_peb_count);

	for (node = rb_first(&ubi->scrub); node; node = rb_next(node)) {
		wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
		fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);

		fec->pnum = cpu_to_be32(wl_e->pnum);
		fec->ec = cpu_to_be32(wl_e->ec);

		scrub_peb_count++;
		fm_pos += sizeof(*fec);
		ubi_assert(fm_pos <= ubi->fm_size);
	}
	fmh->scrub_peb_count = cpu_to_be32(scrub_peb_count);


	list_for_each_entry(ubi_wrk, &ubi->works, list) {
		if (ubi_is_erase_work(ubi_wrk)) {
			wl_e = ubi_wrk->e;
			ubi_assert(wl_e);

			fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);

			fec->pnum = cpu_to_be32(wl_e->pnum);
			fec->ec = cpu_to_be32(wl_e->ec);

			erase_peb_count++;
			fm_pos += sizeof(*fec);
			ubi_assert(fm_pos <= ubi->fm_size);
		}
	}
	fmh->erase_peb_count = cpu_to_be32(erase_peb_count);

	for (i = 0; i < UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT; i++) {
		vol = ubi->volumes[i];

		if (!vol)
			continue;

		vol_count++;

		fvh = (struct ubi_fm_volhdr *)(fm_raw + fm_pos);
		fm_pos += sizeof(*fvh);
		ubi_assert(fm_pos <= ubi->fm_size);

		fvh->magic = cpu_to_be32(UBI_FM_VHDR_MAGIC);
		fvh->vol_id = cpu_to_be32(vol->vol_id);
		fvh->vol_type = vol->vol_type;
		fvh->used_ebs = cpu_to_be32(vol->used_ebs);
		fvh->data_pad = cpu_to_be32(vol->data_pad);
		fvh->last_eb_bytes = cpu_to_be32(vol->last_eb_bytes);

		ubi_assert(vol->vol_type == UBI_DYNAMIC_VOLUME ||
			vol->vol_type == UBI_STATIC_VOLUME);

		feba = (struct ubi_fm_eba *)(fm_raw + fm_pos);
		fm_pos += sizeof(*feba) + (sizeof(__be32) * vol->reserved_pebs);
		ubi_assert(fm_pos <= ubi->fm_size);

		for (j = 0; j < vol->reserved_pebs; j++)
			feba->pnum[j] = cpu_to_be32(vol->eba_tbl[j]);

		feba->reserved_pebs = cpu_to_be32(j);
		feba->magic = cpu_to_be32(UBI_FM_EBA_MAGIC);
	}
	fmh->vol_count = cpu_to_be32(vol_count);
	fmh->bad_peb_count = cpu_to_be32(ubi->bad_peb_count);

	avhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
	avhdr->lnum = 0;

	spin_unlock(&ubi->wl_lock);
	spin_unlock(&ubi->volumes_lock);

	dbg_bld("writing fastmap SB to PEB %i", new_fm->e[0]->pnum);
	ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avhdr);
	if (ret) {
		ubi_err("unable to write vid_hdr to fastmap SB!");
		goto out_kfree;
	}

	for (i = 0; i < new_fm->used_blocks; i++) {
		fmsb->block_loc[i] = cpu_to_be32(new_fm->e[i]->pnum);
		fmsb->block_ec[i] = cpu_to_be32(new_fm->e[i]->ec);
	}

	fmsb->data_crc = 0;
	fmsb->data_crc = cpu_to_be32(crc32(UBI_CRC32_INIT, fm_raw,
					   ubi->fm_size));

	for (i = 1; i < new_fm->used_blocks; i++) {
		dvhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
		dvhdr->lnum = cpu_to_be32(i);
		dbg_bld("writing fastmap data to PEB %i sqnum %llu",
			new_fm->e[i]->pnum, be64_to_cpu(dvhdr->sqnum));
		ret = ubi_io_write_vid_hdr(ubi, new_fm->e[i]->pnum, dvhdr);
		if (ret) {
			ubi_err("unable to write vid_hdr to PEB %i!",
				new_fm->e[i]->pnum);
			goto out_kfree;
		}
	}

	for (i = 0; i < new_fm->used_blocks; i++) {
		ret = ubi_io_write(ubi, fm_raw + (i * ubi->leb_size),
			new_fm->e[i]->pnum, ubi->leb_start, ubi->leb_size);
		if (ret) {
			ubi_err("unable to write fastmap to PEB %i!",
				new_fm->e[i]->pnum);
			goto out_kfree;
		}
	}

	ubi_assert(new_fm);
	ubi->fm = new_fm;

	dbg_bld("fastmap written!");

out_kfree:
	ubi_free_vid_hdr(ubi, avhdr);
	ubi_free_vid_hdr(ubi, dvhdr);
out:
	return ret;
}

/**
 * erase_block - Manually erase a PEB.
 * @ubi: UBI device object
 * @pnum: PEB to be erased
 *
 * Returns the new EC value on success, < 0 indicates an internal error.
 */
static int erase_block(struct ubi_device *ubi, int pnum)
{
	int ret;
	struct ubi_ec_hdr *ec_hdr;
	long long ec;

	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
	if (!ec_hdr)
		return -ENOMEM;

	ret = ubi_io_read_ec_hdr(ubi, pnum, ec_hdr, 0);
	if (ret < 0)
		goto out;
	else if (ret && ret != UBI_IO_BITFLIPS) {
		ret = -EINVAL;
		goto out;
	}

	ret = ubi_io_sync_erase(ubi, pnum, 0);
	if (ret < 0)
		goto out;

	ec = be64_to_cpu(ec_hdr->ec);
	ec += ret;
	if (ec > UBI_MAX_ERASECOUNTER) {
		ret = -EINVAL;
		goto out;
	}

	ec_hdr->ec = cpu_to_be64(ec);
	ret = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr);
	if (ret < 0)
		goto out;

	ret = ec;
out:
	kfree(ec_hdr);
	return ret;
}

/**
 * invalidate_fastmap - destroys a fastmap.
 * @ubi: UBI device object
 * @fm: the fastmap to be destroyed
 *
 * Returns 0 on success, < 0 indicates an internal error.
 */
static int invalidate_fastmap(struct ubi_device *ubi,
			      struct ubi_fastmap_layout *fm)
{
	int ret;
	struct ubi_vid_hdr *vh;

	ret = erase_block(ubi, fm->e[0]->pnum);
	if (ret < 0)
		return ret;

	vh = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID);
	if (!vh)
		return -ENOMEM;

	/* deleting the current fastmap SB is not enough, an old SB may exist,
	 * so create a (corrupted) SB such that fastmap will find it and fall
	 * back to scanning mode in any case */
	vh->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
	ret = ubi_io_write_vid_hdr(ubi, fm->e[0]->pnum, vh);

	return ret;
}

/**
 * ubi_update_fastmap - will be called by UBI if a volume changes or
 * a fastmap pool becomes full.
 * @ubi: UBI device object
 *
 * Returns 0 on success, < 0 indicates an internal error.
 */
int ubi_update_fastmap(struct ubi_device *ubi)
{
	int ret, i;
	struct ubi_fastmap_layout *new_fm, *old_fm;
	struct ubi_wl_entry *tmp_e;

	mutex_lock(&ubi->fm_mutex);

	ubi_refill_pools(ubi);

	if (ubi->ro_mode || ubi->fm_disabled) {
		mutex_unlock(&ubi->fm_mutex);
		return 0;
	}

	ret = ubi_ensure_anchor_pebs(ubi);
	if (ret) {
		mutex_unlock(&ubi->fm_mutex);
		return ret;
	}

	new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL);
	if (!new_fm) {
		mutex_unlock(&ubi->fm_mutex);
		return -ENOMEM;
	}

	new_fm->used_blocks = ubi->fm_size / ubi->leb_size;

	for (i = 0; i < new_fm->used_blocks; i++) {
		new_fm->e[i] = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
		if (!new_fm->e[i]) {
			while (i--)
				kfree(new_fm->e[i]);

			kfree(new_fm);
			mutex_unlock(&ubi->fm_mutex);
			return -ENOMEM;
		}
	}

	old_fm = ubi->fm;
	ubi->fm = NULL;

	if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) {
		ubi_err("fastmap too large");
		ret = -ENOSPC;
		goto err;
	}

	for (i = 1; i < new_fm->used_blocks; i++) {
		spin_lock(&ubi->wl_lock);
		tmp_e = ubi_wl_get_fm_peb(ubi, 0);
		spin_unlock(&ubi->wl_lock);

		if (!tmp_e && !old_fm) {
			int j;
			ubi_err("could not get any free erase block");

			for (j = 1; j < i; j++)
				ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0);

			ret = -ENOSPC;
			goto err;
		} else if (!tmp_e && old_fm) {
			ret = erase_block(ubi, old_fm->e[i]->pnum);
			if (ret < 0) {
				int j;

				for (j = 1; j < i; j++)
					ubi_wl_put_fm_peb(ubi, new_fm->e[j],
							  j, 0);

				ubi_err("could not erase old fastmap PEB");
				goto err;
			}

			new_fm->e[i]->pnum = old_fm->e[i]->pnum;
			new_fm->e[i]->ec = old_fm->e[i]->ec;
		} else {
			new_fm->e[i]->pnum = tmp_e->pnum;
			new_fm->e[i]->ec = tmp_e->ec;

			if (old_fm)
				ubi_wl_put_fm_peb(ubi, old_fm->e[i], i,
						  old_fm->to_be_tortured[i]);
		}
	}

	spin_lock(&ubi->wl_lock);
	tmp_e = ubi_wl_get_fm_peb(ubi, 1);
	spin_unlock(&ubi->wl_lock);

	if (old_fm) {
		/* no fresh anchor PEB was found, reuse the old one */
		if (!tmp_e) {
			ret = erase_block(ubi, old_fm->e[0]->pnum);
			if (ret < 0) {
				int i;
				ubi_err("could not erase old anchor PEB");

				for (i = 1; i < new_fm->used_blocks; i++)
					ubi_wl_put_fm_peb(ubi, new_fm->e[i],
							  i, 0);
				goto err;
			}

			new_fm->e[0]->pnum = old_fm->e[0]->pnum;
			new_fm->e[0]->ec = ret;
		} else {
			/* we've got a new anchor PEB, return the old one */
			ubi_wl_put_fm_peb(ubi, old_fm->e[0], 0,
					  old_fm->to_be_tortured[0]);

			new_fm->e[0]->pnum = tmp_e->pnum;
			new_fm->e[0]->ec = tmp_e->ec;
		}
	} else {
		if (!tmp_e) {
			int i;
			ubi_err("could not find any anchor PEB");

			for (i = 1; i < new_fm->used_blocks; i++)
				ubi_wl_put_fm_peb(ubi, new_fm->e[i], i, 0);

			ret = -ENOSPC;
			goto err;
		}

		new_fm->e[0]->pnum = tmp_e->pnum;
		new_fm->e[0]->ec = tmp_e->ec;
	}

	down_write(&ubi->work_sem);
	down_write(&ubi->fm_sem);
	ret = ubi_write_fastmap(ubi, new_fm);
	up_write(&ubi->fm_sem);
	up_write(&ubi->work_sem);

	if (ret)
		goto err;

out_unlock:
	mutex_unlock(&ubi->fm_mutex);
	kfree(old_fm);
	return ret;

err:
	kfree(new_fm);

	ubi_warn("Unable to write new fastmap, err=%i", ret);

	ret = 0;
	if (old_fm) {
		ret = invalidate_fastmap(ubi, old_fm);
		if (ret < 0)
			ubi_err("Unable to invalidiate current fastmap!");
		else if (ret)
			ret = 0;
	}
	goto out_unlock;
}
