Commit 4f3a29da authored by Linus Torvalds's avatar Linus Torvalds

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
parents 06d36293 45aafd32
menu "UBI - Unsorted block images" menuconfig MTD_UBI
depends on MTD tristate "Enable UBI - Unsorted block images"
config MTD_UBI
tristate "Enable UBI"
depends on MTD
select CRC32 select CRC32
help help
UBI is a software layer above MTD layer which admits of LVM-like UBI is a software layer above MTD layer which admits of LVM-like
...@@ -12,11 +8,12 @@ config MTD_UBI ...@@ -12,11 +8,12 @@ config MTD_UBI
capabilities. Please, consult the MTD web site for more details capabilities. Please, consult the MTD web site for more details
(www.linux-mtd.infradead.org). (www.linux-mtd.infradead.org).
if MTD_UBI
config MTD_UBI_WL_THRESHOLD config MTD_UBI_WL_THRESHOLD
int "UBI wear-leveling threshold" int "UBI wear-leveling threshold"
default 4096 default 4096
range 2 65536 range 2 65536
depends on MTD_UBI
help help
This parameter defines the maximum difference between the highest This parameter defines the maximum difference between the highest
erase counter value and the lowest erase counter value of eraseblocks erase counter value and the lowest erase counter value of eraseblocks
...@@ -34,7 +31,6 @@ config MTD_UBI_BEB_RESERVE ...@@ -34,7 +31,6 @@ config MTD_UBI_BEB_RESERVE
int "Percentage of reserved eraseblocks for bad eraseblocks handling" int "Percentage of reserved eraseblocks for bad eraseblocks handling"
default 1 default 1
range 0 25 range 0 25
depends on MTD_UBI
help help
If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI
reserves some amount of physical eraseblocks to handle new bad reserves some amount of physical eraseblocks to handle new bad
...@@ -48,8 +44,6 @@ config MTD_UBI_BEB_RESERVE ...@@ -48,8 +44,6 @@ config MTD_UBI_BEB_RESERVE
config MTD_UBI_GLUEBI config MTD_UBI_GLUEBI
tristate "MTD devices emulation driver (gluebi)" tristate "MTD devices emulation driver (gluebi)"
default n
depends on MTD_UBI
help help
This option enables gluebi - an additional driver which emulates MTD This option enables gluebi - an additional driver which emulates MTD
devices on top of UBI volumes: for each UBI volumes an MTD device is devices on top of UBI volumes: for each UBI volumes an MTD device is
...@@ -59,4 +53,5 @@ config MTD_UBI_GLUEBI ...@@ -59,4 +53,5 @@ config MTD_UBI_GLUEBI
software. software.
source "drivers/mtd/ubi/Kconfig.debug" source "drivers/mtd/ubi/Kconfig.debug"
endmenu
endif # MTD_UBI
comment "UBI debugging options" comment "UBI debugging options"
depends on MTD_UBI
config MTD_UBI_DEBUG config MTD_UBI_DEBUG
bool "UBI debugging" bool "UBI debugging"
depends on SYSFS depends on SYSFS
depends on MTD_UBI
select DEBUG_FS select DEBUG_FS
select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL
help help
This option enables UBI debugging. This option enables UBI debugging.
if MTD_UBI_DEBUG
config MTD_UBI_DEBUG_MSG config MTD_UBI_DEBUG_MSG
bool "UBI debugging messages" bool "UBI debugging messages"
depends on MTD_UBI_DEBUG
default n
help help
This option enables UBI debugging messages. This option enables UBI debugging messages.
config MTD_UBI_DEBUG_PARANOID config MTD_UBI_DEBUG_PARANOID
bool "Extra self-checks" bool "Extra self-checks"
default n
depends on MTD_UBI_DEBUG
help help
This option enables extra checks in UBI code. Note this slows UBI down This option enables extra checks in UBI code. Note this slows UBI down
significantly. significantly.
config MTD_UBI_DEBUG_DISABLE_BGT config MTD_UBI_DEBUG_DISABLE_BGT
bool "Do not enable the UBI background thread" bool "Do not enable the UBI background thread"
depends on MTD_UBI_DEBUG
default n
help help
This option switches the background thread off by default. The thread This option switches the background thread off by default. The thread
may be also be enabled/disabled via UBI sysfs. may be also be enabled/disabled via UBI sysfs.
config MTD_UBI_DEBUG_EMULATE_BITFLIPS config MTD_UBI_DEBUG_EMULATE_BITFLIPS
bool "Emulate flash bit-flips" bool "Emulate flash bit-flips"
depends on MTD_UBI_DEBUG
default n
help help
This option emulates bit-flips with probability 1/50, which in turn This option emulates bit-flips with probability 1/50, which in turn
causes scrubbing. Useful for debugging and stressing UBI. causes scrubbing. Useful for debugging and stressing UBI.
config MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES config MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES
bool "Emulate flash write failures" bool "Emulate flash write failures"
depends on MTD_UBI_DEBUG
default n
help help
This option emulates write failures with probability 1/100. Useful for This option emulates write failures with probability 1/100. Useful for
debugging and testing how UBI handlines errors. debugging and testing how UBI handlines errors.
config MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES config MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES
bool "Emulate flash erase failures" bool "Emulate flash erase failures"
depends on MTD_UBI_DEBUG
default n
help help
This option emulates erase failures with probability 1/100. Useful for This option emulates erase failures with probability 1/100. Useful for
debugging and testing how UBI handlines errors. debugging and testing how UBI handlines errors.
menu "Additional UBI debugging messages" comment "Additional UBI debugging messages"
depends on MTD_UBI_DEBUG
config MTD_UBI_DEBUG_MSG_BLD config MTD_UBI_DEBUG_MSG_BLD
bool "Additional UBI initialization and build messages" bool "Additional UBI initialization and build messages"
default n
depends on MTD_UBI_DEBUG
help help
This option enables detailed UBI initialization and device build This option enables detailed UBI initialization and device build
debugging messages. debugging messages.
config MTD_UBI_DEBUG_MSG_EBA config MTD_UBI_DEBUG_MSG_EBA
bool "Eraseblock association unit messages" bool "Eraseblock association unit messages"
default n
depends on MTD_UBI_DEBUG
help help
This option enables debugging messages from the UBI eraseblock This option enables debugging messages from the UBI eraseblock
association unit. association unit.
config MTD_UBI_DEBUG_MSG_WL config MTD_UBI_DEBUG_MSG_WL
bool "Wear-leveling unit messages" bool "Wear-leveling unit messages"
default n
depends on MTD_UBI_DEBUG
help help
This option enables debugging messages from the UBI wear-leveling This option enables debugging messages from the UBI wear-leveling
unit. unit.
config MTD_UBI_DEBUG_MSG_IO config MTD_UBI_DEBUG_MSG_IO
bool "Input/output unit messages" bool "Input/output unit messages"
default n
depends on MTD_UBI_DEBUG
help help
This option enables debugging messages from the UBI input/output unit. 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); ...@@ -95,8 +95,8 @@ DEFINE_MUTEX(ubi_devices_mutex);
static DEFINE_SPINLOCK(ubi_devices_lock); static DEFINE_SPINLOCK(ubi_devices_lock);
/* "Show" method for files in '/<sysfs>/class/ubi/' */ /* "Show" method for files in '/<sysfs>/class/ubi/' */
static ssize_t ubi_version_show(struct class *class, struct class_attribute *attr, static ssize_t ubi_version_show(struct class *class,
char *buf) struct class_attribute *attr, char *buf)
{ {
return sprintf(buf, "%d\n", UBI_VERSION); return sprintf(buf, "%d\n", UBI_VERSION);
} }
...@@ -591,6 +591,7 @@ static int attach_by_scanning(struct ubi_device *ubi) ...@@ -591,6 +591,7 @@ static int attach_by_scanning(struct ubi_device *ubi)
ubi->bad_peb_count = si->bad_peb_count; ubi->bad_peb_count = si->bad_peb_count;
ubi->good_peb_count = ubi->peb_count - ubi->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->max_ec = si->max_ec;
ubi->mean_ec = si->mean_ec; ubi->mean_ec = si->mean_ec;
ubi_msg("max. sequence number: %llu", si->max_sqnum); 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) ...@@ -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("MTD device size: %llu MiB", ubi->flash_size >> 20);
ubi_msg("number of good PEBs: %d", ubi->good_peb_count); 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 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("max. allowed volumes: %d", ubi->vtbl_slots);
ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD);
ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); 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); ...@@ -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_mkvol_req(const struct ubi_mkvol_req *req);
void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); 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 #ifdef CONFIG_MTD_UBI_DEBUG_MSG
/* General debugging messages */ /* General debugging messages */
#define dbg_gen(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) #define dbg_gen(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__)
...@@ -172,6 +175,7 @@ static inline int ubi_dbg_is_erase_failure(void) ...@@ -172,6 +175,7 @@ static inline int ubi_dbg_is_erase_failure(void)
#define ubi_dbg_dump_seb(seb, type) ({}) #define ubi_dbg_dump_seb(seb, type) ({})
#define ubi_dbg_dump_mkvol_req(req) ({}) #define ubi_dbg_dump_mkvol_req(req) ({})
#define ubi_dbg_dump_flash(ubi, pnum, offset, len) ({}) #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 UBI_IO_DEBUG 0
#define DBG_DISABLE_BGT 0 #define DBG_DISABLE_BGT 0
......
...@@ -418,7 +418,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, ...@@ -418,7 +418,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
* may try to recover data. FIXME: but this is * may try to recover data. FIXME: but this is
* not implemented. * not implemented.
*/ */
if (err == UBI_IO_BAD_HDR_READ || if (err == UBI_IO_BAD_HDR_EBADMSG ||
err == UBI_IO_BAD_HDR) { err == UBI_IO_BAD_HDR) {
ubi_warn("corrupted VID header at PEB " ubi_warn("corrupted VID header at PEB "
"%d, LEB %d:%d", pnum, vol_id, "%d, LEB %d:%d", pnum, vol_id,
...@@ -963,7 +963,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -963,7 +963,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
static int is_error_sane(int err) static int is_error_sane(int err)
{ {
if (err == -EIO || err == -ENOMEM || err == UBI_IO_BAD_HDR || 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 0;
return 1; return 1;
} }
...@@ -1201,6 +1201,9 @@ static void print_rsvd_warning(struct ubi_device *ubi, ...@@ -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," ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d,"
" need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); " 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) ...@@ -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) { if (ubi->avail_pebs < EBA_RESERVED_PEBS) {
ubi_err("no enough physical eraseblocks (%d, need %d)", ubi_err("no enough physical eraseblocks (%d, need %d)",
ubi->avail_pebs, EBA_RESERVED_PEBS); 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; err = -ENOSPC;
goto out_free; goto out_free;
} }
......
...@@ -376,25 +376,6 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum) ...@@ -376,25 +376,6 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum)
return 0; 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 */ /* Patterns to write to a physical eraseblock when torturing it */
static uint8_t patterns[] = {0xa5, 0x5a, 0x0}; static uint8_t patterns[] = {0xa5, 0x5a, 0x0};
...@@ -426,7 +407,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) ...@@ -426,7 +407,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum)
if (err) if (err)
goto out; 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) { if (err == 0) {
ubi_err("erased PEB %d, but a non-0xFF byte found", ubi_err("erased PEB %d, but a non-0xFF byte found",
pnum); pnum);
...@@ -445,7 +426,8 @@ static int torture_peb(struct ubi_device *ubi, int pnum) ...@@ -445,7 +426,8 @@ static int torture_peb(struct ubi_device *ubi, int pnum)
if (err) if (err)
goto out; 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) { if (err == 0) {
ubi_err("pattern %x checking failed for PEB %d", ubi_err("pattern %x checking failed for PEB %d",
patterns[i], pnum); patterns[i], pnum);
...@@ -517,7 +499,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int 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. * In this case we probably anyway have garbage in this PEB.
*/ */
err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); 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 * 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 * PEB and not afraid that it will be treated as a valid PEB in
...@@ -712,47 +694,47 @@ static int validate_ec_hdr(const struct ubi_device *ubi, ...@@ -712,47 +694,47 @@ static int validate_ec_hdr(const struct ubi_device *ubi,
* and corrected by the flash driver; this is harmless but may indicate that * and corrected by the flash driver; this is harmless but may indicate that
* this eraseblock may become bad soon (but may be not); * 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_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. * o a negative error code in case of failure.
*/ */
int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
struct ubi_ec_hdr *ec_hdr, int verbose) struct ubi_ec_hdr *ec_hdr, int verbose)
{ {
int err, read_err = 0; int err, read_err;
uint32_t crc, magic, hdr_crc; uint32_t crc, magic, hdr_crc;
dbg_io("read EC header from PEB %d", pnum); dbg_io("read EC header from PEB %d", pnum);
ubi_assert(pnum >= 0 && pnum < ubi->peb_count); ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); read_err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);
if (err) { if (read_err) {
if (err != UBI_IO_BITFLIPS && err != -EBADMSG) if (read_err != UBI_IO_BITFLIPS && read_err != -EBADMSG)
return err; return read_err;
/* /*
* We read all the data, but either a correctable bit-flip * We read all the data, but either a correctable bit-flip
* occurred, or MTD reported about some data integrity error, * occurred, or MTD reported a data integrity error
* like an ECC error in case of NAND. The former is harmless, * (uncorrectable ECC error in case of NAND). The former is
* the later may mean that the read data is corrupted. But we * harmless, the later may mean that the read data is
* have a CRC check-sum and we will detect this. If the EC * corrupted. But we have a CRC check-sum and we will detect
* header is still OK, we just report this as there was a * this. If the EC header is still OK, we just report this as
* bit-flip. * 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); magic = be32_to_cpu(ec_hdr->magic);
if (magic != UBI_EC_HDR_MAGIC) { if (magic != UBI_EC_HDR_MAGIC) {
if (read_err) if (read_err == -EBADMSG)
return read_err; return UBI_IO_BAD_HDR_EBADMSG;
/* /*
* The magic field is wrong. Let's check if we have read all * The magic field is wrong. Let's check if we have read all
* 0xFF. If yes, this physical eraseblock is assumed to be * 0xFF. If yes, this physical eraseblock is assumed to be
* empty. * 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 */ /* The physical eraseblock is supposedly empty */
if (verbose) if (verbose)
ubi_warn("no EC header found at PEB %d, " 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, ...@@ -760,7 +742,10 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
else if (UBI_IO_DEBUG) else if (UBI_IO_DEBUG)
dbg_msg("no EC header found at PEB %d, " dbg_msg("no EC header found at PEB %d, "
"only 0xFF bytes", pnum); "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, ...@@ -788,7 +773,11 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
} else if (UBI_IO_DEBUG) } else if (UBI_IO_DEBUG)
dbg_msg("bad EC header CRC at PEB %d, calculated " dbg_msg("bad EC header CRC at PEB %d, calculated "
"%#08x, read %#08x", pnum, crc, hdr_crc); "%#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 */ /* And of course validate what has just been read from the media */
...@@ -975,22 +964,16 @@ static int validate_vid_hdr(const struct ubi_device *ubi, ...@@ -975,22 +964,16 @@ static int validate_vid_hdr(const struct ubi_device *ubi,
* *
* This function reads the volume identifier header from physical eraseblock * 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 * @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; * Note, the implementation of this function is also very similar to
* o %UBI_IO_BITFLIPS if the CRC is correct, but bit-flips were detected * 'ubi_io_read_ec_hdr()', so refer commentaries in 'ubi_io_read_ec_hdr()'.
* 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.
*/ */
int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
struct ubi_vid_hdr *vid_hdr, int verbose) struct ubi_vid_hdr *vid_hdr, int verbose)
{ {
int err, read_err = 0; int err, read_err;
uint32_t crc, magic, hdr_crc; uint32_t crc, magic, hdr_crc;
void *p; void *p;
...@@ -998,48 +981,29 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -998,48 +981,29 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
ubi_assert(pnum >= 0 && pnum < ubi->peb_count); ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
p = (char *)vid_hdr - ubi->vid_hdr_shift; 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); ubi->vid_hdr_alsize);
if (err) { if (read_err && read_err != UBI_IO_BITFLIPS && read_err != -EBADMSG)
if (err != UBI_IO_BITFLIPS && err != -EBADMSG) return read_err;
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;
}
magic = be32_to_cpu(vid_hdr->magic); magic = be32_to_cpu(vid_hdr->magic);
if (magic != UBI_VID_HDR_MAGIC) { if (magic != UBI_VID_HDR_MAGIC) {
if (read_err) if (read_err == -EBADMSG)
return read_err; return UBI_IO_BAD_HDR_EBADMSG;
/* if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {
* 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 (verbose) if (verbose)
ubi_warn("no VID header found at PEB %d, " ubi_warn("no VID header found at PEB %d, "
"only 0xFF bytes", pnum); "only 0xFF bytes", pnum);
else if (UBI_IO_DEBUG) else if (UBI_IO_DEBUG)
dbg_msg("no VID header found at PEB %d, " dbg_msg("no VID header found at PEB %d, "
"only 0xFF bytes", pnum); "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) { if (verbose) {
ubi_warn("bad magic number at PEB %d: %08x instead of " ubi_warn("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_VID_HDR_MAGIC); "%08x", pnum, magic, UBI_VID_HDR_MAGIC);
...@@ -1061,20 +1025,18 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -1061,20 +1025,18 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
} else if (UBI_IO_DEBUG) } else if (UBI_IO_DEBUG)
dbg_msg("bad CRC at PEB %d, calculated %#08x, " dbg_msg("bad CRC at PEB %d, calculated %#08x, "
"read %#08x", pnum, crc, hdr_crc); "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); err = validate_vid_hdr(ubi, vid_hdr);
if (err) { if (err) {
ubi_err("validation failed for PEB %d", pnum); ubi_err("validation failed for PEB %d", pnum);
return -EINVAL; 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; 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) ...@@ -1383,7 +1345,7 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
goto error; goto error;
} }
err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); err = ubi_check_pattern(ubi->dbg_peb_buf, 0xFF, len);
if (err == 0) { if (err == 0) {
ubi_err("flash region at PEB %d:%d, length %d does not " ubi_err("flash region at PEB %d:%d, length %d does not "
"contain all 0xFF bytes", pnum, offset, len); "contain all 0xFF bytes", pnum, offset, len);
......
...@@ -103,3 +103,22 @@ void ubi_calculate_reserved(struct ubi_device *ubi) ...@@ -103,3 +103,22 @@ void ubi_calculate_reserved(struct ubi_device *ubi)
if (ubi->beb_rsvd_level < MIN_RESEVED_PEBS) if (ubi->beb_rsvd_level < MIN_RESEVED_PEBS)
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;
}
This diff is collapsed.
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
* @pnum: physical eraseblock number * @pnum: physical eraseblock number
* @lnum: logical eraseblock number * @lnum: logical eraseblock number
* @scrub: if this physical eraseblock needs scrubbing * @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 * @sqnum: sequence number
* @u: unions RB-tree or @list links * @u: unions RB-tree or @list links
* @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects * @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects
...@@ -42,7 +43,8 @@ struct ubi_scan_leb { ...@@ -42,7 +43,8 @@ struct ubi_scan_leb {
int ec; int ec;
int pnum; int pnum;
int lnum; int lnum;
int scrub; unsigned int scrub:1;
unsigned int copy_flag:1;
unsigned long long sqnum; unsigned long long sqnum;
union { union {
struct rb_node rb; struct rb_node rb;
...@@ -91,14 +93,13 @@ struct ubi_scan_volume { ...@@ -91,14 +93,13 @@ struct ubi_scan_volume {
* @erase: list of physical eraseblocks which have to be erased * @erase: list of physical eraseblocks which have to be erased
* @alien: list of physical eraseblocks which should not be used by UBI (e.g., * @alien: list of physical eraseblocks which should not be used by UBI (e.g.,
* those belonging to "preserve"-compatible internal volumes) * those belonging to "preserve"-compatible internal volumes)
* @used_peb_count: count of used PEBs
* @corr_peb_count: count of PEBs in the @corr list * @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 * @empty_peb_count: count of PEBs which are presumably empty (contain only
* returned) * 0xFF bytes)
* @free_peb_count: count of PEBs in the @free list
* @erase_peb_count: count of PEBs in the @erase list
* @alien_peb_count: count of PEBs in the @alien list * @alien_peb_count: count of PEBs in the @alien list
* @bad_peb_count: count of bad physical eraseblocks * @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 * @vols_found: number of volumes found during scanning
* @highest_vol_id: highest volume ID * @highest_vol_id: highest volume ID
* @is_empty: flag indicating whether the MTD device is empty or not * @is_empty: flag indicating whether the MTD device is empty or not
...@@ -119,13 +120,11 @@ struct ubi_scan_info { ...@@ -119,13 +120,11 @@ struct ubi_scan_info {
struct list_head free; struct list_head free;
struct list_head erase; struct list_head erase;
struct list_head alien; struct list_head alien;
int used_peb_count;
int corr_peb_count; int corr_peb_count;
int read_err_count; int empty_peb_count;
int free_peb_count;
int erase_peb_count;
int alien_peb_count; int alien_peb_count;
int bad_peb_count; int bad_peb_count;
int maybe_bad_peb_count;
int vols_found; int vols_found;
int highest_vol_id; int highest_vol_id;
int is_empty; int is_empty;
......
...@@ -85,21 +85,26 @@ ...@@ -85,21 +85,26 @@
/* /*
* Error codes returned by the I/O sub-system. * Error codes returned by the I/O sub-system.
* *
* UBI_IO_PEB_EMPTY: the physical eraseblock is empty, i.e. it contains only * UBI_IO_FF: the read region of flash contains only 0xFFs
* %0xFF bytes * UBI_IO_FF_BITFLIPS: the same as %UBI_IO_FF, but also also there was a data
* UBI_IO_PEB_FREE: the physical eraseblock is free, i.e. it contains only a * integrity error reported by the MTD driver
* valid erase counter header, and the rest are %0xFF bytes * (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: 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 * UBI_IO_BAD_HDR_EBADMSG: the same as %UBI_IO_BAD_HDR, but also there was a
* error reported by the flash driver * data integrity error reported by the MTD driver
* (uncorrectable ECC error in case of NAND)
* UBI_IO_BITFLIPS: bit-flips were detected and corrected * 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 { enum {
UBI_IO_PEB_EMPTY = 1, UBI_IO_FF = 1,
UBI_IO_PEB_FREE, UBI_IO_FF_BITFLIPS,
UBI_IO_BAD_HDR, UBI_IO_BAD_HDR,
UBI_IO_BAD_HDR_READ, UBI_IO_BAD_HDR_EBADMSG,
UBI_IO_BITFLIPS UBI_IO_BITFLIPS,
}; };
/* /*
...@@ -356,6 +361,8 @@ struct ubi_wl_entry; ...@@ -356,6 +361,8 @@ struct ubi_wl_entry;
* @peb_size: physical eraseblock size * @peb_size: physical eraseblock size
* @bad_peb_count: count of bad physical eraseblocks * @bad_peb_count: count of bad physical eraseblocks
* @good_peb_count: count of good 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 * @erroneous_peb_count: count of erroneous physical eraseblocks in @erroneous
* @max_erroneous: maximum allowed amount of erroneous physical eraseblocks * @max_erroneous: maximum allowed amount of erroneous physical eraseblocks
* @min_io_size: minimal input/output unit size of the underlying MTD device * @min_io_size: minimal input/output unit size of the underlying MTD device
...@@ -442,6 +449,7 @@ struct ubi_device { ...@@ -442,6 +449,7 @@ struct ubi_device {
int peb_size; int peb_size;
int bad_peb_count; int bad_peb_count;
int good_peb_count; int good_peb_count;
int corr_peb_count;
int erroneous_peb_count; int erroneous_peb_count;
int max_erroneous; int max_erroneous;
int min_io_size; int min_io_size;
...@@ -506,6 +514,7 @@ int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf, ...@@ -506,6 +514,7 @@ int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf,
int length); int length);
int ubi_check_volume(struct ubi_device *ubi, int vol_id); int ubi_check_volume(struct ubi_device *ubi, int vol_id);
void ubi_calculate_reserved(struct ubi_device *ubi); void ubi_calculate_reserved(struct ubi_device *ubi);
int ubi_check_pattern(const void *buf, uint8_t patt, int size);
/* eba.c */ /* eba.c */
int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, 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) ...@@ -261,6 +261,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
/* Reserve physical eraseblocks */ /* Reserve physical eraseblocks */
if (vol->reserved_pebs > ubi->avail_pebs) { if (vol->reserved_pebs > ubi->avail_pebs) {
dbg_err("not enough PEBs, only %d available", 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; err = -ENOSPC;
goto out_unlock; goto out_unlock;
} }
...@@ -527,6 +530,9 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) ...@@ -527,6 +530,9 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
if (pebs > ubi->avail_pebs) { if (pebs > ubi->avail_pebs) {
dbg_err("not enough PEBs: requested %d, available %d", dbg_err("not enough PEBs: requested %d, available %d",
pebs, ubi->avail_pebs); 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); spin_unlock(&ubi->volumes_lock);
err = -ENOSPC; err = -ENOSPC;
goto out_free; goto out_free;
......
...@@ -366,7 +366,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si, ...@@ -366,7 +366,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si,
* Probably this physical eraseblock went bad, try to pick * Probably this physical eraseblock went bad, try to pick
* another one. * another one.
*/ */
list_add_tail(&new_seb->u.list, &si->corr); list_add(&new_seb->u.list, &si->erase);
goto retry; goto retry;
} }
kfree(new_seb); kfree(new_seb);
...@@ -662,9 +662,13 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, ...@@ -662,9 +662,13 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
ubi->vol_count += 1; ubi->vol_count += 1;
vol->ubi = ubi; vol->ubi = ubi;
if (reserved_pebs > ubi->avail_pebs) if (reserved_pebs > ubi->avail_pebs) {
ubi_err("not enough PEBs, required %d, available %d", ubi_err("not enough PEBs, required %d, available %d",
reserved_pebs, ubi->avail_pebs); 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->rsvd_pebs += reserved_pebs;
ubi->avail_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) ...@@ -837,7 +841,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
return PTR_ERR(ubi->vtbl); 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 * 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, ...@@ -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); err = ubi_io_read_vid_hdr(ubi, e1->pnum, vid_hdr, 0);
if (err && err != UBI_IO_BITFLIPS) { 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 * We are trying to move PEB without a VID header. UBI
* always write VID headers shortly after the PEB was * 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, ...@@ -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); dbg_wl("PEB %d has no VID header", e1->pnum);
protect = 1; protect = 1;
goto out_not_moved; 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", 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) ...@@ -1468,22 +1478,6 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
ubi->lookuptbl[e->pnum] = e; 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(rb1, sv, &si->volumes, rb) {
ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) {
cond_resched(); cond_resched();
...@@ -1510,6 +1504,9 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) ...@@ -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) { if (ubi->avail_pebs < WL_RESERVED_PEBS) {
ubi_err("no enough physical eraseblocks (%d, need %d)", ubi_err("no enough physical eraseblocks (%d, need %d)",
ubi->avail_pebs, WL_RESERVED_PEBS); 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; goto out_free;
} }
ubi->avail_pebs -= WL_RESERVED_PEBS; ubi->avail_pebs -= WL_RESERVED_PEBS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment