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

UBI: use mtd->writebufsize to set minimal I/O unit size

Previously we used mtd->writesize field to set UBI's minimal
I/O unit size. This sometimes caused UBIFS recovery issues
when mounting an uncleanly unmounted UBIFS partition on NOR
flash since mtd->writesize is 1 byte for NOR flash. The
MTD CFI driver however often performs writing multiple
bytes in one programming operation using the chip's write
buffer. We have to use the size of this write buffer as
a minimal I/O unit size for UBI on NOR flash to fix the
observed UBIFS recovery issues.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

authored by

Anatolij Gustschin and committed by
David Woodhouse
a121f643 7fa33ac0

+27 -1
+27 -1
drivers/mtd/ubi/build.c
··· 672 672 ubi->nor_flash = 1; 673 673 } 674 674 675 - ubi->min_io_size = ubi->mtd->writesize; 675 + /* 676 + * Set UBI min. I/O size (@ubi->min_io_size). We use @mtd->writebufsize 677 + * for these purposes, not @mtd->writesize. At the moment this does not 678 + * matter for NAND, because currently @mtd->writebufsize is equivalent to 679 + * @mtd->writesize for all NANDs. However, some CFI NOR flashes may 680 + * have @mtd->writebufsize which is multiple of @mtd->writesize. 681 + * 682 + * The reason we use @mtd->writebufsize for @ubi->min_io_size is that 683 + * UBI and UBIFS recovery algorithms rely on the fact that if there was 684 + * an unclean power cut, then we can find offset of the last corrupted 685 + * node, align the offset to @ubi->min_io_size, read the rest of the 686 + * eraseblock starting from this offset, and check whether there are 687 + * only 0xFF bytes. If yes, then we are probably dealing with a 688 + * corruption caused by a power cut, if not, then this is probably some 689 + * severe corruption. 690 + * 691 + * Thus, we have to use the maximum write unit size of the flash, which 692 + * is @mtd->writebufsize, because @mtd->writesize is the minimum write 693 + * size, not the maximum. 694 + */ 695 + if (ubi->mtd->type == MTD_NANDFLASH) 696 + ubi_assert(ubi->mtd->writebufsize == ubi->mtd->writesize); 697 + else if (ubi->mtd->type == MTD_NORFLASH) 698 + ubi_assert(ubi->mtd->writebufsize % ubi->mtd->writesize == 0); 699 + 700 + ubi->min_io_size = ubi->mtd->writebufsize; 701 + 676 702 ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; 677 703 678 704 /*