Merge branch 'linux-next' of git://git.infradead.org/ubi-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Oct 2010 23:34:23 +0000 (16:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Oct 2010 23:34:23 +0000 (16:34 -0700)
* '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

13 files changed:
drivers/mtd/ubi/Kconfig
drivers/mtd/ubi/Kconfig.debug
drivers/mtd/ubi/build.c
drivers/mtd/ubi/debug.h
drivers/mtd/ubi/eba.c
drivers/mtd/ubi/io.c
drivers/mtd/ubi/misc.c
drivers/mtd/ubi/scan.c
drivers/mtd/ubi/scan.h
drivers/mtd/ubi/ubi.h
drivers/mtd/ubi/vmt.c
drivers/mtd/ubi/vtbl.c
drivers/mtd/ubi/wl.c

index f702a16..3cf193f 100644 (file)
@@ -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
index 61f6e5e..fad4adc 100644 (file)
@@ -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
index 78ae894..5ebe280 100644 (file)
@@ -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);
index 17a1071..9eca950 100644 (file)
@@ -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
index fe74749..4be6718 100644 (file)
@@ -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;
        }
index 332f992..c2960ac 100644 (file)
@@ -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);
index 22ad314..ff2a65c 100644 (file)
@@ -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;
+}
index 69b52e9..3c63186 100644 (file)
@@ -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
  * 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,38 +728,86 @@ 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;
 
+               seb->ec += 1;
+               list_del(&seb->u.list);
+               dbg_bld("return PEB %d, EC %d", seb->pnum, seb->ec);
+               return seb;
+       }
+
+       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) {
                /*
-                * 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.
+                * 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.
                 */
-               list_for_each_entry_safe(seb, tmp_seb, head, u.list) {
-                       if (seb->ec == UBI_SCAN_UNKNOWN_EC)
-                               seb->ec = si->mean_ec;
+               return 0;
+       }
 
-                       err = ubi_scan_erase_peb(ubi, si, seb->pnum, seb->ec+1);
-                       if (err)
-                               continue;
+       if (err)
+               return err;
 
-                       seb->ec += 1;
-                       list_del(&seb->u.list);
-                       dbg_bld("return PEB %d, EC %d", seb->pnum, seb->ec);
-                       return seb;
-               }
+       if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) {
+               mutex_unlock(&ubi->buf_mutex);
+               return 0;
        }
 
-       ubi_err("no eraseblocks found");
-       return ERR_PTR(-ENOSPC);
+       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;
 }
 
 /**
@@ -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;
 }
 
index 2576a8d..a3264f0 100644 (file)
@@ -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;
index 0359e0c..0b0149c 100644 (file)
 /*
  * 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,
index e42afab..c47620d 100644 (file)
@@ -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;
index 14c10be..fcdb7f6 100644 (file)
@@ -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
index 97a4356..655bbbe 100644 (file)
@@ -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;