diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-04 12:15:51 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-04 12:15:51 -0500 |
| commit | 70dcc535bdf30ffaef58b867fbde45c0287f34c6 (patch) | |
| tree | a031bc9ac814597e2c4af722b90880beeffaf4df | |
| parent | ca50496eb487b639de1f502e77a48dde84152fb9 (diff) | |
| parent | 894aef215775b56b725e9dde856b7a8b091ddfcc (diff) | |
Merge tag 'upstream-3.7-rc9' of git://git.infradead.org/linux-ubi
Pull UBI changes from Artem Bityutskiy:
"Fixes for 2 brown-paperbag bugs introduced this merge window by the
fastmap code:
1. The UBI background thread got stuck when a bit-flip happened
because free LEBs was not removed from the "free" tree when we
started using it.
2. I/O debugging checks did not work because we called a sleeping
function in atomic context."
* tag 'upstream-3.7-rc9' of git://git.infradead.org/linux-ubi:
UBI: dont call ubi_self_check_all_ff() in __wl_get_peb()
UBI: remove PEB from free tree in get_peb_for_wl()
| -rw-r--r-- | drivers/mtd/ubi/wl.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index da7b44998b40..2144f611196e 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -498,7 +498,7 @@ out: | |||
| 498 | * @ubi: UBI device description object | 498 | * @ubi: UBI device description object |
| 499 | * | 499 | * |
| 500 | * This function returns a physical eraseblock in case of success and a | 500 | * This function returns a physical eraseblock in case of success and a |
| 501 | * negative error code in case of failure. Might sleep. | 501 | * negative error code in case of failure. |
| 502 | */ | 502 | */ |
| 503 | static int __wl_get_peb(struct ubi_device *ubi) | 503 | static int __wl_get_peb(struct ubi_device *ubi) |
| 504 | { | 504 | { |
| @@ -540,13 +540,6 @@ retry: | |||
| 540 | * ubi_wl_get_peb() after removing e from the pool. */ | 540 | * ubi_wl_get_peb() after removing e from the pool. */ |
| 541 | prot_queue_add(ubi, e); | 541 | prot_queue_add(ubi, e); |
| 542 | #endif | 542 | #endif |
| 543 | err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, | ||
| 544 | ubi->peb_size - ubi->vid_hdr_aloffset); | ||
| 545 | if (err) { | ||
| 546 | ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); | ||
| 547 | return err; | ||
| 548 | } | ||
| 549 | |||
| 550 | return e->pnum; | 543 | return e->pnum; |
| 551 | } | 544 | } |
| 552 | 545 | ||
| @@ -679,17 +672,30 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) | |||
| 679 | #else | 672 | #else |
| 680 | static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) | 673 | static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) |
| 681 | { | 674 | { |
| 682 | return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); | 675 | struct ubi_wl_entry *e; |
| 676 | |||
| 677 | e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); | ||
| 678 | self_check_in_wl_tree(ubi, e, &ubi->free); | ||
| 679 | rb_erase(&e->u.rb, &ubi->free); | ||
| 680 | |||
| 681 | return e; | ||
| 683 | } | 682 | } |
| 684 | 683 | ||
| 685 | int ubi_wl_get_peb(struct ubi_device *ubi) | 684 | int ubi_wl_get_peb(struct ubi_device *ubi) |
| 686 | { | 685 | { |
| 687 | int peb; | 686 | int peb, err; |
| 688 | 687 | ||
| 689 | spin_lock(&ubi->wl_lock); | 688 | spin_lock(&ubi->wl_lock); |
| 690 | peb = __wl_get_peb(ubi); | 689 | peb = __wl_get_peb(ubi); |
| 691 | spin_unlock(&ubi->wl_lock); | 690 | spin_unlock(&ubi->wl_lock); |
| 692 | 691 | ||
| 692 | err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, | ||
| 693 | ubi->peb_size - ubi->vid_hdr_aloffset); | ||
| 694 | if (err) { | ||
| 695 | ubi_err("new PEB %d does not contain all 0xFF bytes", peb); | ||
| 696 | return err; | ||
| 697 | } | ||
| 698 | |||
| 693 | return peb; | 699 | return peb; |
| 694 | } | 700 | } |
| 695 | #endif | 701 | #endif |
