diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-10 18:52:09 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-10 18:52:09 -0400 |
| commit | ab0b2e59323cd3972e5f011fbbf3868a4ec360dd (patch) | |
| tree | 982f6b1f4a585f120dbd8b09afe639577c861030 | |
| parent | 5f85942c2ea2ed59d8f19c954bbb0f5c1a2ebdd1 (diff) | |
| parent | f5a926dd529870de4bd19199ce7b36985f130d70 (diff) | |
Merge tag 'upstream-4.18-rc1' of git://git.infradead.org/linux-ubifs
Pull UBI and UBIFS updates from Richard Weinberger:
- the UBI on-disk format header file is now dual licensed
- new way to detect Fastmap problems during runtime
- bugfix for Fastmap
- minor updates for UBIFS (spelling, comments, vm_fault_t, ...)
* tag 'upstream-4.18-rc1' of git://git.infradead.org/linux-ubifs:
mtd: ubi: Update ubi-media.h to dual license
ubi: fastmap: Detect EBA mismatches on-the-fly
ubi: fastmap: Check each mapping only once
ubi: fastmap: Correctly handle interrupted erasures in EBA
ubi: fastmap: Cancel work upon detach
ubifs: lpt: Fix wrong pnode number range in comment
ubifs: gc: Fix typo
ubifs: log: Some spelling fixes
ubifs: Spelling fix someting -> something
ubifs: journal: Remove wrong comment
ubifs: remove set but never used variable
ubifs, xattr: remove misguided quota flags
fs: ubifs: Adding new return type vm_fault_t
| -rw-r--r-- | drivers/mtd/ubi/build.c | 4 | ||||
| -rw-r--r-- | drivers/mtd/ubi/eba.c | 111 | ||||
| -rw-r--r-- | drivers/mtd/ubi/fastmap.c | 20 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi-media.h | 22 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi.h | 11 | ||||
| -rw-r--r-- | drivers/mtd/ubi/vmt.c | 1 | ||||
| -rw-r--r-- | drivers/mtd/ubi/vtbl.c | 16 | ||||
| -rw-r--r-- | drivers/mtd/ubi/wl.c | 4 | ||||
| -rw-r--r-- | fs/ubifs/file.c | 11 | ||||
| -rw-r--r-- | fs/ubifs/gc.c | 2 | ||||
| -rw-r--r-- | fs/ubifs/journal.c | 5 | ||||
| -rw-r--r-- | fs/ubifs/log.c | 6 | ||||
| -rw-r--r-- | fs/ubifs/lpt_commit.c | 2 | ||||
| -rw-r--r-- | fs/ubifs/replay.c | 5 | ||||
| -rw-r--r-- | fs/ubifs/ubifs.h | 2 | ||||
| -rw-r--r-- | fs/ubifs/xattr.c | 2 |
16 files changed, 178 insertions, 46 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 753494e042d5..d2a726654ff1 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
| @@ -526,6 +526,7 @@ void ubi_free_internal_volumes(struct ubi_device *ubi) | |||
| 526 | for (i = ubi->vtbl_slots; | 526 | for (i = ubi->vtbl_slots; |
| 527 | i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { | 527 | i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { |
| 528 | ubi_eba_replace_table(ubi->volumes[i], NULL); | 528 | ubi_eba_replace_table(ubi->volumes[i], NULL); |
| 529 | ubi_fastmap_destroy_checkmap(ubi->volumes[i]); | ||
| 529 | kfree(ubi->volumes[i]); | 530 | kfree(ubi->volumes[i]); |
| 530 | } | 531 | } |
| 531 | } | 532 | } |
| @@ -1091,6 +1092,9 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
| 1091 | if (ubi->bgt_thread) | 1092 | if (ubi->bgt_thread) |
| 1092 | kthread_stop(ubi->bgt_thread); | 1093 | kthread_stop(ubi->bgt_thread); |
| 1093 | 1094 | ||
| 1095 | #ifdef CONFIG_MTD_UBI_FASTMAP | ||
| 1096 | cancel_work_sync(&ubi->fm_work); | ||
| 1097 | #endif | ||
| 1094 | ubi_debugfs_exit_dev(ubi); | 1098 | ubi_debugfs_exit_dev(ubi); |
| 1095 | uif_close(ubi); | 1099 | uif_close(ubi); |
| 1096 | 1100 | ||
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 250e30fac61b..edb1c8362faa 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
| @@ -490,6 +490,103 @@ 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 | struct ubi_vid_hdr *vid_hdr; | ||
| 517 | |||
| 518 | if (!ubi->fast_attach) | ||
| 519 | return 0; | ||
| 520 | |||
| 521 | if (!vol->checkmap || test_bit(lnum, vol->checkmap)) | ||
| 522 | return 0; | ||
| 523 | |||
| 524 | vidb = ubi_alloc_vid_buf(ubi, GFP_NOFS); | ||
| 525 | if (!vidb) | ||
| 526 | return -ENOMEM; | ||
| 527 | |||
| 528 | err = ubi_io_read_vid_hdr(ubi, *pnum, vidb, 0); | ||
| 529 | if (err > 0 && err != UBI_IO_BITFLIPS) { | ||
| 530 | int torture = 0; | ||
| 531 | |||
| 532 | switch (err) { | ||
| 533 | case UBI_IO_FF: | ||
| 534 | case UBI_IO_FF_BITFLIPS: | ||
| 535 | case UBI_IO_BAD_HDR: | ||
| 536 | case UBI_IO_BAD_HDR_EBADMSG: | ||
| 537 | break; | ||
| 538 | default: | ||
| 539 | ubi_assert(0); | ||
| 540 | } | ||
| 541 | |||
| 542 | if (err == UBI_IO_BAD_HDR_EBADMSG || err == UBI_IO_FF_BITFLIPS) | ||
| 543 | torture = 1; | ||
| 544 | |||
| 545 | down_read(&ubi->fm_eba_sem); | ||
| 546 | vol->eba_tbl->entries[lnum].pnum = UBI_LEB_UNMAPPED; | ||
| 547 | up_read(&ubi->fm_eba_sem); | ||
| 548 | ubi_wl_put_peb(ubi, vol->vol_id, lnum, *pnum, torture); | ||
| 549 | |||
| 550 | *pnum = UBI_LEB_UNMAPPED; | ||
| 551 | } else if (err < 0) { | ||
| 552 | ubi_err(ubi, "unable to read VID header back from PEB %i: %i", | ||
| 553 | *pnum, err); | ||
| 554 | |||
| 555 | goto out_free; | ||
| 556 | } else { | ||
| 557 | int found_vol_id, found_lnum; | ||
| 558 | |||
| 559 | ubi_assert(err == 0 || err == UBI_IO_BITFLIPS); | ||
| 560 | |||
| 561 | vid_hdr = ubi_get_vid_hdr(vidb); | ||
| 562 | found_vol_id = be32_to_cpu(vid_hdr->vol_id); | ||
| 563 | found_lnum = be32_to_cpu(vid_hdr->lnum); | ||
| 564 | |||
| 565 | if (found_lnum != lnum || found_vol_id != vol->vol_id) { | ||
| 566 | ubi_err(ubi, "EBA mismatch! PEB %i is LEB %i:%i instead of LEB %i:%i", | ||
| 567 | *pnum, found_vol_id, found_lnum, vol->vol_id, lnum); | ||
| 568 | ubi_ro_mode(ubi); | ||
| 569 | err = -EINVAL; | ||
| 570 | goto out_free; | ||
| 571 | } | ||
| 572 | } | ||
| 573 | |||
| 574 | set_bit(lnum, vol->checkmap); | ||
| 575 | err = 0; | ||
| 576 | |||
| 577 | out_free: | ||
| 578 | ubi_free_vid_buf(vidb); | ||
| 579 | |||
| 580 | return err; | ||
| 581 | } | ||
| 582 | #else | ||
| 583 | static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | ||
| 584 | int *pnum) | ||
| 585 | { | ||
| 586 | return 0; | ||
| 587 | } | ||
| 588 | #endif | ||
| 589 | |||
| 493 | /** | 590 | /** |
| 494 | * ubi_eba_read_leb - read data. | 591 | * ubi_eba_read_leb - read data. |
| 495 | * @ubi: UBI device description object | 592 | * @ubi: UBI device description object |
| @@ -522,7 +619,13 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | |||
| 522 | return err; | 619 | return err; |
| 523 | 620 | ||
| 524 | pnum = vol->eba_tbl->entries[lnum].pnum; | 621 | pnum = vol->eba_tbl->entries[lnum].pnum; |
| 525 | if (pnum < 0) { | 622 | if (pnum >= 0) { |
| 623 | err = check_mapping(ubi, vol, lnum, &pnum); | ||
| 624 | if (err < 0) | ||
| 625 | goto out_unlock; | ||
| 626 | } | ||
| 627 | |||
| 628 | if (pnum == UBI_LEB_UNMAPPED) { | ||
| 526 | /* | 629 | /* |
| 527 | * The logical eraseblock is not mapped, fill the whole buffer | 630 | * The logical eraseblock is not mapped, fill the whole buffer |
| 528 | * with 0xFF bytes. The exception is static volumes for which | 631 | * with 0xFF bytes. The exception is static volumes for which |
| @@ -931,6 +1034,12 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | |||
| 931 | 1034 | ||
| 932 | pnum = vol->eba_tbl->entries[lnum].pnum; | 1035 | pnum = vol->eba_tbl->entries[lnum].pnum; |
| 933 | if (pnum >= 0) { | 1036 | if (pnum >= 0) { |
| 1037 | err = check_mapping(ubi, vol, lnum, &pnum); | ||
| 1038 | if (err < 0) | ||
| 1039 | goto out; | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | if (pnum >= 0) { | ||
| 934 | dbg_eba("write %d bytes at offset %d of LEB %d:%d, PEB %d", | 1043 | dbg_eba("write %d bytes at offset %d of LEB %d:%d, PEB %d", |
| 935 | len, offset, vol_id, lnum, pnum); | 1044 | len, offset, vol_id, lnum, pnum); |
| 936 | 1045 | ||
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 91705962ba73..462526a10537 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c | |||
| @@ -1100,6 +1100,26 @@ free_fm_sb: | |||
| 1100 | goto out; | 1100 | goto out; |
| 1101 | } | 1101 | } |
| 1102 | 1102 | ||
| 1103 | int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count) | ||
| 1104 | { | ||
| 1105 | struct ubi_device *ubi = vol->ubi; | ||
| 1106 | |||
| 1107 | if (!ubi->fast_attach) | ||
| 1108 | return 0; | ||
| 1109 | |||
| 1110 | vol->checkmap = kcalloc(BITS_TO_LONGS(leb_count), sizeof(unsigned long), | ||
| 1111 | GFP_KERNEL); | ||
| 1112 | if (!vol->checkmap) | ||
| 1113 | return -ENOMEM; | ||
| 1114 | |||
| 1115 | return 0; | ||
| 1116 | } | ||
