]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
UBI: add empty eraseblocks verification
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Sun, 28 Jun 2009 16:16:55 +0000 (19:16 +0300)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Sun, 5 Jul 2009 15:47:03 +0000 (18:47 +0300)
This patch adds code which makes sure eraseblocks contain all 0xFF
bytes before starting using them. The verification is done only when
debugging checks are enabled.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
drivers/mtd/ubi/debug.h
drivers/mtd/ubi/io.c
drivers/mtd/ubi/wl.c

index 13777e5beac93344ae759aa2ea0176c796e97d1d..6fc7fda2ab91794ae19bc1332c7637da6092b492 100644 (file)
@@ -93,6 +93,12 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req);
 #define UBI_IO_DEBUG 0
 #endif
 
+#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
+int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len);
+#else
+#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
+#endif
+
 #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT
 #define DBG_DISABLE_BGT 1
 #else
index effaff28bab18ef4936c69cf354a4b8a11db17dd..6c5441e8791da4bfa101f3420f67be335287f6c2 100644 (file)
@@ -98,8 +98,6 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
 static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum);
 static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
                                  const struct ubi_vid_hdr *vid_hdr);
-static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
-                                int len);
 static int paranoid_check_empty(struct ubi_device *ubi, int pnum);
 #else
 #define paranoid_check_not_bad(ubi, pnum) 0
@@ -107,7 +105,6 @@ static int paranoid_check_empty(struct ubi_device *ubi, int pnum);
 #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr)  0
 #define paranoid_check_peb_vid_hdr(ubi, pnum) 0
 #define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0
-#define paranoid_check_all_ff(ubi, pnum, offset, len) 0
 #define paranoid_check_empty(ubi, pnum) 0
 #endif
 
@@ -244,7 +241,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
                return err > 0 ? -EINVAL : err;
 
        /* The area we are writing to has to contain all 0xFF bytes */
-       err = paranoid_check_all_ff(ubi, pnum, offset, len);
+       err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
        if (err)
                return err > 0 ? -EINVAL : err;
 
@@ -350,7 +347,7 @@ retry:
                return -EIO;
        }
 
-       err = paranoid_check_all_ff(ubi, pnum, 0, ubi->peb_size);
+       err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size);
        if (err)
                return err > 0 ? -EINVAL : err;
 
@@ -672,8 +669,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
                if (read_err != -EBADMSG &&
                    check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) {
                        /* The physical eraseblock is supposedly empty */
-                       err = paranoid_check_all_ff(ubi, pnum, 0,
-                                                   ubi->peb_size);
+                       err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size);
                        if (err)
                                return err > 0 ? UBI_IO_BAD_EC_HDR : err;
 
@@ -1229,7 +1225,7 @@ exit:
 }
 
 /**
- * paranoid_check_all_ff - check that a region of flash is empty.
+ * ubi_dbg_check_all_ff - check that a region of flash is empty.
  * @ubi: UBI device description object
  * @pnum: the physical eraseblock number to check
  * @offset: the starting offset within the physical eraseblock to check
@@ -1239,13 +1235,14 @@ exit:
  * @offset of the physical eraseblock @pnum, %1 if not, and a negative error
  * code if an error occurred.
  */
-static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
-                                int len)
+int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
 {
        size_t read;
        int err;
        loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
 
+       ubi_assert(!mutex_is_locked(&ubi->dbg_buf_mutex));
+
        mutex_lock(&ubi->dbg_buf_mutex);
        err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf);
        if (err && err != -EUCLEAN) {
index 2b2472300610f166eb897a53647436f4307c9456..e4be446e05ed61d29dfb6cdf04e0fd0174c40765 100644 (file)
@@ -459,6 +459,14 @@ retry:
        dbg_wl("PEB %d EC %d", e->pnum, e->ec);
        prot_queue_add(ubi, e);
        spin_unlock(&ubi->wl_lock);
+
+       err = ubi_dbg_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
+                                  ubi->peb_size - ubi->vid_hdr_aloffset);
+       if (err) {
+               dbg_err("new PEB does not contain all 0xFF bytes");
+               return err > 0 ? -EINVAL : err;
+       }
+
        return e->pnum;
 }