diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-12 21:20:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-12 21:20:20 -0500 |
commit | 60b7eca1dc2ec066916b3b7ac6ad89bea13cb9af (patch) | |
tree | e95a890586b5d8113de5d1516a8b73add32876b0 /drivers | |
parent | 420d12d6ade1e9c02b98fb9a381a17d7ccc7d35e (diff) | |
parent | 4fdd1d51ad5d059548c6539ac9d281f74d24bcbe (diff) |
Merge tag 'upstream-4.5-rc1' of git://git.infradead.org/linux-ubifs
Pull UBI/UBIFS updates from Richard Weinberger:
"This contains three changes - two cleanups and one UBI wear leveling
improvement by Sebastian Siewior"
* tag 'upstream-4.5-rc1' of git://git.infradead.org/linux-ubifs:
ubifs: Use XATTR_*_PREFIX_LEN
UBIFS: add a comment in key.h for unused parameter
mtd: ubi: wl: avoid erasing a PEB which is empty
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/ubi/wl.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 56065632a5b8..17ec948ac40e 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -628,6 +628,7 @@ static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, | |||
628 | return __erase_worker(ubi, &wl_wrk); | 628 | return __erase_worker(ubi, &wl_wrk); |
629 | } | 629 | } |
630 | 630 | ||
631 | static int ensure_wear_leveling(struct ubi_device *ubi, int nested); | ||
631 | /** | 632 | /** |
632 | * wear_leveling_worker - wear-leveling worker function. | 633 | * wear_leveling_worker - wear-leveling worker function. |
633 | * @ubi: UBI device description object | 634 | * @ubi: UBI device description object |
@@ -649,6 +650,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
649 | #endif | 650 | #endif |
650 | struct ubi_wl_entry *e1, *e2; | 651 | struct ubi_wl_entry *e1, *e2; |
651 | struct ubi_vid_hdr *vid_hdr; | 652 | struct ubi_vid_hdr *vid_hdr; |
653 | int dst_leb_clean = 0; | ||
652 | 654 | ||
653 | kfree(wrk); | 655 | kfree(wrk); |
654 | if (shutdown) | 656 | if (shutdown) |
@@ -753,6 +755,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
753 | 755 | ||
754 | err = ubi_io_read_vid_hdr(ubi, e1->pnum, vid_hdr, 0); | 756 | err = ubi_io_read_vid_hdr(ubi, e1->pnum, vid_hdr, 0); |
755 | if (err && err != UBI_IO_BITFLIPS) { | 757 | if (err && err != UBI_IO_BITFLIPS) { |
758 | dst_leb_clean = 1; | ||
756 | if (err == UBI_IO_FF) { | 759 | if (err == UBI_IO_FF) { |
757 | /* | 760 | /* |
758 | * We are trying to move PEB without a VID header. UBI | 761 | * We are trying to move PEB without a VID header. UBI |
@@ -798,10 +801,12 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
798 | * protection queue. | 801 | * protection queue. |
799 | */ | 802 | */ |
800 | protect = 1; | 803 | protect = 1; |
804 | dst_leb_clean = 1; | ||
801 | goto out_not_moved; | 805 | goto out_not_moved; |
802 | } | 806 | } |
803 | if (err == MOVE_RETRY) { | 807 | if (err == MOVE_RETRY) { |
804 | scrubbing = 1; | 808 | scrubbing = 1; |
809 | dst_leb_clean = 1; | ||
805 | goto out_not_moved; | 810 | goto out_not_moved; |
806 | } | 811 | } |
807 | if (err == MOVE_TARGET_BITFLIPS || err == MOVE_TARGET_WR_ERR || | 812 | if (err == MOVE_TARGET_BITFLIPS || err == MOVE_TARGET_WR_ERR || |
@@ -827,6 +832,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
827 | ubi->erroneous_peb_count); | 832 | ubi->erroneous_peb_count); |
828 | goto out_error; | 833 | goto out_error; |
829 | } | 834 | } |
835 | dst_leb_clean = 1; | ||
830 | erroneous = 1; | 836 | erroneous = 1; |
831 | goto out_not_moved; | 837 | goto out_not_moved; |
832 | } | 838 | } |
@@ -897,15 +903,24 @@ out_not_moved: | |||
897 | wl_tree_add(e1, &ubi->scrub); | 903 | wl_tree_add(e1, &ubi->scrub); |
898 | else | 904 | else |
899 | wl_tree_add(e1, &ubi->used); | 905 | wl_tree_add(e1, &ubi->used); |
906 | if (dst_leb_clean) { | ||
907 | wl_tree_add(e2, &ubi->free); | ||
908 | ubi->free_count++; | ||
909 | } | ||
910 | |||
900 | ubi_assert(!ubi->move_to_put); | 911 | ubi_assert(!ubi->move_to_put); |
901 | ubi->move_from = ubi->move_to = NULL; | 912 | ubi->move_from = ubi->move_to = NULL; |
902 | ubi->wl_scheduled = 0; | 913 | ubi->wl_scheduled = 0; |
903 | spin_unlock(&ubi->wl_lock); | 914 | spin_unlock(&ubi->wl_lock); |
904 | 915 | ||
905 | ubi_free_vid_hdr(ubi, vid_hdr); | 916 | ubi_free_vid_hdr(ubi, vid_hdr); |
906 | err = do_sync_erase(ubi, e2, vol_id, lnum, torture); | 917 | if (dst_leb_clean) { |
907 | if (err) | 918 | ensure_wear_leveling(ubi, 1); |
908 | goto out_ro; | 919 | } else { |
920 | err = do_sync_erase(ubi, e2, vol_id, lnum, torture); | ||
921 | if (err) | ||
922 | goto out_ro; | ||
923 | } | ||
909 | 924 | ||
910 | mutex_unlock(&ubi->move_mutex); | 925 | mutex_unlock(&ubi->move_mutex); |
911 | return 0; | 926 | return 0; |