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

Commit 5a181a30 authored by Tanya Brokhman's avatar Tanya Brokhman Committed by Gerrit - the friendly Code Review server
Browse files

Revert "mtd: ubi: Fill read disturb statistics"



This reverts commit fae74b62.

This patch is part of the "read-disturb implementation" set of patches. It
was decided to take different approach in addressing the read disturb,
thus the whole patch series is reverted in order to simplify the code and
reduce memory footprint.

Conflicts and compilation errors were addressed.

Change-Id: I129fa63bdbffa6c1881f1a4e702a443741b41d5f
Signed-off-by: default avatarTanya Brokhman <tlinder@codeaurora.org>
parent 3b5117d5
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