forked from Minki/linux
f9e109a209
Since commit 46b5889cc2c5("mtd: implement proper partition handling")
applied, mtd partition device won't hold some callback functions, such
as _block_isbad, _block_markbad, etc. Besides, function mtd_block_isbad()
will get mtd device's master mtd device, then invokes master mtd device's
callback function. So, following process may result mtd_block_isbad()
always return 0, even though mtd device has bad blocks:
1. Split a mtd device into 3 partitions: PA, PB, PC
[ Each mtd partition device won't has callback function _block_isbad(). ]
2. Concatenate PA and PB as a new mtd device PN
[ mtd_concat_create() finds out each subdev has no callback function
_block_isbad(), so PN won't be assigned callback function
concat_block_isbad(). ]
Then, mtd_block_isbad() checks "!master->_block_isbad" is true, will
always return 0.
Reproducer:
// reproduce.c
static int __init init_diy_module(void)
{
struct mtd_info *mtd[2];
struct mtd_info *mtd_combine = NULL;
mtd[0] = get_mtd_device_nm("NAND simulator partition 0");
if (!mtd[0]) {
pr_err("cannot find mtd1\n");
return -EINVAL;
}
mtd[1] = get_mtd_device_nm("NAND simulator partition 1");
if (!mtd[1]) {
pr_err("cannot find mtd2\n");
return -EINVAL;
}
put_mtd_device(mtd[0]);
put_mtd_device(mtd[1]);
mtd_combine = mtd_concat_create(mtd, 2, "Combine mtd");
if (mtd_combine == NULL) {
pr_err("combine failed\n");
return -EINVAL;
}
mtd_device_register(mtd_combine, NULL, 0);
pr_info("Combine success\n");
return 0;
}
1. ID="0x20,0xac,0x00,0x15"
2. modprobe nandsim id_bytes=$ID parts=50,100 badblocks=100
3. insmod reproduce.ko
4. flash_erase /dev/mtd3 0 0
libmtd: error!: MEMERASE64 ioctl failed for eraseblock 100 (mtd3)
error 5 (Input/output error)
// Should be "flash_erase: Skipping bad block at 00c80000"
Fixes:
|
||
---|---|---|
.. | ||
chips | ||
devices | ||
hyperbus | ||
lpddr | ||
maps | ||
nand | ||
parsers | ||
spi-nor | ||
tests | ||
ubi | ||
ftl.c | ||
inftlcore.c | ||
inftlmount.c | ||
Kconfig | ||
Makefile | ||
mtd_blkdevs.c | ||
mtdblock_ro.c | ||
mtdblock.c | ||
mtdchar.c | ||
mtdconcat.c | ||
mtdcore.c | ||
mtdcore.h | ||
mtdoops.c | ||
mtdpart.c | ||
mtdpstore.c | ||
mtdsuper.c | ||
mtdswap.c | ||
nftlcore.c | ||
nftlmount.c | ||
rfd_ftl.c | ||
sm_ftl.c | ||
sm_ftl.h | ||
ssfdc.c |