diff options
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r-- | drivers/mtd/ubi/build.c | 28 | ||||
-rw-r--r-- | drivers/mtd/ubi/vtbl.c | 6 |
2 files changed, 29 insertions, 5 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 5ebe280225d6..f49e49dc5928 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -672,7 +672,33 @@ static int io_init(struct ubi_device *ubi) ubi->nor_flash = 1; } - ubi->min_io_size = ubi->mtd->writesize; + /* + * Set UBI min. I/O size (@ubi->min_io_size). We use @mtd->writebufsize + * for these purposes, not @mtd->writesize. At the moment this does not + * matter for NAND, because currently @mtd->writebufsize is equivalent to + * @mtd->writesize for all NANDs. However, some CFI NOR flashes may + * have @mtd->writebufsize which is multiple of @mtd->writesize. + * + * The reason we use @mtd->writebufsize for @ubi->min_io_size is that + * UBI and UBIFS recovery algorithms rely on the fact that if there was + * an unclean power cut, then we can find offset of the last corrupted + * node, align the offset to @ubi->min_io_size, read the rest of the + * eraseblock starting from this offset, and check whether there are + * only 0xFF bytes. If yes, then we are probably dealing with a + * corruption caused by a power cut, if not, then this is probably some + * severe corruption. + * + * Thus, we have to use the maximum write unit size of the flash, which + * is @mtd->writebufsize, because @mtd->writesize is the minimum write + * size, not the maximum. + */ + if (ubi->mtd->type == MTD_NANDFLASH) + ubi_assert(ubi->mtd->writebufsize == ubi->mtd->writesize); + else if (ubi->mtd->type == MTD_NORFLASH) + ubi_assert(ubi->mtd->writebufsize % ubi->mtd->writesize == 0); + + ubi->min_io_size = ubi->mtd->writebufsize; + ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; /* diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index fcdb7f65fe0b..0b8141fc5c26 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -425,12 +425,11 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, /* Read both LEB 0 and LEB 1 into memory */ ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { - leb[seb->lnum] = vmalloc(ubi->vtbl_size); + leb[seb->lnum] = vzalloc(ubi->vtbl_size); if (!leb[seb->lnum]) { err = -ENOMEM; goto out_free; } - memset(leb[seb->lnum], 0, ubi->vtbl_size); err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, ubi->vtbl_size); @@ -516,10 +515,9 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, int i; struct ubi_vtbl_record *vtbl; - vtbl = vmalloc(ubi->vtbl_size); + vtbl = vzalloc(ubi->vtbl_size); if (!vtbl) return ERR_PTR(-ENOMEM); - memset(vtbl, 0, ubi->vtbl_size); for (i = 0; i < ubi->vtbl_slots; i++) memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE); |