[MTD] [NAND] fix race in nand_base.c

When we mark block bad we have to get chip because this involves
writing to the page's OOB. We hit this bug in UBI - we observed
random obscure crashes when it marks block bad from the background
thread and there is some parallel task which utilizes flash.

This patch also adds a TODO note about BBT table protection which
it seems does not exist.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
This commit is contained in:
Artem Bityutskiy 2007-07-23 16:06:50 +03:00 committed by David Woodhouse
parent 9d7b4b5562
commit 06a7643cd3
1 changed files with 4 additions and 0 deletions

View File

@ -24,6 +24,7 @@
* if we have HW ecc support. * if we have HW ecc support.
* The AG-AND chips have nice features for speed improvement, * The AG-AND chips have nice features for speed improvement,
* which are not supported yet. Read / program 4 pages in one go. * which are not supported yet. Read / program 4 pages in one go.
* BBT table is not serialized, has to be fixed
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@ -360,6 +361,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
/* We write two bytes, so we dont have to mess with 16 bit /* We write two bytes, so we dont have to mess with 16 bit
* access * access
*/ */
nand_get_device(chip, mtd, FL_WRITING);
ofs += mtd->oobsize; ofs += mtd->oobsize;
chip->ops.len = chip->ops.ooblen = 2; chip->ops.len = chip->ops.ooblen = 2;
chip->ops.datbuf = NULL; chip->ops.datbuf = NULL;
@ -367,9 +369,11 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
chip->ops.ooboffs = chip->badblockpos & ~0x01; chip->ops.ooboffs = chip->badblockpos & ~0x01;
ret = nand_do_write_oob(mtd, ofs, &chip->ops); ret = nand_do_write_oob(mtd, ofs, &chip->ops);
nand_release_device(mtd);
} }
if (!ret) if (!ret)
mtd->ecc_stats.badblocks++; mtd->ecc_stats.badblocks++;
return ret; return ret;
} }