mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-18 06:15:12 +00:00
Merge branch 'linux-next' of git://git.infradead.org/ubi-2.6
* 'linux-next' of git://git.infradead.org/ubi-2.6: UBI: tighten the corrupted PEB criteria UBI: fix check_data_ff return code UBI: remember copy_flag while scanning UBI: preserve corrupted PEBs UBI: add truly corrupted PEBs to corrupted list UBI: introduce debugging helper function UBI: make check_pattern function non-static UBI: do not put eraseblocks to the corrupted list unnecessarily UBI: separate out corrupted list UBI: change cascade of ifs to switch statements UBI: rename a local variable UBI: handle bit-flips when no header found UBI: remove duplicate IO error codes UBI: rename IO error code UBI: fix small 80 characters limit style issue UBI: cleanup and simplify Kconfig
This commit is contained in:
commit
4f3a29dada
@ -1,9 +1,5 @@
|
||||
menu "UBI - Unsorted block images"
|
||||
depends on MTD
|
||||
|
||||
config MTD_UBI
|
||||
tristate "Enable UBI"
|
||||
depends on MTD
|
||||
menuconfig MTD_UBI
|
||||
tristate "Enable UBI - Unsorted block images"
|
||||
select CRC32
|
||||
help
|
||||
UBI is a software layer above MTD layer which admits of LVM-like
|
||||
@ -12,11 +8,12 @@ config MTD_UBI
|
||||
capabilities. Please, consult the MTD web site for more details
|
||||
(www.linux-mtd.infradead.org).
|
||||
|
||||
if MTD_UBI
|
||||
|
||||
config MTD_UBI_WL_THRESHOLD
|
||||
int "UBI wear-leveling threshold"
|
||||
default 4096
|
||||
range 2 65536
|
||||
depends on MTD_UBI
|
||||
help
|
||||
This parameter defines the maximum difference between the highest
|
||||
erase counter value and the lowest erase counter value of eraseblocks
|
||||
@ -34,7 +31,6 @@ config MTD_UBI_BEB_RESERVE
|
||||
int "Percentage of reserved eraseblocks for bad eraseblocks handling"
|
||||
default 1
|
||||
range 0 25
|
||||
depends on MTD_UBI
|
||||
help
|
||||
If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI
|
||||
reserves some amount of physical eraseblocks to handle new bad
|
||||
@ -48,8 +44,6 @@ config MTD_UBI_BEB_RESERVE
|
||||
|
||||
config MTD_UBI_GLUEBI
|
||||
tristate "MTD devices emulation driver (gluebi)"
|
||||
default n
|
||||
depends on MTD_UBI
|
||||
help
|
||||
This option enables gluebi - an additional driver which emulates MTD
|
||||
devices on top of UBI volumes: for each UBI volumes an MTD device is
|
||||
@ -59,4 +53,5 @@ config MTD_UBI_GLUEBI
|
||||
software.
|
||||
|
||||
source "drivers/mtd/ubi/Kconfig.debug"
|
||||
endmenu
|
||||
|
||||
endif # MTD_UBI
|
||||
|
@ -1,94 +1,73 @@
|
||||
comment "UBI debugging options"
|
||||
depends on MTD_UBI
|
||||
|
||||
config MTD_UBI_DEBUG
|
||||
bool "UBI debugging"
|
||||
depends on SYSFS
|
||||
depends on MTD_UBI
|
||||
select DEBUG_FS
|
||||
select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL
|
||||
help
|
||||
This option enables UBI debugging.
|
||||
|
||||
if MTD_UBI_DEBUG
|
||||
|
||||
config MTD_UBI_DEBUG_MSG
|
||||
bool "UBI debugging messages"
|
||||
depends on MTD_UBI_DEBUG
|
||||
default n
|
||||
help
|
||||
This option enables UBI debugging messages.
|
||||
|
||||
config MTD_UBI_DEBUG_PARANOID
|
||||
bool "Extra self-checks"
|
||||
default n
|
||||
depends on MTD_UBI_DEBUG
|
||||
help
|
||||
This option enables extra checks in UBI code. Note this slows UBI down
|
||||
significantly.
|
||||
|
||||
config MTD_UBI_DEBUG_DISABLE_BGT
|
||||
bool "Do not enable the UBI background thread"
|
||||
depends on MTD_UBI_DEBUG
|
||||
default n
|
||||
help
|
||||
This option switches the background thread off by default. The thread
|
||||
may be also be enabled/disabled via UBI sysfs.
|
||||
|
||||
config MTD_UBI_DEBUG_EMULATE_BITFLIPS
|
||||
bool "Emulate flash bit-flips"
|
||||
depends on MTD_UBI_DEBUG
|
||||
default n
|
||||
help
|
||||
This option emulates bit-flips with probability 1/50, which in turn
|
||||
causes scrubbing. Useful for debugging and stressing UBI.
|
||||
|
||||
config MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES
|
||||
bool "Emulate flash write failures"
|
||||
depends on MTD_UBI_DEBUG
|
||||
default n
|
||||
help
|
||||
This option emulates write failures with probability 1/100. Useful for
|
||||
debugging and testing how UBI handlines errors.
|
||||
|
||||
config MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES
|
||||
bool "Emulate flash erase failures"
|
||||
depends on MTD_UBI_DEBUG
|
||||
default n
|
||||
help
|
||||
This option emulates erase failures with probability 1/100. Useful for
|
||||
debugging and testing how UBI handlines errors.
|
||||
|
||||
menu "Additional UBI debugging messages"
|
||||
depends on MTD_UBI_DEBUG
|
||||
comment "Additional UBI debugging messages"
|
||||
|
||||
config MTD_UBI_DEBUG_MSG_BLD
|
||||
bool "Additional UBI initialization and build messages"
|
||||
default n
|
||||
depends on MTD_UBI_DEBUG
|
||||
help
|
||||
This option enables detailed UBI initialization and device build
|
||||
debugging messages.
|
||||
|
||||
config MTD_UBI_DEBUG_MSG_EBA
|
||||
bool "Eraseblock association unit messages"
|
||||
default n
|
||||
depends on MTD_UBI_DEBUG
|
||||
help
|
||||
This option enables debugging messages from the UBI eraseblock
|
||||
association unit.
|
||||
|
||||
config MTD_UBI_DEBUG_MSG_WL
|
||||
bool "Wear-leveling unit messages"
|
||||
default n
|
||||
depends on MTD_UBI_DEBUG
|
||||
help
|
||||
This option enables debugging messages from the UBI wear-leveling
|
||||
unit.
|
||||
|
||||
config MTD_UBI_DEBUG_MSG_IO
|
||||
bool "Input/output unit messages"
|
||||
default n
|
||||
depends on MTD_UBI_DEBUG
|
||||
help
|
||||
This option enables debugging messages from the UBI input/output unit.
|
||||
|
||||
endmenu # UBI debugging messages
|
||||
endif # MTD_UBI_DEBUG
|
||||
|
@ -95,8 +95,8 @@ DEFINE_MUTEX(ubi_devices_mutex);
|
||||
static DEFINE_SPINLOCK(ubi_devices_lock);
|
||||
|
||||
/* "Show" method for files in '/<sysfs>/class/ubi/' */
|
||||
static ssize_t ubi_version_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
static ssize_t ubi_version_show(struct class *class,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", UBI_VERSION);
|
||||
}
|
||||
@ -591,6 +591,7 @@ static int attach_by_scanning(struct ubi_device *ubi)
|
||||
|
||||
ubi->bad_peb_count = si->bad_peb_count;
|
||||
ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count;
|
||||
ubi->corr_peb_count = si->corr_peb_count;
|
||||
ubi->max_ec = si->max_ec;
|
||||
ubi->mean_ec = si->mean_ec;
|
||||
ubi_msg("max. sequence number: %llu", si->max_sqnum);
|
||||
@ -972,6 +973,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
|
||||
ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20);
|
||||
ubi_msg("number of good PEBs: %d", ubi->good_peb_count);
|
||||
ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count);
|
||||
ubi_msg("number of corrupted PEBs: %d", ubi->corr_peb_count);
|
||||
ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots);
|
||||
ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD);
|
||||
ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT);
|
||||
|
@ -57,6 +57,9 @@ void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type);
|
||||
void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req);
|
||||
void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
|
||||
|
||||
#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \
|
||||
print_hex_dump(l, ps, pt, r, g, b, len, a)
|
||||
|
||||
#ifdef CONFIG_MTD_UBI_DEBUG_MSG
|
||||
/* General debugging messages */
|
||||
#define dbg_gen(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__)
|
||||
@ -172,6 +175,7 @@ static inline int ubi_dbg_is_erase_failure(void)
|
||||
#define ubi_dbg_dump_seb(seb, type) ({})
|
||||
#define ubi_dbg_dump_mkvol_req(req) ({})
|
||||
#define ubi_dbg_dump_flash(ubi, pnum, offset, len) ({})
|
||||
#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) ({})
|
||||
|
||||
#define UBI_IO_DEBUG 0
|
||||
#define DBG_DISABLE_BGT 0
|
||||
|
@ -418,7 +418,7 @@ retry:
|
||||
* may try to recover data. FIXME: but this is
|
||||
* not implemented.
|
||||
*/
|
||||
if (err == UBI_IO_BAD_HDR_READ ||
|
||||
if (err == UBI_IO_BAD_HDR_EBADMSG ||
|
||||
err == UBI_IO_BAD_HDR) {
|
||||
ubi_warn("corrupted VID header at PEB "
|
||||
"%d, LEB %d:%d", pnum, vol_id,
|
||||
@ -963,7 +963,7 @@ write_error:
|
||||
static int is_error_sane(int err)
|
||||
{
|
||||
if (err == -EIO || err == -ENOMEM || err == UBI_IO_BAD_HDR ||
|
||||
err == UBI_IO_BAD_HDR_READ || err == -ETIMEDOUT)
|
||||
err == UBI_IO_BAD_HDR_EBADMSG || err == -ETIMEDOUT)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@ -1201,6 +1201,9 @@ static void print_rsvd_warning(struct ubi_device *ubi,
|
||||
|
||||
ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d,"
|
||||
" need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level);
|
||||
if (ubi->corr_peb_count)
|
||||
ubi_warn("%d PEBs are corrupted and not used",
|
||||
ubi->corr_peb_count);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1263,6 +1266,9 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
|
||||
if (ubi->avail_pebs < EBA_RESERVED_PEBS) {
|
||||
ubi_err("no enough physical eraseblocks (%d, need %d)",
|
||||
ubi->avail_pebs, EBA_RESERVED_PEBS);
|
||||
if (ubi->corr_peb_count)
|
||||
ubi_err("%d PEBs are corrupted and not used",
|
||||
ubi->corr_peb_count);
|
||||
err = -ENOSPC;
|
||||
goto out_free;
|
||||
}
|
||||
|
@ -376,25 +376,6 @@ retry:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* check_pattern - check if buffer contains only a certain byte pattern.
|
||||
* @buf: buffer to check
|
||||
* @patt: the pattern to check
|
||||
* @size: buffer size in bytes
|
||||
*
|
||||
* This function returns %1 in there are only @patt bytes in @buf, and %0 if
|
||||
* something else was also found.
|
||||
*/
|
||||
static int check_pattern(const void *buf, uint8_t patt, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
if (((const uint8_t *)buf)[i] != patt)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Patterns to write to a physical eraseblock when torturing it */
|
||||
static uint8_t patterns[] = {0xa5, 0x5a, 0x0};
|
||||
|
||||
@ -426,7 +407,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum)
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size);
|
||||
err = ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size);
|
||||
if (err == 0) {
|
||||
ubi_err("erased PEB %d, but a non-0xFF byte found",
|
||||
pnum);
|
||||
@ -445,7 +426,8 @@ static int torture_peb(struct ubi_device *ubi, int pnum)
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = check_pattern(ubi->peb_buf1, patterns[i], ubi->peb_size);
|
||||
err = ubi_check_pattern(ubi->peb_buf1, patterns[i],
|
||||
ubi->peb_size);
|
||||
if (err == 0) {
|
||||
ubi_err("pattern %x checking failed for PEB %d",
|
||||
patterns[i], pnum);
|
||||
@ -517,7 +499,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
|
||||
* In this case we probably anyway have garbage in this PEB.
|
||||
*/
|
||||
err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
|
||||
if (err1 == UBI_IO_BAD_HDR_READ || err1 == UBI_IO_BAD_HDR)
|
||||
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
|
||||
/*
|
||||
* The VID header is corrupted, so we can safely erase this
|
||||
* PEB and not afraid that it will be treated as a valid PEB in
|
||||
@ -712,47 +694,47 @@ bad:
|
||||
* and corrected by the flash driver; this is harmless but may indicate that
|
||||
* this eraseblock may become bad soon (but may be not);
|
||||
* o %UBI_IO_BAD_HDR if the erase counter header is corrupted (a CRC error);
|
||||
* o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty;
|
||||
* o %UBI_IO_BAD_HDR_EBADMSG is the same as %UBI_IO_BAD_HDR, but there also was
|
||||
* a data integrity error (uncorrectable ECC error in case of NAND);
|
||||
* o %UBI_IO_FF if only 0xFF bytes were read (the PEB is supposedly empty)
|
||||
* o a negative error code in case of failure.
|
||||
*/
|
||||
int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
|
||||
struct ubi_ec_hdr *ec_hdr, int verbose)
|
||||
{
|
||||
int err, read_err = 0;
|
||||
int err, read_err;
|
||||
uint32_t crc, magic, hdr_crc;
|
||||
|
||||
dbg_io("read EC header from PEB %d", pnum);
|
||||
ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
|
||||
|
||||
err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);
|
||||
if (err) {
|
||||
if (err != UBI_IO_BITFLIPS && err != -EBADMSG)
|
||||
return err;
|
||||
read_err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);
|
||||
if (read_err) {
|
||||
if (read_err != UBI_IO_BITFLIPS && read_err != -EBADMSG)
|
||||
return read_err;
|
||||
|
||||
/*
|
||||
* We read all the data, but either a correctable bit-flip
|
||||
* occurred, or MTD reported about some data integrity error,
|
||||
* like an ECC error in case of NAND. The former is harmless,
|
||||
* the later may mean that the read data is corrupted. But we
|
||||
* have a CRC check-sum and we will detect this. If the EC
|
||||
* header is still OK, we just report this as there was a
|
||||
* bit-flip.
|
||||
* occurred, or MTD reported a data integrity error
|
||||
* (uncorrectable ECC error in case of NAND). The former is
|
||||
* harmless, the later may mean that the read data is
|
||||
* corrupted. But we have a CRC check-sum and we will detect
|
||||
* this. If the EC header is still OK, we just report this as
|
||||
* there was a bit-flip, to force scrubbing.
|
||||
*/
|
||||
if (err == -EBADMSG)
|
||||
read_err = UBI_IO_BAD_HDR_READ;
|
||||
}
|
||||
|
||||
magic = be32_to_cpu(ec_hdr->magic);
|
||||
if (magic != UBI_EC_HDR_MAGIC) {
|
||||
if (read_err)
|
||||
return read_err;
|
||||
if (read_err == -EBADMSG)
|
||||
return UBI_IO_BAD_HDR_EBADMSG;
|
||||
|
||||
/*
|
||||
* The magic field is wrong. Let's check if we have read all
|
||||
* 0xFF. If yes, this physical eraseblock is assumed to be
|
||||
* empty.
|
||||
*/
|
||||
if (check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) {
|
||||
if (ubi_check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) {
|
||||
/* The physical eraseblock is supposedly empty */
|
||||
if (verbose)
|
||||
ubi_warn("no EC header found at PEB %d, "
|
||||
@ -760,7 +742,10 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
|
||||
else if (UBI_IO_DEBUG)
|
||||
dbg_msg("no EC header found at PEB %d, "
|
||||
"only 0xFF bytes", pnum);
|
||||
return UBI_IO_PEB_EMPTY;
|
||||
if (!read_err)
|
||||
return UBI_IO_FF;
|
||||
else
|
||||
return UBI_IO_FF_BITFLIPS;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -788,7 +773,11 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
|
||||
} else if (UBI_IO_DEBUG)
|
||||
dbg_msg("bad EC header CRC at PEB %d, calculated "
|
||||
"%#08x, read %#08x", pnum, crc, hdr_crc);
|
||||
return read_err ?: UBI_IO_BAD_HDR;
|
||||
|
||||
if (!read_err)
|
||||
return UBI_IO_BAD_HDR;
|
||||
else
|
||||
return UBI_IO_BAD_HDR_EBADMSG;
|
||||
}
|
||||
|
||||
/* And of course validate what has just been read from the media */
|
||||
@ -975,22 +964,16 @@ bad:
|
||||
*
|
||||
* This function reads the volume identifier header from physical eraseblock
|
||||
* @pnum and stores it in @vid_hdr. It also checks CRC checksum of the read
|
||||
* volume identifier header. The following codes may be returned:
|
||||
* volume identifier header. The error codes are the same as in
|
||||
* 'ubi_io_read_ec_hdr()'.
|
||||
*
|
||||
* o %0 if the CRC checksum is correct and the header was successfully read;
|
||||
* o %UBI_IO_BITFLIPS if the CRC is correct, but bit-flips were detected
|
||||
* and corrected by the flash driver; this is harmless but may indicate that
|
||||
* this eraseblock may become bad soon;
|
||||
* o %UBI_IO_BAD_HDR if the volume identifier header is corrupted (a CRC
|
||||
* error detected);
|
||||
* o %UBI_IO_PEB_FREE if the physical eraseblock is free (i.e., there is no VID
|
||||
* header there);
|
||||
* o a negative error code in case of failure.
|
||||
* Note, the implementation of this function is also very similar to
|
||||
* 'ubi_io_read_ec_hdr()', so refer commentaries in 'ubi_io_read_ec_hdr()'.
|
||||
*/
|
||||
int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
|
||||
struct ubi_vid_hdr *vid_hdr, int verbose)
|
||||
{
|
||||
int err, read_err = 0;
|
||||
int err, read_err;
|
||||
uint32_t crc, magic, hdr_crc;
|
||||
void *p;
|
||||
|
||||
@ -998,48 +981,29 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
|
||||
ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
|
||||
|
||||
p = (char *)vid_hdr - ubi->vid_hdr_shift;
|
||||
err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
|
||||
read_err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
|
||||
ubi->vid_hdr_alsize);
|
||||
if (err) {
|
||||
if (err != UBI_IO_BITFLIPS && err != -EBADMSG)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* We read all the data, but either a correctable bit-flip
|
||||
* occurred, or MTD reported about some data integrity error,
|
||||
* like an ECC error in case of NAND. The former is harmless,
|
||||
* the later may mean the read data is corrupted. But we have a
|
||||
* CRC check-sum and we will identify this. If the VID header is
|
||||
* still OK, we just report this as there was a bit-flip.
|
||||
*/
|
||||
if (err == -EBADMSG)
|
||||
read_err = UBI_IO_BAD_HDR_READ;
|
||||
}
|
||||
if (read_err && read_err != UBI_IO_BITFLIPS && read_err != -EBADMSG)
|
||||
return read_err;
|
||||
|
||||
magic = be32_to_cpu(vid_hdr->magic);
|
||||
if (magic != UBI_VID_HDR_MAGIC) {
|
||||
if (read_err)
|
||||
return read_err;
|
||||
if (read_err == -EBADMSG)
|
||||
return UBI_IO_BAD_HDR_EBADMSG;
|
||||
|
||||
/*
|
||||
* If we have read all 0xFF bytes, the VID header probably does
|
||||
* not exist and the physical eraseblock is assumed to be free.
|
||||
*/
|
||||
if (check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {
|
||||
/* The physical eraseblock is supposedly free */
|
||||
if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {
|
||||
if (verbose)
|
||||
ubi_warn("no VID header found at PEB %d, "
|
||||
"only 0xFF bytes", pnum);
|
||||
else if (UBI_IO_DEBUG)
|
||||
dbg_msg("no VID header found at PEB %d, "
|
||||
"only 0xFF bytes", pnum);
|
||||
return UBI_IO_PEB_FREE;
|
||||
if (!read_err)
|
||||
return UBI_IO_FF;
|
||||
else
|
||||
return UBI_IO_FF_BITFLIPS;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is not a valid VID header, and these are not 0xFF
|
||||
* bytes. Report that the header is corrupted.
|
||||
*/
|
||||
if (verbose) {
|
||||
ubi_warn("bad magic number at PEB %d: %08x instead of "
|
||||
"%08x", pnum, magic, UBI_VID_HDR_MAGIC);
|
||||
@ -1061,20 +1025,18 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
|
||||
} else if (UBI_IO_DEBUG)
|
||||
dbg_msg("bad CRC at PEB %d, calculated %#08x, "
|
||||
"read %#08x", pnum, crc, hdr_crc);
|
||||
return read_err ?: UBI_IO_BAD_HDR;
|
||||
if (!read_err)
|
||||
return UBI_IO_BAD_HDR;
|
||||
else
|
||||
return UBI_IO_BAD_HDR_EBADMSG;
|
||||
}
|
||||
|
||||
/* Validate the VID header that we have just read */
|
||||
err = validate_vid_hdr(ubi, vid_hdr);
|
||||
if (err) {
|
||||
ubi_err("validation failed for PEB %d", pnum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there was a read error (%-EBADMSG), but the header CRC is still
|
||||
* OK, report about a bit-flip to force scrubbing on this PEB.
|
||||
*/
|
||||
return read_err ? UBI_IO_BITFLIPS : 0;
|
||||
}
|
||||
|
||||
@ -1383,7 +1345,7 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = check_pattern(ubi->dbg_peb_buf, 0xFF, len);
|
||||
err = ubi_check_pattern(ubi->dbg_peb_buf, 0xFF, len);
|
||||
if (err == 0) {
|
||||
ubi_err("flash region at PEB %d:%d, length %d does not "
|
||||
"contain all 0xFF bytes", pnum, offset, len);
|
||||
|
@ -103,3 +103,22 @@ void ubi_calculate_reserved(struct ubi_device *ubi)
|
||||
if (ubi->beb_rsvd_level < MIN_RESEVED_PEBS)
|
||||
ubi->beb_rsvd_level = MIN_RESEVED_PEBS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ubi_check_pattern - check if buffer contains only a certain byte pattern.
|
||||
* @buf: buffer to check
|
||||
* @patt: the pattern to check
|
||||
* @size: buffer size in bytes
|
||||
*
|
||||
* This function returns %1 in there are only @patt bytes in @buf, and %0 if
|
||||
* something else was also found.
|
||||
*/
|
||||
int ubi_check_pattern(const void *buf, uint8_t patt, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
if (((const uint8_t *)buf)[i] != patt)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
* objects which are kept in volume RB-tree with root at the @volumes field.
|
||||
* The RB-tree is indexed by the volume ID.
|
||||
*
|
||||
* Found logical eraseblocks are represented by &struct ubi_scan_leb objects.
|
||||
* Scanned logical eraseblocks are represented by &struct ubi_scan_leb objects.
|
||||
* These objects are kept in per-volume RB-trees with the root at the
|
||||
* corresponding &struct ubi_scan_volume object. To put it differently, we keep
|
||||
* an RB-tree of per-volume objects and each of these objects is the root of
|
||||
@ -38,6 +38,33 @@
|
||||
* Corrupted physical eraseblocks are put to the @corr list, free physical
|
||||
* eraseblocks are put to the @free list and the physical eraseblock to be
|
||||
* erased are put to the @erase list.
|
||||
*
|
||||
* UBI tries to distinguish between 2 types of corruptions.
|
||||
* 1. Corruptions caused by power cuts. These are harmless and expected
|
||||
* corruptions and UBI tries to handle them gracefully, without printing too
|
||||
* many warnings and error messages. The idea is that we do not lose
|
||||
* important data in these case - we may lose only the data which was being
|
||||
* written to the media just before the power cut happened, and the upper
|
||||
* layers (e.g., UBIFS) are supposed to handle these situations. UBI puts
|
||||
* these PEBs to the head of the @erase list and they are scheduled for
|
||||
* erasure.
|
||||
*
|
||||
* 2. Unexpected corruptions which are not caused by power cuts. During
|
||||
* scanning, such PEBs are put to the @corr list and UBI preserves them.
|
||||
* Obviously, this lessens the amount of available PEBs, and if at some
|
||||
* point UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly
|
||||
* informs about such PEBs every time the MTD device is attached.
|
||||
*
|
||||
* However, it is difficult to reliably distinguish between these types of
|
||||
* corruptions and UBI's strategy is as follows. UBI assumes (2.) if the VID
|
||||
* header is corrupted and the data area does not contain all 0xFFs, and there
|
||||
* were not bit-flips or integrity errors while reading the data area. Otherwise
|
||||
* UBI assumes (1.). The assumptions are:
|
||||
* o if the data area contains only 0xFFs, there is no data, and it is safe
|
||||
* to just erase this PEB.
|
||||
* o if the data area has bit-flips and data integrity errors (ECC errors on
|
||||
* NAND), it is probably a PEB which was being erased when power cut
|
||||
* happened.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
@ -62,26 +89,26 @@ static struct ubi_vid_hdr *vidh;
|
||||
* @si: scanning information
|
||||
* @pnum: physical eraseblock number to add
|
||||
* @ec: erase counter of the physical eraseblock
|
||||
* @to_head: if not zero, add to the head of the list
|
||||
* @list: the list to add to
|
||||
*
|
||||
* This function adds physical eraseblock @pnum to free, erase, corrupted or
|
||||
* alien lists. Returns zero in case of success and a negative error code in
|
||||
* case of failure.
|
||||
* This function adds physical eraseblock @pnum to free, erase, or alien lists.
|
||||
* If @to_head is not zero, PEB will be added to the head of the list, which
|
||||
* basically means it will be processed first later. E.g., we add corrupted
|
||||
* PEBs (corrupted due to power cuts) to the head of the erase list to make
|
||||
* sure we erase them first and get rid of corruptions ASAP. This function
|
||||
* returns zero in case of success and a negative error code in case of
|
||||
* failure.
|
||||
*/
|
||||
static int add_to_list(struct ubi_scan_info *si, int pnum, int ec,
|
||||
static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head,
|
||||
struct list_head *list)
|
||||
{
|
||||
struct ubi_scan_leb *seb;
|
||||
|
||||
if (list == &si->free) {
|
||||
dbg_bld("add to free: PEB %d, EC %d", pnum, ec);
|
||||
si->free_peb_count += 1;
|
||||
} else if (list == &si->erase) {
|
||||
dbg_bld("add to erase: PEB %d, EC %d", pnum, ec);
|
||||
si->erase_peb_count += 1;
|
||||
} else if (list == &si->corr) {
|
||||
dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec);
|
||||
si->corr_peb_count += 1;
|
||||
} else if (list == &si->alien) {
|
||||
dbg_bld("add to alien: PEB %d, EC %d", pnum, ec);
|
||||
si->alien_peb_count += 1;
|
||||
@ -94,7 +121,37 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec,
|
||||
|
||||
seb->pnum = pnum;
|
||||
seb->ec = ec;
|
||||
list_add_tail(&seb->u.list, list);
|
||||
if (to_head)
|
||||
list_add(&seb->u.list, list);
|
||||
else
|
||||
list_add_tail(&seb->u.list, list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_corrupted - add a corrupted physical eraseblock.
|
||||
* @si: scanning information
|
||||
* @pnum: physical eraseblock number to add
|
||||
* @ec: erase counter of the physical eraseblock
|
||||
*
|
||||
* This function adds corrupted physical eraseblock @pnum 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_scan_info *si, int pnum, int ec)
|
||||
{
|
||||
struct ubi_scan_leb *seb;
|
||||
|
||||
dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec);
|
||||
|
||||
seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL);
|
||||
if (!seb)
|
||||
return -ENOMEM;
|
||||
|
||||
si->corr_peb_count += 1;
|
||||
seb->pnum = pnum;
|
||||
seb->ec = ec;
|
||||
list_add(&seb->u.list, &si->corr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -258,8 +315,8 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb,
|
||||
* created before sequence numbers support has been added. At
|
||||
* that times we used 32-bit LEB versions stored in logical
|
||||
* eraseblocks. That was before UBI got into mainline. We do not
|
||||
* support these images anymore. Well, those images will work
|
||||
* still work, but only if no unclean reboots happened.
|
||||
* support these images anymore. Well, those images still work,
|
||||
* but only if no unclean reboots happened.
|
||||
*/
|
||||
ubi_err("unsupported on-flash UBI format\n");
|
||||
return -EINVAL;
|
||||
@ -285,19 +342,25 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb,
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
pnum = seb->pnum;
|
||||
if (!seb->copy_flag) {
|
||||
/* It is not a copy, so it is newer */
|
||||
dbg_bld("first PEB %d is newer, copy_flag is unset",
|
||||
pnum);
|
||||
return bitflips << 1;
|
||||
}
|
||||
|
||||
vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
|
||||
if (!vh)
|
||||
return -ENOMEM;
|
||||
|
||||
pnum = seb->pnum;
|
||||
err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
|
||||
if (err) {
|
||||
if (err == UBI_IO_BITFLIPS)
|
||||
bitflips = 1;
|
||||
else {
|
||||
dbg_err("VID of PEB %d header is bad, but it "
|
||||
"was OK earlier", pnum);
|
||||
"was OK earlier, err %d", pnum, err);
|
||||
if (err > 0)
|
||||
err = -EIO;
|
||||
|
||||
@ -305,14 +368,6 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb,
|
||||
}
|
||||
}
|
||||
|
||||
if (!vh->copy_flag) {
|
||||
/* It is not a copy, so it is newer */
|
||||
dbg_bld("first PEB %d is newer, copy_flag is unset",
|
||||
pnum);
|
||||
err = bitflips << 1;
|
||||
goto out_free_vidh;
|
||||
}
|
||||
|
||||
vid_hdr = vh;
|
||||
}
|
||||
|
||||
@ -463,18 +518,15 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (cmp_res & 4)
|
||||
err = add_to_list(si, seb->pnum, seb->ec,
|
||||
&si->corr);
|
||||
else
|
||||
err = add_to_list(si, seb->pnum, seb->ec,
|
||||
&si->erase);
|
||||
err = add_to_list(si, seb->pnum, seb->ec, cmp_res & 4,
|
||||
&si->erase);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
seb->ec = ec;
|
||||
seb->pnum = pnum;
|
||||
seb->scrub = ((cmp_res & 2) || bitflips);
|
||||
seb->copy_flag = vid_hdr->copy_flag;
|
||||
seb->sqnum = sqnum;
|
||||
|
||||
if (sv->highest_lnum == lnum)
|
||||
@ -487,10 +539,8 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
* This logical eraseblock is older than the one found
|
||||
* previously.
|
||||
*/
|
||||
if (cmp_res & 4)
|
||||
return add_to_list(si, pnum, ec, &si->corr);
|
||||
else
|
||||
return add_to_list(si, pnum, ec, &si->erase);
|
||||
return add_to_list(si, pnum, ec, cmp_res & 4,
|
||||
&si->erase);
|
||||
}
|
||||
}
|
||||
|
||||
@ -510,8 +560,9 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
seb->ec = ec;
|
||||
seb->pnum = pnum;
|
||||
seb->lnum = lnum;
|
||||
seb->sqnum = sqnum;
|
||||
seb->scrub = bitflips;
|
||||
seb->copy_flag = vid_hdr->copy_flag;
|
||||
seb->sqnum = sqnum;
|
||||
|
||||
if (sv->highest_lnum <= lnum) {
|
||||
sv->highest_lnum = lnum;
|
||||
@ -521,7 +572,6 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
sv->leb_count += 1;
|
||||
rb_link_node(&seb->u.rb, parent, p);
|
||||
rb_insert_color(&seb->u.rb, &sv->root);
|
||||
si->used_peb_count += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -668,8 +718,8 @@ out_free:
|
||||
struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi,
|
||||
struct ubi_scan_info *si)
|
||||
{
|
||||
int err = 0, i;
|
||||
struct ubi_scan_leb *seb;
|
||||
int err = 0;
|
||||
struct ubi_scan_leb *seb, *tmp_seb;
|
||||
|
||||
if (!list_empty(&si->free)) {
|
||||
seb = list_entry(si->free.next, struct ubi_scan_leb, u.list);
|
||||
@ -678,40 +728,88 @@ struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi,
|
||||
return seb;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct list_head *head;
|
||||
struct ubi_scan_leb *tmp_seb;
|
||||
/*
|
||||
* We try to erase the first physical eraseblock from the erase list
|
||||
* and pick it if we succeed, or try to erase the next one if not. And
|
||||
* so forth. We don't want to take care about bad eraseblocks here -
|
||||
* they'll be handled later.
|
||||
*/
|
||||
list_for_each_entry_safe(seb, tmp_seb, &si->erase, u.list) {
|
||||
if (seb->ec == UBI_SCAN_UNKNOWN_EC)
|
||||
seb->ec = si->mean_ec;
|
||||
|
||||
if (i == 0)
|
||||
head = &si->erase;
|
||||
else
|
||||
head = &si->corr;
|
||||
err = ubi_scan_erase_peb(ubi, si, seb->pnum, seb->ec+1);
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We try to erase the first physical eraseblock from the @head
|
||||
* list and pick it if we succeed, or try to erase the
|
||||
* next one if not. And so forth. We don't want to take care
|
||||
* about bad eraseblocks here - they'll be handled later.
|
||||
*/
|
||||
list_for_each_entry_safe(seb, tmp_seb, head, u.list) {
|
||||
if (seb->ec == UBI_SCAN_UNKNOWN_EC)
|
||||
seb->ec = si->mean_ec;
|
||||
|
||||
err = ubi_scan_erase_peb(ubi, si, seb->pnum, seb->ec+1);
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
seb->ec += 1;
|
||||
list_del(&seb->u.list);
|
||||
dbg_bld("return PEB %d, EC %d", seb->pnum, seb->ec);
|
||||
return seb;
|
||||
}
|
||||
seb->ec += 1;
|
||||
list_del(&seb->u.list);
|
||||
dbg_bld("return PEB %d, EC %d", seb->pnum, seb->ec);
|
||||
return seb;
|
||||
}
|
||||
|
||||
ubi_err("no eraseblocks found");
|
||||
ubi_err("no free eraseblocks");
|
||||
return ERR_PTR(-ENOSPC);
|
||||
}
|
||||
|
||||
/**
|
||||
* check_corruption - check the data area of PEB.
|
||||
* @ubi: UBI device description object
|
||||
* @vid_hrd: the (corrupted) VID header of this PEB
|
||||
* @pnum: the physical eraseblock number to check
|
||||
*
|
||||
* This is a helper function which is used to distinguish between VID header
|
||||
* corruptions caused by power cuts and other reasons. If the PEB contains only
|
||||
* 0xFF bytes in the data area, the VID header is most probably corrupted
|
||||
* because of a power cut (%0 is returned in this case). Otherwise, it was
|
||||
* probably corrupted for some other reasons (%1 is returned in this case). A
|
||||
* negative error code is returned if a read error occurred.
|
||||
*
|
||||
* If the corruption reason was a power cut, UBI can safely erase this PEB.
|
||||
* Otherwise, it should preserve it to avoid possibly destroying important
|
||||
* information.
|
||||
*/
|
||||
static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
|
||||
int pnum)
|
||||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&ubi->buf_mutex);
|
||||
memset(ubi->peb_buf1, 0x00, ubi->leb_size);
|
||||
|
||||
err = ubi_io_read(ubi, ubi->peb_buf1, pnum, ubi->leb_start,
|
||||
ubi->leb_size);
|
||||
if (err == UBI_IO_BITFLIPS || err == -EBADMSG) {
|
||||
/*
|
||||
* Bit-flips or integrity errors while reading the data area.
|
||||
* It is difficult to say for sure what type of corruption is
|
||||
* this, but presumably a power cut happened while this PEB was
|
||||
* erased, so it became unstable and corrupted, and should be
|
||||
* erased.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) {
|
||||
mutex_unlock(&ubi->buf_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ubi_err("PEB %d contains corrupted VID header, and the data does not "
|
||||
"contain all 0xFF, this may be a non-UBI PEB or a severe VID "
|
||||
"header corruption which requires manual inspection", pnum);
|
||||
ubi_dbg_dump_vid_hdr(vid_hdr);
|
||||
dbg_msg("hexdump of PEB %d offset %d, length %d",
|
||||
pnum, ubi->leb_start, ubi->leb_size);
|
||||
ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
|
||||
ubi->peb_buf1, ubi->leb_size, 1);
|
||||
mutex_unlock(&ubi->buf_mutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* process_eb - read, check UBI headers, and add them to scanning information.
|
||||
* @ubi: UBI device description object
|
||||
@ -725,7 +823,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
int pnum)
|
||||
{
|
||||
long long uninitialized_var(ec);
|
||||
int err, bitflips = 0, vol_id, ec_corr = 0;
|
||||
int err, bitflips = 0, vol_id, ec_err = 0;
|
||||
|
||||
dbg_bld("scan PEB %d", pnum);
|
||||
|
||||
@ -746,22 +844,37 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
else if (err == UBI_IO_BITFLIPS)
|
||||
switch (err) {
|
||||
case 0:
|
||||
break;
|
||||
case UBI_IO_BITFLIPS:
|
||||
bitflips = 1;
|
||||
else if (err == UBI_IO_PEB_EMPTY)
|
||||
return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, &si->erase);
|
||||
else if (err == UBI_IO_BAD_HDR_READ || err == UBI_IO_BAD_HDR) {
|
||||
break;
|
||||
case UBI_IO_FF:
|
||||
si->empty_peb_count += 1;
|
||||
return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, 0,
|
||||
&si->erase);
|
||||
case UBI_IO_FF_BITFLIPS:
|
||||
si->empty_peb_count += 1;
|
||||
return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, 1,
|
||||
&si->erase);
|
||||
case UBI_IO_BAD_HDR_EBADMSG:
|
||||
case UBI_IO_BAD_HDR:
|
||||
/*
|
||||
* We have to also look at the VID header, possibly it is not
|
||||
* corrupted. Set %bitflips flag in order to make this PEB be
|
||||
* moved and EC be re-created.
|
||||
*/
|
||||
ec_corr = err;
|
||||
ec_err = err;
|
||||
ec = UBI_SCAN_UNKNOWN_EC;
|
||||
bitflips = 1;
|
||||
break;
|
||||
default:
|
||||
ubi_err("'ubi_io_read_ec_hdr()' returned unknown code %d", err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!ec_corr) {
|
||||
if (!ec_err) {
|
||||
int image_seq;
|
||||
|
||||
/* Make sure UBI version is OK */
|
||||
@ -814,24 +927,67 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
err = ubi_io_read_vid_hdr(ubi, pnum, vidh, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
else if (err == UBI_IO_BITFLIPS)
|
||||
switch (err) {
|
||||
case 0:
|
||||
break;
|
||||
case UBI_IO_BITFLIPS:
|
||||
bitflips = 1;
|
||||
else if (err == UBI_IO_BAD_HDR_READ || err == UBI_IO_BAD_HDR ||
|
||||
(err == UBI_IO_PEB_FREE && ec_corr)) {
|
||||
/* VID header is corrupted */
|
||||
if (err == UBI_IO_BAD_HDR_READ ||
|
||||
ec_corr == UBI_IO_BAD_HDR_READ)
|
||||
si->read_err_count += 1;
|
||||
err = add_to_list(si, pnum, ec, &si->corr);
|
||||
break;
|
||||
case UBI_IO_BAD_HDR_EBADMSG:
|
||||
if (ec_err == UBI_IO_BAD_HDR_EBADMSG)
|
||||
/*
|
||||
* Both EC and VID headers are corrupted and were read
|
||||
* with data integrity error, probably this is a bad
|
||||
* PEB, bit it is not marked as bad yet. This may also
|
||||
* be a result of power cut during erasure.
|
||||
*/
|
||||
si->maybe_bad_peb_count += 1;
|
||||
case UBI_IO_BAD_HDR:
|
||||
if (ec_err)
|
||||
/*
|
||||
* Both headers are corrupted. There is a possibility
|
||||
* that this a valid UBI PEB which has corresponding
|
||||
* LEB, but the headers are corrupted. However, it is
|
||||
* impossible to distinguish it from a PEB which just
|
||||
* contains garbage because of a power cut during erase
|
||||
* operation. So we just schedule this PEB for erasure.
|
||||
*/
|
||||
err = 0;
|
||||
else
|
||||
/*
|
||||
* The EC was OK, but the VID header is corrupted. We
|
||||
* have to check what is in the data area.
|
||||
*/
|
||||
err = check_corruption(ubi, vidh, pnum);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
else if (!err)
|
||||
/* This corruption is caused by a power cut */
|
||||
err = add_to_list(si, pnum, ec, 1, &si->erase);
|
||||
else
|
||||
/* This is an unexpected corruption */
|
||||
err = add_corrupted(si, pnum, ec);
|
||||
if (err)
|
||||
return err;
|
||||
goto adjust_mean_ec;
|
||||
} else if (err == UBI_IO_PEB_FREE) {
|
||||
/* No VID header - the physical eraseblock is free */
|
||||
err = add_to_list(si, pnum, ec, &si->free);
|
||||
case UBI_IO_FF_BITFLIPS:
|
||||
err = add_to_list(si, pnum, ec, 1, &si->erase);
|
||||
if (err)
|
||||
return err;
|
||||
goto adjust_mean_ec;
|
||||
case UBI_IO_FF:
|
||||
if (ec_err)
|
||||
err = add_to_list(si, pnum, ec, 1, &si->erase);
|
||||
else
|
||||
err = add_to_list(si, pnum, ec, 0, &si->free);
|
||||
if (err)
|
||||
return err;
|
||||
goto adjust_mean_ec;
|
||||
default:
|
||||
ubi_err("'ubi_io_read_vid_hdr()' returned unknown code %d",
|
||||
err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vol_id = be32_to_cpu(vidh->vol_id);
|
||||
@ -843,7 +999,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
case UBI_COMPAT_DELETE:
|
||||
ubi_msg("\"delete\" compatible internal volume %d:%d"
|
||||
" found, will remove it", vol_id, lnum);
|
||||
err = add_to_list(si, pnum, ec, &si->erase);
|
||||
err = add_to_list(si, pnum, ec, 1, &si->erase);
|
||||
if (err)
|
||||
return err;
|
||||
return 0;
|
||||
@ -858,7 +1014,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
case UBI_COMPAT_PRESERVE:
|
||||
ubi_msg("\"preserve\" compatible internal volume %d:%d"
|
||||
" found", vol_id, lnum);
|
||||
err = add_to_list(si, pnum, ec, &si->alien);
|
||||
err = add_to_list(si, pnum, ec, 0, &si->alien);
|
||||
if (err)
|
||||
return err;
|
||||
return 0;
|
||||
@ -870,7 +1026,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
}
|
||||
}
|
||||
|
||||
if (ec_corr)
|
||||
if (ec_err)
|
||||
ubi_warn("valid VID header but corrupted EC header at PEB %d",
|
||||
pnum);
|
||||
err = ubi_scan_add_used(ubi, si, pnum, ec, vidh, bitflips);
|
||||
@ -878,7 +1034,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
|
||||
return err;
|
||||
|
||||
adjust_mean_ec:
|
||||
if (!ec_corr) {
|
||||
if (!ec_err) {
|
||||
si->ec_sum += ec;
|
||||
si->ec_count += 1;
|
||||
if (ec > si->max_ec)
|
||||
@ -904,19 +1060,20 @@ adjust_mean_ec:
|
||||
static int check_what_we_have(struct ubi_device *ubi, struct ubi_scan_info *si)
|
||||
{
|
||||
struct ubi_scan_leb *seb;
|
||||
int max_corr;
|
||||
int max_corr, peb_count;
|
||||
|
||||
max_corr = ubi->peb_count - si->bad_peb_count - si->alien_peb_count;
|
||||
max_corr = max_corr / 20 ?: 8;
|
||||
peb_count = ubi->peb_count - si->bad_peb_count - si->alien_peb_count;
|
||||
max_corr = peb_count / 20 ?: 8;
|
||||
|
||||
/*
|
||||
* Few corrupted PEBs are not a problem and may be just a result of
|
||||
* Few corrupted PEBs is not a problem and may be just a result of
|
||||
* unclean reboots. However, many of them may indicate some problems
|
||||
* with the flash HW or driver.
|
||||
*/
|
||||
if (si->corr_peb_count >= 8) {
|
||||
ubi_warn("%d PEBs are corrupted", si->corr_peb_count);
|
||||
printk(KERN_WARNING "corrupted PEBs are:");
|
||||
if (si->corr_peb_count) {
|
||||
ubi_err("%d PEBs are corrupted and preserved",
|
||||
si->corr_peb_count);
|
||||
printk(KERN_ERR "Corrupted PEBs are:");
|
||||
list_for_each_entry(seb, &si->corr, u.list)
|
||||
printk(KERN_CONT " %d", seb->pnum);
|
||||
printk(KERN_CONT "\n");
|
||||
@ -931,41 +1088,35 @@ static int check_what_we_have(struct ubi_device *ubi, struct ubi_scan_info *si)
|
||||
}
|
||||
}
|
||||
|
||||
if (si->free_peb_count + si->used_peb_count +
|
||||
si->alien_peb_count == 0) {
|
||||
/* No UBI-formatted eraseblocks were found */
|
||||
if (si->corr_peb_count == si->read_err_count &&
|
||||
si->corr_peb_count < 8) {
|
||||
/* No or just few corrupted PEBs, and all of them had a
|
||||
* read error. We assume that those are bad PEBs, which
|
||||
* were just not marked as bad so far.
|
||||
*
|
||||
* This piece of code basically tries to distinguish
|
||||
* between the following 2 situations:
|
||||
*
|
||||
* 1. Flash is empty, but there are few bad PEBs, which
|
||||
* are not marked as bad so far, and which were read
|
||||
* with error. We want to go ahead and format this
|
||||
* flash. While formating, the faulty PEBs will
|
||||
* probably be marked as bad.
|
||||
*
|
||||
* 2. Flash probably contains non-UBI data and we do
|
||||
* not want to format it and destroy possibly needed
|
||||
* data (e.g., consider the case when the bootloader
|
||||
* MTD partition was accidentally fed to UBI).
|
||||
*/
|
||||
if (si->empty_peb_count + si->maybe_bad_peb_count == peb_count) {
|
||||
/*
|
||||
* All PEBs are empty, or almost all - a couple PEBs look like
|
||||
* they may be bad PEBs which were not marked as bad yet.
|
||||
*
|
||||
* This piece of code basically tries to distinguish between
|
||||
* the following situations:
|
||||
*
|
||||
* 1. Flash is empty, but there are few bad PEBs, which are not
|
||||
* marked as bad so far, and which were read with error. We
|
||||
* want to go ahead and format this flash. While formatting,
|
||||
* the faulty PEBs will probably be marked as bad.
|
||||
*
|
||||
* 2. Flash contains non-UBI data and we do not want to format
|
||||
* it and destroy possibly important information.
|
||||
*/
|
||||
if (si->maybe_bad_peb_count <= 2) {
|
||||
si->is_empty = 1;
|
||||
ubi_msg("empty MTD device detected");
|
||||
get_random_bytes(&ubi->image_seq, sizeof(ubi->image_seq));
|
||||
get_random_bytes(&ubi->image_seq,
|
||||
sizeof(ubi->image_seq));
|
||||
} else {
|
||||
ubi_err("MTD device possibly contains non-UBI data, "
|
||||
"refusing it");
|
||||
ubi_err("MTD device is not UBI-formatted and possibly "
|
||||
"contains non-UBI data - refusing it");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (si->corr_peb_count > 0)
|
||||
ubi_msg("corrupted PEBs will be formatted");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
* @pnum: physical eraseblock number
|
||||
* @lnum: logical eraseblock number
|
||||
* @scrub: if this physical eraseblock needs scrubbing
|
||||
* @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB)
|
||||
* @sqnum: sequence number
|
||||
* @u: unions RB-tree or @list links
|
||||
* @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects
|
||||
@ -42,7 +43,8 @@ struct ubi_scan_leb {
|
||||
int ec;
|
||||
int pnum;
|
||||
int lnum;
|
||||
int scrub;
|
||||
unsigned int scrub:1;
|
||||
unsigned int copy_flag:1;
|
||||
unsigned long long sqnum;
|
||||
union {
|
||||
struct rb_node rb;
|
||||
@ -91,14 +93,13 @@ struct ubi_scan_volume {
|
||||
* @erase: list of physical eraseblocks which have to be erased
|
||||
* @alien: list of physical eraseblocks which should not be used by UBI (e.g.,
|
||||
* those belonging to "preserve"-compatible internal volumes)
|
||||
* @used_peb_count: count of used PEBs
|
||||
* @corr_peb_count: count of PEBs in the @corr list
|
||||
* @read_err_count: count of PEBs read with error (%UBI_IO_BAD_HDR_READ was
|
||||
* returned)
|
||||
* @free_peb_count: count of PEBs in the @free list
|
||||
* @erase_peb_count: count of PEBs in the @erase list
|
||||
* @empty_peb_count: count of PEBs which are presumably empty (contain only
|
||||
* 0xFF bytes)
|
||||
* @alien_peb_count: count of PEBs in the @alien list
|
||||
* @bad_peb_count: count of bad physical eraseblocks
|
||||
* @maybe_bad_peb_count: count of bad physical eraseblocks which are not marked
|
||||
* as bad yet, but which look like bad
|
||||
* @vols_found: number of volumes found during scanning
|
||||
* @highest_vol_id: highest volume ID
|
||||
* @is_empty: flag indicating whether the MTD device is empty or not
|
||||
@ -119,13 +120,11 @@ struct ubi_scan_info {
|
||||
struct list_head free;
|
||||
struct list_head erase;
|
||||
struct list_head alien;
|
||||
int used_peb_count;
|
||||
int corr_peb_count;
|
||||
int read_err_count;
|
||||
int free_peb_count;
|
||||
int erase_peb_count;
|
||||
int empty_peb_count;
|
||||
int alien_peb_count;
|
||||
int bad_peb_count;
|
||||
int maybe_bad_peb_count;
|
||||
int vols_found;
|
||||
int highest_vol_id;
|
||||
int is_empty;
|
||||
|
@ -85,21 +85,26 @@
|
||||
/*
|
||||
* Error codes returned by the I/O sub-system.
|
||||
*
|
||||
* UBI_IO_PEB_EMPTY: the physical eraseblock is empty, i.e. it contains only
|
||||
* %0xFF bytes
|
||||
* UBI_IO_PEB_FREE: the physical eraseblock is free, i.e. it contains only a
|
||||
* valid erase counter header, and the rest are %0xFF bytes
|
||||
* UBI_IO_FF: the read region of flash contains only 0xFFs
|
||||
* UBI_IO_FF_BITFLIPS: the same as %UBI_IO_FF, but also also there was a data
|
||||
* integrity error reported by the MTD driver
|
||||
* (uncorrectable ECC error in case of NAND)
|
||||
* UBI_IO_BAD_HDR: the EC or VID header is corrupted (bad magic or CRC)
|
||||
* UBI_IO_BAD_HDR_READ: the same as %UBI_IO_BAD_HDR, but also there was a read
|
||||
* error reported by the flash driver
|
||||
* UBI_IO_BAD_HDR_EBADMSG: the same as %UBI_IO_BAD_HDR, but also there was a
|
||||
* data integrity error reported by the MTD driver
|
||||
* (uncorrectable ECC error in case of NAND)
|
||||
* UBI_IO_BITFLIPS: bit-flips were detected and corrected
|
||||
*
|
||||
* Note, it is probably better to have bit-flip and ebadmsg as flags which can
|
||||
* be or'ed with other error code. But this is a big change because there are
|
||||
* may callers, so it does not worth the risk of introducing a bug
|
||||
*/
|
||||
enum {
|
||||
UBI_IO_PEB_EMPTY = 1,
|
||||
UBI_IO_PEB_FREE,
|
||||
UBI_IO_FF = 1,
|
||||
UBI_IO_FF_BITFLIPS,
|
||||
UBI_IO_BAD_HDR,
|
||||
UBI_IO_BAD_HDR_READ,
|
||||
UBI_IO_BITFLIPS
|
||||
UBI_IO_BAD_HDR_EBADMSG,
|
||||
UBI_IO_BITFLIPS,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -356,6 +361,8 @@ struct ubi_wl_entry;
|
||||
* @peb_size: physical eraseblock size
|
||||
* @bad_peb_count: count of bad physical eraseblocks
|
||||
* @good_peb_count: count of good physical eraseblocks
|
||||
* @corr_peb_count: count of corrupted physical eraseblocks (preserved and not
|
||||
* used by UBI)
|
||||
* @erroneous_peb_count: count of erroneous physical eraseblocks in @erroneous
|
||||
* @max_erroneous: maximum allowed amount of erroneous physical eraseblocks
|
||||
* @min_io_size: minimal input/output unit size of the underlying MTD device
|
||||
@ -442,6 +449,7 @@ struct ubi_device {
|
||||
int peb_size;
|
||||
int bad_peb_count;
|
||||
int good_peb_count;
|
||||
int corr_peb_count;
|
||||
int erroneous_peb_count;
|
||||
int max_erroneous;
|
||||
int min_io_size;
|
||||
@ -506,6 +514,7 @@ int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf,
|
||||
int length);
|
||||
int ubi_check_volume(struct ubi_device *ubi, int vol_id);
|
||||
void ubi_calculate_reserved(struct ubi_device *ubi);
|
||||
int ubi_check_pattern(const void *buf, uint8_t patt, int size);
|
||||
|
||||
/* eba.c */
|
||||
int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
|
||||
|
@ -261,6 +261,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
|
||||
/* Reserve physical eraseblocks */
|
||||
if (vol->reserved_pebs > ubi->avail_pebs) {
|
||||
dbg_err("not enough PEBs, only %d available", ubi->avail_pebs);
|
||||
if (ubi->corr_peb_count)
|
||||
dbg_err("%d PEBs are corrupted and not used",
|
||||
ubi->corr_peb_count);
|
||||
err = -ENOSPC;
|
||||
goto out_unlock;
|
||||
}
|
||||
@ -527,6 +530,9 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
|
||||
if (pebs > ubi->avail_pebs) {
|
||||
dbg_err("not enough PEBs: requested %d, available %d",
|
||||
pebs, ubi->avail_pebs);
|
||||
if (ubi->corr_peb_count)
|
||||
dbg_err("%d PEBs are corrupted and not used",
|
||||
ubi->corr_peb_count);
|
||||
spin_unlock(&ubi->volumes_lock);
|
||||
err = -ENOSPC;
|
||||
goto out_free;
|
||||
|
@ -366,7 +366,7 @@ write_error:
|
||||
* Probably this physical eraseblock went bad, try to pick
|
||||
* another one.
|
||||
*/
|
||||
list_add_tail(&new_seb->u.list, &si->corr);
|
||||
list_add(&new_seb->u.list, &si->erase);
|
||||
goto retry;
|
||||
}
|
||||
kfree(new_seb);
|
||||
@ -662,9 +662,13 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
|
||||
ubi->vol_count += 1;
|
||||
vol->ubi = ubi;
|
||||
|
||||
if (reserved_pebs > ubi->avail_pebs)
|
||||
if (reserved_pebs > ubi->avail_pebs) {
|
||||
ubi_err("not enough PEBs, required %d, available %d",
|
||||
reserved_pebs, ubi->avail_pebs);
|
||||
if (ubi->corr_peb_count)
|
||||
ubi_err("%d PEBs are corrupted and not used",
|
||||
ubi->corr_peb_count);
|
||||
}
|
||||
ubi->rsvd_pebs += reserved_pebs;
|
||||
ubi->avail_pebs -= reserved_pebs;
|
||||
|
||||
@ -837,7 +841,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
|
||||
return PTR_ERR(ubi->vtbl);
|
||||
}
|
||||
|
||||
ubi->avail_pebs = ubi->good_peb_count;
|
||||
ubi->avail_pebs = ubi->good_peb_count - ubi->corr_peb_count;
|
||||
|
||||
/*
|
||||
* The layout volume is OK, initialize the corresponding in-RAM data
|
||||
|
@ -745,7 +745,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
|
||||
|
||||
err = ubi_io_read_vid_hdr(ubi, e1->pnum, vid_hdr, 0);
|
||||
if (err && err != UBI_IO_BITFLIPS) {
|
||||
if (err == UBI_IO_PEB_FREE) {
|
||||
if (err == UBI_IO_FF) {
|
||||
/*
|
||||
* We are trying to move PEB without a VID header. UBI
|
||||
* always write VID headers shortly after the PEB was
|
||||
@ -759,6 +759,16 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
|
||||
dbg_wl("PEB %d has no VID header", e1->pnum);
|
||||
protect = 1;
|
||||
goto out_not_moved;
|
||||
} else if (err == UBI_IO_FF_BITFLIPS) {
|
||||
/*
|
||||
* The same situation as %UBI_IO_FF, but bit-flips were
|
||||
* detected. It is better to schedule this PEB for
|
||||
* scrubbing.
|
||||
*/
|
||||
dbg_wl("PEB %d has no VID header but has bit-flips",
|
||||
e1->pnum);
|
||||
scrubbing = 1;
|
||||
goto out_not_moved;
|
||||
}
|
||||
|
||||
ubi_err("error %d while reading VID header from PEB %d",
|
||||
@ -1468,22 +1478,6 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
|
||||
ubi->lookuptbl[e->pnum] = e;
|
||||
}
|
||||
|
||||
list_for_each_entry(seb, &si->corr, u.list) {
|
||||
cond_resched();
|
||||
|
||||
e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
|
||||
if (!e)
|
||||
goto out_free;
|
||||
|
||||
e->pnum = seb->pnum;
|
||||
e->ec = seb->ec;
|
||||
ubi->lookuptbl[e->pnum] = e;
|
||||
if (schedule_erase(ubi, e, 0)) {
|
||||
kmem_cache_free(ubi_wl_entry_slab, e);
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
|
||||
ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) {
|
||||
ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) {
|
||||
cond_resched();
|
||||
@ -1510,6 +1504,9 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
|
||||
if (ubi->avail_pebs < WL_RESERVED_PEBS) {
|
||||
ubi_err("no enough physical eraseblocks (%d, need %d)",
|
||||
ubi->avail_pebs, WL_RESERVED_PEBS);
|
||||
if (ubi->corr_peb_count)
|
||||
ubi_err("%d PEBs are corrupted and not used",
|
||||
ubi->corr_peb_count);
|
||||
goto out_free;
|
||||
}
|
||||
ubi->avail_pebs -= WL_RESERVED_PEBS;
|
||||
|
Loading…
x
Reference in New Issue
Block a user