diff options
| -rw-r--r-- | drivers/mtd/ubi/eba.c | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 250e30fac61b..593a4f9d97e3 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
| @@ -490,6 +490,82 @@ out_unlock: | |||
| 490 | return err; | 490 | return err; |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | #ifdef CONFIG_MTD_UBI_FASTMAP | ||
| 494 | /** | ||
| 495 | * check_mapping - check and fixup a mapping | ||
| 496 | * @ubi: UBI device description object | ||
| 497 | * @vol: volume description object | ||
| 498 | * @lnum: logical eraseblock number | ||
| 499 | * @pnum: physical eraseblock number | ||
| 500 | * | ||
| 501 | * Checks whether a given mapping is valid. Fastmap cannot track LEB unmap | ||
| 502 | * operations, if such an operation is interrupted the mapping still looks | ||
| 503 | * good, but upon first read an ECC is reported to the upper layer. | ||
| 504 | * Normaly during the full-scan at attach time this is fixed, for Fastmap | ||
| 505 | * we have to deal with it while reading. | ||
| 506 | * If the PEB behind a LEB shows this symthom we change the mapping to | ||
| 507 | * %UBI_LEB_UNMAPPED and schedule the PEB for erasure. | ||
| 508 | * | ||
| 509 | * Returns 0 on success, negative error code in case of failure. | ||
| 510 | */ | ||
| 511 | static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | ||
| 512 | int *pnum) | ||
| 513 | { | ||
| 514 | int err; | ||
| 515 | struct ubi_vid_io_buf *vidb; | ||
| 516 | |||
| 517 | if (!ubi->fast_attach) | ||
| 518 | return 0; | ||
| 519 | |||
| 520 | vidb = ubi_alloc_vid_buf(ubi, GFP_NOFS); | ||
| 521 | if (!vidb) | ||
| 522 | return -ENOMEM; | ||
| 523 | |||
| 524 | err = ubi_io_read_vid_hdr(ubi, *pnum, vidb, 0); | ||
| 525 | if (err > 0 && err != UBI_IO_BITFLIPS) { | ||
| 526 | int torture = 0; | ||
| 527 | |||
| 528 | switch (err) { | ||
| 529 | case UBI_IO_FF: | ||
| 530 | case UBI_IO_FF_BITFLIPS: | ||
| 531 | case UBI_IO_BAD_HDR: | ||
| 532 | case UBI_IO_BAD_HDR_EBADMSG: | ||
| 533 | break; | ||
| 534 | default: | ||
| 535 | ubi_assert(0); | ||
| 536 | } | ||
| 537 | |||
| 538 | if (err == UBI_IO_BAD_HDR_EBADMSG || err == UBI_IO_FF_BITFLIPS) | ||
| 539 | torture = 1; | ||
| 540 | |||
| 541 | down_read(&ubi->fm_eba_sem); | ||
| 542 | vol->eba_tbl->entries[lnum].pnum = UBI_LEB_UNMAPPED; | ||
| 543 | up_read(&ubi->fm_eba_sem); | ||
| 544 | ubi_wl_put_peb(ubi, vol->vol_id, lnum, *pnum, torture); | ||
| 545 | |||
| 546 | *pnum = UBI_LEB_UNMAPPED; | ||
| 547 | } else if (err < 0) { | ||
| 548 | ubi_err(ubi, "unable to read VID header back from PEB %i: %i", | ||
| 549 | *pnum, err); | ||
| 550 | |||
| 551 | goto out_free; | ||
| 552 | } | ||
| 553 | |||
| 554 | err = 0; | ||
| 555 | |||
| 556 | out_free: | ||
| 557 | ubi_free_vid_buf(vidb); | ||
| 558 | |||
| 559 | return err; | ||
| 560 | } | ||
| 561 | #else | ||
| 562 | static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | ||
| 563 | int *pnum) | ||
| 564 | { | ||
| 565 | return 0; | ||
| 566 | } | ||
| 567 | #endif | ||
| 568 | |||
| 493 | /** | 569 | /** |
| 494 | * ubi_eba_read_leb - read data. | 570 | * ubi_eba_read_leb - read data. |
| 495 | * @ubi: UBI device description object | 571 | * @ubi: UBI device description object |
| @@ -522,7 +598,13 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | |||
| 522 | return err; | 598 | return err; |
| 523 | 599 | ||
| 524 | pnum = vol->eba_tbl->entries[lnum].pnum; | 600 | pnum = vol->eba_tbl->entries[lnum].pnum; |
| 525 | if (pnum < 0) { | 601 | if (pnum >= 0) { |
| 602 | err = check_mapping(ubi, vol, lnum, &pnum); | ||
| 603 | if (err < 0) | ||
| 604 | goto out_unlock; | ||
| 605 | } | ||
| 606 | |||
| 607 | if (pnum == UBI_LEB_UNMAPPED) { | ||
| 526 | /* | 608 | /* |
| 527 | * The logical eraseblock is not mapped, fill the whole buffer | 609 | * The logical eraseblock is not mapped, fill the whole buffer |
| 528 | * with 0xFF bytes. The exception is static volumes for which | 610 | * with 0xFF bytes. The exception is static volumes for which |
| @@ -931,6 +1013,12 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | |||
| 931 | 1013 | ||
| 932 | pnum = vol->eba_tbl->entries[lnum].pnum; | 1014 | pnum = vol->eba_tbl->entries[lnum].pnum; |
| 933 | if (pnum >= 0) { | 1015 | if (pnum >= 0) { |
| 1016 | err = check_mapping(ubi, vol, lnum, &pnum); | ||
| 1017 | if (err < 0) | ||
| 1018 | goto out; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | if (pnum >= 0) { | ||
| 934 | dbg_eba("write %d bytes at offset %d of LEB %d:%d, PEB %d", | 1022 | dbg_eba("write %d bytes at offset %d of LEB %d:%d, PEB %d", |
| 935 | len, offset, vol_id, lnum, pnum); | 1023 | len, offset, vol_id, lnum, pnum); |
| 936 | 1024 | ||
