diff options
| -rw-r--r-- | drivers/mtd/ubi/wl.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 667f5f451c2b..442099d76ec9 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -738,13 +738,12 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, | |||
| 738 | static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | 738 | static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, |
| 739 | int cancel) | 739 | int cancel) |
| 740 | { | 740 | { |
| 741 | int err, put = 0, scrubbing = 0; | 741 | int err, scrubbing = 0; |
| 742 | struct ubi_wl_prot_entry *uninitialized_var(pe); | 742 | struct ubi_wl_prot_entry *uninitialized_var(pe); |
| 743 | struct ubi_wl_entry *e1, *e2; | 743 | struct ubi_wl_entry *e1, *e2; |
| 744 | struct ubi_vid_hdr *vid_hdr; | 744 | struct ubi_vid_hdr *vid_hdr; |
| 745 | 745 | ||
| 746 | kfree(wrk); | 746 | kfree(wrk); |
| 747 | |||
| 748 | if (cancel) | 747 | if (cancel) |
| 749 | return 0; | 748 | return 0; |
| 750 | 749 | ||
| @@ -864,6 +863,8 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 864 | } | 863 | } |
| 865 | 864 | ||
| 866 | ubi_free_vid_hdr(ubi, vid_hdr); | 865 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 866 | vid_hdr = NULL; | ||
| 867 | |||
| 867 | spin_lock(&ubi->wl_lock); | 868 | spin_lock(&ubi->wl_lock); |
| 868 | prot_tree_add(ubi, e1, pe, U_PROTECTION); | 869 | prot_tree_add(ubi, e1, pe, U_PROTECTION); |
| 869 | ubi_assert(!ubi->move_to_put); | 870 | ubi_assert(!ubi->move_to_put); |
| @@ -871,6 +872,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 871 | ubi->wl_scheduled = 0; | 872 | ubi->wl_scheduled = 0; |
| 872 | spin_unlock(&ubi->wl_lock); | 873 | spin_unlock(&ubi->wl_lock); |
| 873 | 874 | ||
| 875 | e1 = NULL; | ||
| 874 | err = schedule_erase(ubi, e2, 0); | 876 | err = schedule_erase(ubi, e2, 0); |
| 875 | if (err) | 877 | if (err) |
| 876 | goto out_error; | 878 | goto out_error; |
| @@ -880,24 +882,27 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 880 | 882 | ||
| 881 | /* The PEB has been successfully moved */ | 883 | /* The PEB has been successfully moved */ |
| 882 | ubi_free_vid_hdr(ubi, vid_hdr); | 884 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 885 | vid_hdr = NULL; | ||
| 883 | if (scrubbing) | 886 | if (scrubbing) |
| 884 | ubi_msg("scrubbed PEB %d, data moved to PEB %d", | 887 | ubi_msg("scrubbed PEB %d, data moved to PEB %d", |
| 885 | e1->pnum, e2->pnum); | 888 | e1->pnum, e2->pnum); |
| 886 | 889 | ||
| 887 | spin_lock(&ubi->wl_lock); | 890 | spin_lock(&ubi->wl_lock); |
| 888 | if (!ubi->move_to_put) | 891 | if (!ubi->move_to_put) { |
| 889 | wl_tree_add(e2, &ubi->used); | 892 | wl_tree_add(e2, &ubi->used); |
| 890 | else | 893 | e2 = NULL; |
| 891 | put = 1; | 894 | } |
| 892 | ubi->move_from = ubi->move_to = NULL; | 895 | ubi->move_from = ubi->move_to = NULL; |
| 893 | ubi->move_to_put = ubi->wl_scheduled = 0; | 896 | ubi->move_to_put = ubi->wl_scheduled = 0; |
| 894 | spin_unlock(&ubi->wl_lock); | 897 | spin_unlock(&ubi->wl_lock); |
| 895 | 898 | ||
| 896 | err = schedule_erase(ubi, e1, 0); | 899 | err = schedule_erase(ubi, e1, 0); |
| 897 | if (err) | 900 | if (err) { |
| 901 | e1 = NULL; | ||
| 898 | goto out_error; | 902 | goto out_error; |
| 903 | } | ||
| 899 | 904 | ||
| 900 | if (put) { | 905 | if (e2) { |
| 901 | /* | 906 | /* |
| 902 | * Well, the target PEB was put meanwhile, schedule it for | 907 | * Well, the target PEB was put meanwhile, schedule it for |
| 903 | * erasure. | 908 | * erasure. |
| @@ -919,6 +924,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
| 919 | */ | 924 | */ |
| 920 | out_not_moved: | 925 | out_not_moved: |
| 921 | ubi_free_vid_hdr(ubi, vid_hdr); | 926 | ubi_free_vid_hdr(ubi, vid_hdr); |
| 927 | vid_hdr = NULL; | ||
| 922 | spin_lock(&ubi->wl_lock); | 928 | spin_lock(&ubi->wl_lock); |
| 923 | if (scrubbing) | 929 | if (scrubbing) |
| 924 | wl_tree_add(e1, &ubi->scrub); | 930 | wl_tree_add(e1, &ubi->scrub); |
| @@ -928,6 +934,7 @@ out_not_moved: | |||
| 928 | ubi->move_to_put = ubi->wl_scheduled = 0; | 934 | ubi->move_to_put = ubi->wl_scheduled = 0; |
| 929 | spin_unlock(&ubi->wl_lock); | 935 | spin_unlock(&ubi->wl_lock); |
| 930 | 936 | ||
| 937 | e1 = NULL; | ||
| 931 | err = schedule_erase(ubi, e2, 0); | 938 | err = schedule_erase(ubi, e2, 0); |
| 932 | if (err) | 939 | if (err) |
| 933 | goto out_error; | 940 | goto out_error; |
| @@ -945,8 +952,10 @@ out_error: | |||
| 945 | ubi->move_to_put = ubi->wl_scheduled = 0; | 952 | ubi->move_to_put = ubi->wl_scheduled = 0; |
| 946 | spin_unlock(&ubi->wl_lock); | 953 | spin_unlock(&ubi->wl_lock); |
| 947 | 954 | ||
| 948 | kmem_cache_free(ubi_wl_entry_slab, e1); | 955 | if (e1) |
| 949 | kmem_cache_free(ubi_wl_entry_slab, e2); | 956 | kmem_cache_free(ubi_wl_entry_slab, e1); |
| 957 | if (e2) | ||
| 958 | kmem_cache_free(ubi_wl_entry_slab, e2); | ||
| 950 | ubi_ro_mode(ubi); | 959 | ubi_ro_mode(ubi); |
| 951 | 960 | ||
| 952 | mutex_unlock(&ubi->move_mutex); | 961 | mutex_unlock(&ubi->move_mutex); |
