Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e7a0496 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "Revert "mtd: ubi: Fill read disturb statistics""

parents 76f75534 5a181a30
Loading
Loading
Loading
Loading
+32 −105
Original line number Diff line number Diff line
/*
 * Copyright (c) International Business Machines Corp., 2006
 * Copyright (c) 2014, Linux Foundation. All rights reserved.
 * Linux Foundation chooses to take subject only to the GPLv2
 * license terms, and distributes only under these terms.
 *
 * 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
@@ -90,21 +87,8 @@
#include <linux/crc32.h>
#include <linux/math64.h>
#include <linux/random.h>
#include <linux/time.h>
#include "ubi.h"

#define set_aeb_default_values(aeb, ai)		\
	do {					\
		if (aeb->ec == UBI_UNKNOWN) {	\
			aeb->ec = ai->mean_ec;	\
			if (ai->mean_last_erase_time) \
				aeb->last_erase_time = \
					ai->mean_last_erase_time; \
			else \
				aeb->last_erase_time = UBI_DT_THRESHOLD / 2; \
		}		\
	} while (0)

static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai);

/* Temporary variables used during scanning */
@@ -118,9 +102,6 @@ static struct ubi_vid_hdr *vidh;
 * @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
 * @last_erase_time: last erase time stamp (%UBI_UNKNOWN if it
 *				is unknown)
 * @rc: read counter (%UBI_UNKNOWN if it is unknown)
 * @to_head: if not zero, add to the head of the list
 * @list: the list to add to
 *
@@ -136,8 +117,7 @@ static struct ubi_vid_hdr *vidh;
 * failure.
 */
static int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id,
		       int lnum, int ec, long last_erase_time, long rc,
		       int to_head, struct list_head *list)
		       int lnum, int ec, int to_head, struct list_head *list)
{
	struct ubi_ainf_peb *aeb;

@@ -159,9 +139,6 @@ static int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id,
	aeb->vol_id = vol_id;
	aeb->lnum = lnum;
	aeb->ec = ec;
	aeb->rc = rc;
	aeb->last_erase_time = last_erase_time;

	if (to_head)
		list_add(&aeb->u.list, list);
	else
@@ -174,17 +151,13 @@ static int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id,
 * @ai: attaching information
 * @pnum: physical eraseblock number to add
 * @ec: erase counter of the physical eraseblock
 * @last_erase_time: last erase time stamp (%UBI_UNKNOWN if it
 *			   is unknown)
 * @rc: read counter (%UBI_UNKNOWN if it is unknown)
 *
 * 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, long rc, long last_erase_time)
static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec)
{
	struct ubi_ainf_peb *aeb;

@@ -197,8 +170,6 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum,
	ai->corr_peb_count += 1;
	aeb->pnum = pnum;
	aeb->ec = ec;
	aeb->rc = rc;
	aeb->last_erase_time = last_erase_time;
	list_add(&aeb->u.list, &ai->corr);
	return 0;
}
@@ -465,9 +436,6 @@ out_free_vidh:
 * @ai: attaching information
 * @pnum: the physical eraseblock number
 * @ec: erase counter
 * @last_erase_time: last erase time stamp (%UBI_UNKNOWN if it
 *			   is unknown)
 * @rc: read counter (%UBI_UNKNOWN if it is unknown)
 * @vid_hdr: the volume identifier header
 * @bitflips: if bit-flips were detected when this physical eraseblock was read
 *
@@ -479,8 +447,7 @@ out_free_vidh:
 * zero in case of success and a negative error code in case of failure.
 */
int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
		  int ec, long last_erase_time, long rc,
		  const struct ubi_vid_hdr *vid_hdr, int bitflips)
		  int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips)
{
	int err, vol_id, lnum;
	unsigned long long sqnum;
@@ -567,16 +534,12 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
				return err;

			err = add_to_list(ai, aeb->pnum, aeb->vol_id,
					  aeb->lnum, aeb->ec,
					  aeb->last_erase_time,
					  aeb->rc, cmp_res & 4,
					  aeb->lnum, aeb->ec, cmp_res & 4,
					  &ai->erase);
			if (err)
				return err;

			aeb->ec = ec;
			aeb->last_erase_time = last_erase_time;
			aeb->rc = rc;
			aeb->pnum = pnum;
			aeb->vol_id = vol_id;
			aeb->lnum = lnum;
@@ -595,8 +558,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
			 * previously.
			 */
			return add_to_list(ai, pnum, vol_id, lnum, ec,
					   last_erase_time, rc, cmp_res & 4,
					   &ai->erase);
					   cmp_res & 4, &ai->erase);
		}
	}

@@ -614,8 +576,6 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
		return -ENOMEM;

	aeb->ec = ec;
	aeb->last_erase_time = last_erase_time;
	aeb->rc = rc;
	aeb->pnum = pnum;
	aeb->vol_id = vol_id;
	aeb->lnum = lnum;
@@ -692,8 +652,6 @@ void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av)
 * @ai: attaching information
 * @pnum: physical eraseblock number to erase;
 * @ec: erase counter value to write (%UBI_UNKNOWN if it is unknown)
 * @last_erase_time: last erase time stamp (%UBI_UNKNOWN if it
 *			   is unknown)
 *
 * This function erases physical eraseblock 'pnum', and writes the erase
 * counter header to it. This function should only be used on UBI device
@@ -702,8 +660,7 @@ void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av)
 * case of failure.
 */
static int early_erase_peb(struct ubi_device *ubi,
			   const struct ubi_attach_info *ai,
			   int pnum, int ec, long last_erase_time)
			   const struct ubi_attach_info *ai, int pnum, int ec)
{
	int err;
	struct ubi_ec_hdr *ec_hdr;
@@ -723,7 +680,7 @@ static int early_erase_peb(struct ubi_device *ubi,
		return -ENOMEM;

	ec_hdr->ec = cpu_to_be64(ec);
	ec_hdr->last_erase_time = cpu_to_be64(last_erase_time);

	err = ubi_io_sync_erase(ubi, pnum, 0);
	if (err < 0)
		goto out_free;
@@ -754,7 +711,6 @@ struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
{
	int err = 0;
	struct ubi_ainf_peb *aeb, *tmp_aeb;
	struct timeval tv;

	if (!list_empty(&ai->free)) {
		aeb = list_entry(ai->free.next, struct ubi_ainf_peb, u.list);
@@ -769,20 +725,15 @@ struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
	 * so forth. We don't want to take care about bad eraseblocks here -
	 * they'll be handled later.
	 */
	do_gettimeofday(&tv);
	list_for_each_entry_safe(aeb, tmp_aeb, &ai->erase, u.list) {
		if (aeb->ec == UBI_UNKNOWN)
			aeb->ec = ai->mean_ec;

		/* The last erase time resolution is in days */
		err = early_erase_peb(ubi, ai, aeb->pnum,
				  aeb->ec+1, tv.tv_sec / NUM_SEC_IN_DAY);
		err = early_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1);
		if (err)
			continue;

		aeb->ec += 1;
		aeb->last_erase_time = tv.tv_sec / NUM_SEC_IN_DAY;
		aeb->rc = 0;
		list_del(&aeb->u.list);
		dbg_bld("return PEB %d, EC %d", aeb->pnum, aeb->ec);
		return aeb;
@@ -869,8 +820,6 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
		    int pnum, int *vid, unsigned long long *sqnum)
{
	long long uninitialized_var(ec);
	long long uninitialized_var(rc);
	long long uninitialized_var(last_erase_time);
	int err, bitflips = 0, vol_id = -1, ec_err = 0;

	dbg_bld("scan PEB %d", pnum);
@@ -896,13 +845,11 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
	case UBI_IO_FF:
		ai->empty_peb_count += 1;
		return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
				   UBI_UNKNOWN, UBI_UNKNOWN, UBI_UNKNOWN,
				   0, &ai->erase);
				   UBI_UNKNOWN, 0, &ai->erase);
	case UBI_IO_FF_BITFLIPS:
		ai->empty_peb_count += 1;
		return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
				   UBI_UNKNOWN, UBI_UNKNOWN, UBI_UNKNOWN,
				   1, &ai->erase);
				   UBI_UNKNOWN, 1, &ai->erase);
	case UBI_IO_BAD_HDR_EBADMSG:
	case UBI_IO_BAD_HDR:
		/*
@@ -912,8 +859,6 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
		 */
		ec_err = err;
		ec = UBI_UNKNOWN;
		last_erase_time = UBI_UNKNOWN;
		rc = UBI_UNKNOWN;
		bitflips = 1;
		break;
	default:
@@ -933,16 +878,6 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
		}

		ec = be64_to_cpu(ech->ec);
		last_erase_time = be64_to_cpu(ech->last_erase_time);
		/*
		 * Default value for read counter should be 0. If this is a
		 * free or erased peb, the counter has no meaning.
		 * If this peb is used, later code will schedule the peb for
		 * scrubbing. We can afford erasing all used blocks in this
		 * case as this is a rear case, and not doing so might have
		 * destructive implication on the system.
		 */
		rc = 0;
		if (ec > UBI_MAX_ERASECOUNTER) {
			/*
			 * Erase counter overflow. The EC headers have 64 bits
@@ -1027,32 +962,29 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
		else if (!err)
			/* This corruption is caused by a power cut */
			err = add_to_list(ai, pnum, UBI_UNKNOWN,
					  UBI_UNKNOWN, ec, last_erase_time, rc,
					  1, &ai->erase);
					  UBI_UNKNOWN, ec, 1, &ai->erase);
		else
			/* This is an unexpected corruption */
			err = add_corrupted(ai, pnum, ec, rc, last_erase_time);
			err = add_corrupted(ai, pnum, ec);
		if (err)
			return err;
		goto adjust_mean_av_stat;
		goto adjust_mean_ec;
	case UBI_IO_FF_BITFLIPS:
		err = add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN,
				  ec, last_erase_time, rc, 1, &ai->erase);
				  ec, 1, &ai->erase);
		if (err)
			return err;
		goto adjust_mean_av_stat;
		goto adjust_mean_ec;
	case UBI_IO_FF:
		if (ec_err || bitflips)
			err = add_to_list(ai, pnum, UBI_UNKNOWN,
					  UBI_UNKNOWN, ec, last_erase_time, rc,
					  1, &ai->erase);
					  UBI_UNKNOWN, ec, 1, &ai->erase);
		else
			err = add_to_list(ai, pnum, UBI_UNKNOWN,
					  UBI_UNKNOWN, ec, last_erase_time, 0,
					  0, &ai->free);
					  UBI_UNKNOWN, ec, 0, &ai->free);
		if (err)
			return err;
		goto adjust_mean_av_stat;
		goto adjust_mean_ec;
	default:
		ubi_err(ubi->ubi_num, "'ubi_io_read_vid_hdr()' returned unknown code %d",
			err);
@@ -1078,8 +1010,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
					vol_id, lnum);
			}
			err = add_to_list(ai, pnum, vol_id, lnum,
					  ec, last_erase_time,
					  rc, 1, &ai->erase);
					  ec, 1, &ai->erase);
			if (err)
				return err;
			return 0;
@@ -1098,8 +1029,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
				"volume %d:%d found",
				vol_id, lnum);
			err = add_to_list(ai, pnum, vol_id, lnum,
					  ec, last_erase_time,
					  rc, 0, &ai->alien);
					  ec, 0, &ai->alien);
			if (err)
				return err;
			return 0;
@@ -1114,13 +1044,11 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
	if (ec_err)
		ubi_warn(ubi->ubi_num, "valid VID header but corrupted EC header at PEB %d",
			 pnum);

	err = ubi_add_to_av(ubi, ai, pnum, ec, last_erase_time,
				UBI_DEF_RD_THRESHOLD, vidh, bitflips);
	err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips);
	if (err)
		return err;

adjust_mean_av_stat:
adjust_mean_ec:
	if (!ec_err) {
		ai->ec_sum += ec;
		ai->ec_count += 1;
@@ -1128,8 +1056,6 @@ adjust_mean_av_stat:
			ai->max_ec = ec;
		if (ec < ai->min_ec)
			ai->min_ec = ec;
		ai->last_erase_time_sum += last_erase_time;
		ai->last_erase_time_count++;
	}

	return 0;
@@ -1339,10 +1265,6 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
	if (ai->ec_count)
		ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count);

	if (ai->last_erase_time_count)
		ai->mean_last_erase_time = div_u64(ai->last_erase_time_sum,
						   ai->last_erase_time_count);

	err = late_analysis(ubi, ai);
	if (err)
		goto out_vidh;
@@ -1353,17 +1275,22 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
	 */
	ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) {
		ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb)
			set_aeb_default_values(aeb, ai);
			if (aeb->ec == UBI_UNKNOWN)
				aeb->ec = ai->mean_ec;
	}

	list_for_each_entry(aeb, &ai->free, u.list)
		set_aeb_default_values(aeb, ai);
	list_for_each_entry(aeb, &ai->free, u.list) {
		if (aeb->ec == UBI_UNKNOWN)
			aeb->ec = ai->mean_ec;
	}

	list_for_each_entry(aeb, &ai->corr, u.list)
		set_aeb_default_values(aeb, ai);
		if (aeb->ec == UBI_UNKNOWN)
			aeb->ec = ai->mean_ec;

	list_for_each_entry(aeb, &ai->erase, u.list)
		set_aeb_default_values(aeb, ai);
		if (aeb->ec == UBI_UNKNOWN)
			aeb->ec = ai->mean_ec;

	err = self_check_ai(ubi, ai);
	if (err)
+0 −12
Original line number Diff line number Diff line
/*
 * Copyright (c) International Business Machines Corp., 2006
 * Copyright (c) 2014, Linux Foundation. All rights reserved.
 * Linux Foundation chooses to take subject only to the GPLv2
 * license terms, and distributes only under these terms.
 *
 * 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
@@ -51,15 +48,6 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
			err, len, pnum, offset, read);
		goto out;
	}
	if (ubi->lookuptbl) {
		if (ubi->lookuptbl[pnum]->rc < UBI_MAX_READCOUNTER)
			ubi->lookuptbl[pnum]->rc++;
		else
			ubi_err(ubi->ubi_num,
				"read counter overflow at PEB %d, RC %d",
					pnum, ubi->lookuptbl[pnum]->rc);
	} else
		ubi_err(ubi->ubi_num, "Can't update RC. No lookuptbl");

	ubi_msg(ubi->ubi_num, "dumping %d bytes of data from PEB %d, offset %d",
		len, pnum, offset);
+15 −103
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi)
		sizeof(struct ubi_fm_scan_pool) + \
		(ubi->peb_count * sizeof(struct ubi_fm_ec)) + \
		(sizeof(struct ubi_fm_eba) + \
		(ubi->peb_count * sizeof(__be32)) + \
		(ubi->peb_count * sizeof(__be32))) + \
		sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
	return roundup(size, ubi->leb_size);
@@ -73,16 +72,12 @@ out:
 * @list: the target list
 * @pnum: PEB number of the new attach erase block
 * @ec: erease counter of the new LEB
 * @last_erase_time: last erase time stamp (%UBI_UNKNOWN if it
 *			   is unknown)
 * @rc: read counter (%UBI_UNKNOWN if it is unknown)
 * @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, unsigned long last_erase_time,
		   int rc,  int scrub)
		   int pnum, int ec, int scrub)
{
	struct ubi_ainf_peb *aeb;

@@ -92,8 +87,6 @@ static int add_aeb(struct ubi_attach_info *ai, struct list_head *list,

	aeb->pnum = pnum;
	aeb->ec = ec;
	aeb->rc = rc;
	aeb->last_erase_time = last_erase_time;
	aeb->lnum = -1;
	aeb->scrub = scrub;
	aeb->copy_flag = aeb->sqnum = 0;
@@ -107,9 +100,6 @@ static int add_aeb(struct ubi_attach_info *ai, struct list_head *list,
	if (ai->min_ec > aeb->ec)
		ai->min_ec = aeb->ec;

	ai->last_erase_time_sum += aeb->last_erase_time;
	ai->last_erase_time_count++;

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

	return 0;
@@ -257,8 +247,6 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
				return -ENOMEM;

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

@@ -270,8 +258,6 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
				av->vol_id, aeb->lnum, new_aeb->pnum);

			aeb->ec = new_aeb->ec;
			aeb->last_erase_time = new_aeb->last_erase_time;
			aeb->rc = new_aeb->rc;
			aeb->pnum = new_aeb->pnum;
			aeb->copy_flag = new_vh->copy_flag;
			aeb->scrub = new_aeb->scrub;
@@ -286,7 +272,7 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,

		return 0;
	}
	/* This LEB is new, last_erase_time's add it to the volume */
	/* 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);
@@ -459,16 +445,12 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
		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);
			unsigned long long last_erase_time =
					be64_to_cpu(ech->last_erase_time);
			unmap_peb(ai, pnum);
			dbg_bld("Adding PEB to free: %i", pnum);
			if (err == UBI_IO_FF_BITFLIPS)
				add_aeb(ai, free, pnum, ec, last_erase_time,
						0, 1);
				add_aeb(ai, free, pnum, ec, 1);
			else
				add_aeb(ai, free, pnum, ec, last_erase_time,
						0, 0);
				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);
@@ -496,9 +478,6 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
			}

			new_aeb->ec = be64_to_cpu(ech->ec);
			new_aeb->last_erase_time =
				be64_to_cpu(ech->last_erase_time);
			new_aeb->rc = UBI_DEF_RD_THRESHOLD;
			new_aeb->pnum = pnum;
			new_aeb->lnum = be32_to_cpu(vh->lnum);
			new_aeb->sqnum = be64_to_cpu(vh->sqnum);
@@ -673,9 +652,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
			goto fail_bad;

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

	/* read EC values from used list */
@@ -686,9 +663,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
			goto fail_bad;

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

	/* read EC values from scrub list */
@@ -699,9 +674,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
			goto fail_bad;

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

	/* read EC values from erase list */
@@ -712,14 +685,10 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
			goto fail_bad;

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

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

	/* Iterate over all volumes and read their EBA table */
@@ -751,8 +720,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,

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

@@ -796,9 +764,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
				aeb->lnum = j;
				aeb->pnum =
					be32_to_cpu(fm_eba->peb_data[j].pnum);
				aeb->ec = UBI_UNKNOWN;
				aeb->rc = be32_to_cpu(fm_eba->peb_data[j].rc);
				aeb->last_erase_time = UBI_UNKNOWN;
				aeb->ec = -1;
				aeb->scrub = aeb->copy_flag = aeb->sqnum = 0;
				list_add_tail(&aeb->u.list, &eba_orphans);
				continue;
@@ -845,9 +811,6 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
				tmp_aeb->scrub = 1;

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

@@ -1112,8 +1075,6 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,

		e->pnum = be32_to_cpu(fmsb2->block_loc[i]);
		e->ec = be32_to_cpu(fmsb2->block_ec[i]);
		e->last_erase_time = be64_to_cpu(fmsb2->block_let[i]);
		e->rc = be32_to_cpu(fmsb2->block_rc[i]);
		fm->e[i] = e;
	}

@@ -1233,8 +1194,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,

		fec->pnum = cpu_to_be32(wl_e->pnum);
		fec->ec = cpu_to_be32(wl_e->ec);
		fec->last_erase_time = cpu_to_be64(wl_e->last_erase_time);
		fec->rc = cpu_to_be32(wl_e->rc);

		free_peb_count++;
		fm_pos += sizeof(*fec);
		ubi_assert(fm_pos <= ubi->fm_size);
@@ -1247,8 +1207,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,

		fec->pnum = cpu_to_be32(wl_e->pnum);
		fec->ec = cpu_to_be32(wl_e->ec);
		fec->last_erase_time = cpu_to_be64(wl_e->last_erase_time);
		fec->rc = cpu_to_be32(wl_e->rc);

		used_peb_count++;
		fm_pos += sizeof(*fec);
		ubi_assert(fm_pos <= ubi->fm_size);
@@ -1274,8 +1233,6 @@ static int ubi_write_fastmap(struct ubi_device *ubi,

		fec->pnum = cpu_to_be32(wl_e->pnum);
		fec->ec = cpu_to_be32(wl_e->ec);
		fec->last_erase_time = cpu_to_be64(wl_e->last_erase_time);
		fec->rc = cpu_to_be32(wl_e->rc);

		scrub_peb_count++;
		fm_pos += sizeof(*fec);
@@ -1293,9 +1250,6 @@ static int ubi_write_fastmap(struct ubi_device *ubi,

			fec->pnum = cpu_to_be32(wl_e->pnum);
			fec->ec = cpu_to_be32(wl_e->ec);
			fec->last_erase_time =
				cpu_to_be64(wl_e->last_erase_time);
			fec->rc = cpu_to_be32(wl_e->rc);

			erase_peb_count++;
			fm_pos += sizeof(*fec);
@@ -1331,15 +1285,8 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
			2 * (sizeof(__be32) * vol->reserved_pebs);
		ubi_assert(fm_pos <= ubi->fm_size);

		for (j = 0; j < vol->reserved_pebs; j++) {
		for (j = 0; j < vol->reserved_pebs; j++)
			feba->peb_data[j].pnum = cpu_to_be32(vol->eba_tbl[j]);
			feba->peb_data[j].rc = cpu_to_be32(UBI_UNKNOWN);
			if (vol->eba_tbl[j] >= 0 &&
				ubi->lookuptbl[vol->eba_tbl[j]])
				feba->peb_data[j].rc =
					cpu_to_be32(
					ubi->lookuptbl[vol->eba_tbl[j]]->rc);
		}

		feba->reserved_pebs = cpu_to_be32(j);
		feba->magic = cpu_to_be32(UBI_FM_EBA_MAGIC);
@@ -1363,8 +1310,6 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
	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->block_let[i] = cpu_to_be64(new_fm->e[i]->last_erase_time);
		fmsb->block_rc[i] = cpu_to_be32(new_fm->e[i]->rc);
	}

	fmsb->data_crc = 0;
@@ -1420,7 +1365,6 @@ static int erase_block(struct ubi_device *ubi, int pnum)
	int ret;
	struct ubi_ec_hdr *ec_hdr;
	long long ec;
	struct timeval tv;

	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
	if (!ec_hdr)
@@ -1446,9 +1390,6 @@ static int erase_block(struct ubi_device *ubi, int pnum)
	}

	ec_hdr->ec = cpu_to_be64(ec);
	do_gettimeofday(&tv);
	/* The last erase time resolution is in days */
	ec_hdr->last_erase_time = cpu_to_be64(tv.tv_sec / NUM_SEC_IN_DAY);
	ret = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr);
	if (ret < 0)
		goto out;
@@ -1471,17 +1412,10 @@ static int invalidate_fastmap(struct ubi_device *ubi,
{
	int ret;
	struct ubi_vid_hdr *vh;
	struct timeval tv;

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

	do_gettimeofday(&tv);
	/* The last erase time resolution is in days */
	fm->e[0]->last_erase_time = tv.tv_sec / NUM_SEC_IN_DAY;
	fm->e[0]->rc = 0;

	vh = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID);
	if (!vh)
@@ -1508,9 +1442,6 @@ 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;
	struct timeval tv;

	do_gettimeofday(&tv);

	mutex_lock(&ubi->fm_mutex);

@@ -1586,19 +1517,10 @@ int ubi_update_fastmap(struct ubi_device *ubi)
			}

			new_fm->e[i]->pnum = old_fm->e[i]->pnum;
			new_fm->e[i]->ec = old_fm->e[i]->ec = ret;

			/* The last erase time resolution is in days */
			new_fm->e[i]->last_erase_time =
					tv.tv_sec / NUM_SEC_IN_DAY;
			old_fm->e[i]->last_erase_time =
					tv.tv_sec / NUM_SEC_IN_DAY;
			new_fm->e[i]->rc = old_fm->e[i]->rc = 0;
			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;
			new_fm->e[i]->rc = tmp_e->rc;
			new_fm->e[i]->last_erase_time = tmp_e->last_erase_time;

			if (old_fm)
				ubi_wl_put_fm_peb(ubi, old_fm->e[i], i,
@@ -1626,13 +1548,7 @@ int ubi_update_fastmap(struct ubi_device *ubi)
			}

			new_fm->e[0]->pnum = old_fm->e[0]->pnum;
			new_fm->e[0]->ec = old_fm->e[0]->ec = ret;
			/* The last erase time resolution is in days */
			new_fm->e[0]->last_erase_time =
					tv.tv_sec / NUM_SEC_IN_DAY;
			old_fm->e[0]->last_erase_time =
					tv.tv_sec / NUM_SEC_IN_DAY;
			new_fm->e[0]->rc = old_fm->e[0]->rc = 0;
			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,
@@ -1640,8 +1556,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)

			new_fm->e[0]->pnum = tmp_e->pnum;
			new_fm->e[0]->ec = tmp_e->ec;
			new_fm->e[0]->last_erase_time = tmp_e->last_erase_time;
			new_fm->e[0]->rc = tmp_e->rc;
		}
	} else {
		if (!tmp_e) {
@@ -1657,8 +1571,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)

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

	down_write(&ubi->work_sem);
+0 −32
Original line number Diff line number Diff line
/*
 * Copyright (c) International Business Machines Corp., 2006
 * Copyright (c) Nokia Corporation, 2006, 2007
 * Copyright (c) 2014, Linux Foundation. All rights reserved.
 * Linux Foundation chooses to take subject only to the GPLv2
 * license terms, and distributes only under these terms.
 *
 * 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
@@ -212,15 +209,6 @@ retry:
		}
	} else {
		ubi_assert(len == read);
		if (ubi->lookuptbl && ubi->lookuptbl[pnum]) {
			if (ubi->lookuptbl[pnum]->rc <
				UBI_MAX_READCOUNTER)
				ubi->lookuptbl[pnum]->rc++;
			else
				ubi_err(ubi->ubi_num,
				  "read counter overflow at PEB %d, RC %d",
					pnum, ubi->lookuptbl[pnum]->rc);
		}

		if (ubi_dbg_is_bitflip(ubi)) {
			dbg_gen("bit-flip (emulated)");
@@ -1380,16 +1368,6 @@ static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum,
	if (err && !mtd_is_bitflip(err))
		goto out_free;

	if (ubi->lookuptbl && ubi->lookuptbl[pnum]) {
		if (ubi->lookuptbl[pnum]->rc < UBI_MAX_READCOUNTER)
			ubi->lookuptbl[pnum]->rc++;
		else
			ubi_err(ubi->ubi_num,
				"read counter overflow at PEB %d, RC %d",
					pnum, ubi->lookuptbl[pnum]->rc);
	} else
		ubi_err(ubi->ubi_num, "Can't update RC. No lookuptbl");

	for (i = 0; i < len; i++) {
		uint8_t c = ((uint8_t *)buf)[i];
		uint8_t c1 = ((uint8_t *)buf1)[i];
@@ -1459,16 +1437,6 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
			err, len, pnum, offset, read);
		goto error;
	}
	if (ubi->lookuptbl && ubi->lookuptbl[pnum]) {
		if (ubi->lookuptbl[pnum]->rc < UBI_MAX_READCOUNTER)
			ubi->lookuptbl[pnum]->rc++;
		else
			ubi_err(ubi->ubi_num,
				"read counter overflow at PEB %d, RC %d",
					pnum, ubi->lookuptbl[pnum]->rc);
	} else
		ubi_err(ubi->ubi_num,
			"Can't update RC. No lookuptbl");

	err = ubi_check_pattern(buf, 0xFF, len);
	if (err == 0) {
+1 −23
Original line number Diff line number Diff line
@@ -96,16 +96,6 @@
 */
#define UBI_RD_THRESHOLD 100000

/*
 * This is the default read counter to be assigned to blocks lacking
 * read counter value on attach. The value was choosen as mean between
 * just_erased_block (rc = 0) and needs_scrubbibg_block
 * (rc = UBI_RD_THRESHOLD). On the one hand we don't want to miss
 * blocks that needs scrubbing but on the other, we dont want to
 * abuse scrubbing.
 */
#define UBI_DEF_RD_THRESHOLD (UBI_RD_THRESHOLD / 2)

/*
 * This parameter defines the maximun interval (in days) between two
 * erasures of an eraseblock. When this interval is reached, UBI starts
@@ -114,9 +104,6 @@
 */
#define UBI_DT_THRESHOLD 120

/* Used when calculaing the lats erase timestamp of a PEB */
#define NUM_SEC_IN_DAY (60*60*24)

/*
 * The UBI debugfs directory name pattern and maximum name length (3 for "ubi"
 * + 2 for the number plus 1 for the trailing zero byte.
@@ -736,11 +723,6 @@ struct ubi_ainf_volume {
 * @ec_count: a temporary variable used when calculating @mean_ec
 * @failed_fm: set to true if fm faound invalid during attach
 * @aeb_slab_cache: slab cache for &struct ubi_ainf_peb objects
 * @mean_last_erase_time: mean late erase timestamp value
 * @last_erase_time_sum: temporary variable, used to calculate
 *				@mean_last_erase_time
 * @last_erase_time_count: temporary variable, used to calculate
 *				@mean_last_erase_time
 *
 * This data structure contains the result of attaching an MTD device and may
 * be used by other UBI sub-systems to build final UBI data structures, further
@@ -768,9 +750,6 @@ struct ubi_attach_info {
	int ec_count;
	int failed_fm;
	struct kmem_cache *aeb_slab_cache;
	long long  mean_last_erase_time;
	long long last_erase_time_sum;
	int last_erase_time_count;
};

/**
@@ -811,8 +790,7 @@ extern struct blocking_notifier_head ubi_notifiers;

/* attach.c */
int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
		  int ec, long last_erase_time, long rc,
		  const struct ubi_vid_hdr *vid_hdr, int bitflips);
		  int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips);
struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
				    int vol_id);
void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av);
Loading