Commit 67b967dd authored by Miquel Raynal's avatar Miquel Raynal
Browse files

mtd: Introduce an expert mode for forensics and debugging purposes



When developping NAND controller drivers or when debugging filesystem
corruptions, it is quite common to need hacking locally into the
MTD/NAND core in order to get access to the content of the bad
blocks. Instead of having multiple implementations out there let's
provide a simple yet effective specific MTD-wide debugfs entry to fully
disable these checks on purpose.

A warning is added to inform the user when this mode gets enabled.

Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20211118114659.1282855-1-miquel.raynal@bootlin.com
parent 00596576
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -2370,6 +2370,14 @@ static struct backing_dev_info * __init mtd_bdi_init(const char *name)
	return ret ? ERR_PTR(ret) : bdi;
}

char *mtd_expert_analysis_warning =
	"Bad block checks have been entirely disabled.\n"
	"This is only reserved for post-mortem forensics and debug purposes.\n"
	"Never enable this mode if you do not know what you are doing!\n";
EXPORT_SYMBOL_GPL(mtd_expert_analysis_warning);
bool mtd_expert_analysis_mode;
EXPORT_SYMBOL_GPL(mtd_expert_analysis_mode);

static struct proc_dir_entry *proc_mtd;

static int __init init_mtd(void)
@@ -2393,6 +2401,8 @@ static int __init init_mtd(void)
		goto out_procfs;

	dfs_dir_mtd = debugfs_create_dir("mtd", NULL);
	debugfs_create_bool("expert_analysis_mode", 0600, dfs_dir_mtd,
			    &mtd_expert_analysis_mode);

	return 0;

+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@
 */
bool nanddev_isbad(struct nand_device *nand, const struct nand_pos *pos)
{
	if (WARN_ONCE(mtd_expert_analysis_mode, mtd_expert_analysis_warning))
		return false;

	if (nanddev_bbt_is_initialized(nand)) {
		unsigned int entry;
		int status;
+3 −0
Original line number Diff line number Diff line
@@ -321,6 +321,9 @@ static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
	if (nand_region_is_secured(chip, ofs, mtd->erasesize))
		return -EIO;

	if (WARN_ONCE(mtd_expert_analysis_mode, mtd_expert_analysis_warning))
		return 0;

	if (chip->legacy.block_bad)
		return chip->legacy.block_bad(chip, ofs);

+3 −0
Original line number Diff line number Diff line
@@ -1455,6 +1455,9 @@ int nand_isbad_bbt(struct nand_chip *this, loff_t offs, int allowbbt)
	pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
		 (unsigned int)offs, block, res);

	if (WARN_ONCE(mtd_expert_analysis_mode, mtd_expert_analysis_warning))
		return 0;

	switch (res) {
	case BBT_BLOCK_GOOD:
		return 0;
+3 −0
Original line number Diff line number Diff line
@@ -711,4 +711,7 @@ static inline int mtd_is_bitflip_or_eccerr(int err) {

unsigned mtd_mmap_capabilities(struct mtd_info *mtd);

extern char *mtd_expert_analysis_warning;
extern bool mtd_expert_analysis_mode;

#endif /* __MTD_MTD_H__ */