Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

UBI: add empty eraseblocks verification

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>

+21 -10
+6
drivers/mtd/ubi/debug.h
··· 93 93 #define UBI_IO_DEBUG 0 94 94 #endif 95 95 96 + #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID 97 + int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); 98 + #else 99 + #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 100 + #endif 101 + 96 102 #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT 97 103 #define DBG_DISABLE_BGT 1 98 104 #else
+7 -10
drivers/mtd/ubi/io.c
··· 98 98 static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); 99 99 static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, 100 100 const struct ubi_vid_hdr *vid_hdr); 101 - static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, 102 - int len); 103 101 static int paranoid_check_empty(struct ubi_device *ubi, int pnum); 104 102 #else 105 103 #define paranoid_check_not_bad(ubi, pnum) 0 ··· 105 107 #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 106 108 #define paranoid_check_peb_vid_hdr(ubi, pnum) 0 107 109 #define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 108 - #define paranoid_check_all_ff(ubi, pnum, offset, len) 0 109 110 #define paranoid_check_empty(ubi, pnum) 0 110 111 #endif 111 112 ··· 241 244 return err > 0 ? -EINVAL : err; 242 245 243 246 /* The area we are writing to has to contain all 0xFF bytes */ 244 - err = paranoid_check_all_ff(ubi, pnum, offset, len); 247 + err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); 245 248 if (err) 246 249 return err > 0 ? -EINVAL : err; 247 250 ··· 347 350 return -EIO; 348 351 } 349 352 350 - err = paranoid_check_all_ff(ubi, pnum, 0, ubi->peb_size); 353 + err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size); 351 354 if (err) 352 355 return err > 0 ? -EINVAL : err; 353 356 ··· 669 672 if (read_err != -EBADMSG && 670 673 check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { 671 674 /* The physical eraseblock is supposedly empty */ 672 - err = paranoid_check_all_ff(ubi, pnum, 0, 673 - ubi->peb_size); 675 + err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size); 674 676 if (err) 675 677 return err > 0 ? UBI_IO_BAD_EC_HDR : err; 676 678 ··· 1225 1229 } 1226 1230 1227 1231 /** 1228 - * paranoid_check_all_ff - check that a region of flash is empty. 1232 + * ubi_dbg_check_all_ff - check that a region of flash is empty. 1229 1233 * @ubi: UBI device description object 1230 1234 * @pnum: the physical eraseblock number to check 1231 1235 * @offset: the starting offset within the physical eraseblock to check ··· 1235 1239 * @offset of the physical eraseblock @pnum, %1 if not, and a negative error 1236 1240 * code if an error occurred. 1237 1241 */ 1238 - static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, 1239 - int len) 1242 + int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) 1240 1243 { 1241 1244 size_t read; 1242 1245 int err; 1243 1246 loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 1247 + 1248 + ubi_assert(!mutex_is_locked(&ubi->dbg_buf_mutex)); 1244 1249 1245 1250 mutex_lock(&ubi->dbg_buf_mutex); 1246 1251 err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf);
+8
drivers/mtd/ubi/wl.c
··· 459 459 dbg_wl("PEB %d EC %d", e->pnum, e->ec); 460 460 prot_queue_add(ubi, e); 461 461 spin_unlock(&ubi->wl_lock); 462 + 463 + err = ubi_dbg_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, 464 + ubi->peb_size - ubi->vid_hdr_aloffset); 465 + if (err) { 466 + dbg_err("new PEB does not contain all 0xFF bytes"); 467 + return err > 0 ? -EINVAL : err; 468 + } 469 + 462 470 return e->pnum; 463 471 } 464 472