diff options
Diffstat (limited to 'drivers/mtd/ubi/wl.c')
-rw-r--r-- | drivers/mtd/ubi/wl.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index b6be644e7b85..032fc57f1090 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -978,9 +978,10 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
978 | int cancel) | 978 | int cancel) |
979 | { | 979 | { |
980 | struct ubi_wl_entry *e = wl_wrk->e; | 980 | struct ubi_wl_entry *e = wl_wrk->e; |
981 | int pnum = e->pnum, err, need; | 981 | int pnum = e->pnum; |
982 | int vol_id = wl_wrk->vol_id; | 982 | int vol_id = wl_wrk->vol_id; |
983 | int lnum = wl_wrk->lnum; | 983 | int lnum = wl_wrk->lnum; |
984 | int err, available_consumed = 0; | ||
984 | 985 | ||
985 | if (cancel) { | 986 | if (cancel) { |
986 | dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); | 987 | dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); |
@@ -1045,20 +1046,14 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
1045 | } | 1046 | } |
1046 | 1047 | ||
1047 | spin_lock(&ubi->volumes_lock); | 1048 | spin_lock(&ubi->volumes_lock); |
1048 | need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs + 1; | ||
1049 | if (need > 0) { | ||
1050 | need = ubi->avail_pebs >= need ? need : ubi->avail_pebs; | ||
1051 | ubi->avail_pebs -= need; | ||
1052 | ubi->rsvd_pebs += need; | ||
1053 | ubi->beb_rsvd_pebs += need; | ||
1054 | if (need > 0) | ||
1055 | ubi_msg("reserve more %d PEBs", need); | ||
1056 | } | ||
1057 | |||
1058 | if (ubi->beb_rsvd_pebs == 0) { | 1049 | if (ubi->beb_rsvd_pebs == 0) { |
1059 | spin_unlock(&ubi->volumes_lock); | 1050 | if (ubi->avail_pebs == 0) { |
1060 | ubi_err("no reserved physical eraseblocks"); | 1051 | spin_unlock(&ubi->volumes_lock); |
1061 | goto out_ro; | 1052 | ubi_err("no reserved/available physical eraseblocks"); |
1053 | goto out_ro; | ||
1054 | } | ||
1055 | ubi->avail_pebs -= 1; | ||
1056 | available_consumed = 1; | ||
1062 | } | 1057 | } |
1063 | spin_unlock(&ubi->volumes_lock); | 1058 | spin_unlock(&ubi->volumes_lock); |
1064 | 1059 | ||
@@ -1068,19 +1063,36 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
1068 | goto out_ro; | 1063 | goto out_ro; |
1069 | 1064 | ||
1070 | spin_lock(&ubi->volumes_lock); | 1065 | spin_lock(&ubi->volumes_lock); |
1071 | ubi->beb_rsvd_pebs -= 1; | 1066 | if (ubi->beb_rsvd_pebs > 0) { |
1067 | if (available_consumed) { | ||
1068 | /* | ||
1069 | * The amount of reserved PEBs increased since we last | ||
1070 | * checked. | ||
1071 | */ | ||
1072 | ubi->avail_pebs += 1; | ||
1073 | available_consumed = 0; | ||
1074 | } | ||
1075 | ubi->beb_rsvd_pebs -= 1; | ||
1076 | } | ||
1072 | ubi->bad_peb_count += 1; | 1077 | ubi->bad_peb_count += 1; |
1073 | ubi->good_peb_count -= 1; | 1078 | ubi->good_peb_count -= 1; |
1074 | ubi_calculate_reserved(ubi); | 1079 | ubi_calculate_reserved(ubi); |
1075 | if (ubi->beb_rsvd_pebs) | 1080 | if (available_consumed) |
1081 | ubi_warn("no PEBs in the reserved pool, used an available PEB"); | ||
1082 | else if (ubi->beb_rsvd_pebs) | ||
1076 | ubi_msg("%d PEBs left in the reserve", ubi->beb_rsvd_pebs); | 1083 | ubi_msg("%d PEBs left in the reserve", ubi->beb_rsvd_pebs); |
1077 | else | 1084 | else |
1078 | ubi_warn("last PEB from the reserved pool was used"); | 1085 | ubi_warn("last PEB from the reserve was used"); |
1079 | spin_unlock(&ubi->volumes_lock); | 1086 | spin_unlock(&ubi->volumes_lock); |
1080 | 1087 | ||
1081 | return err; | 1088 | return err; |
1082 | 1089 | ||
1083 | out_ro: | 1090 | out_ro: |
1091 | if (available_consumed) { | ||
1092 | spin_lock(&ubi->volumes_lock); | ||
1093 | ubi->avail_pebs += 1; | ||
1094 | spin_unlock(&ubi->volumes_lock); | ||
1095 | } | ||
1084 | ubi_ro_mode(ubi); | 1096 | ubi_ro_mode(ubi); |
1085 | return err; | 1097 | return err; |
1086 | } | 1098 | } |
@@ -1189,7 +1201,7 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum) | |||
1189 | { | 1201 | { |
1190 | struct ubi_wl_entry *e; | 1202 | struct ubi_wl_entry *e; |
1191 | 1203 | ||
1192 | dbg_msg("schedule PEB %d for scrubbing", pnum); | 1204 | ubi_msg("schedule PEB %d for scrubbing", pnum); |
1193 | 1205 | ||
1194 | retry: | 1206 | retry: |
1195 | spin_lock(&ubi->wl_lock); | 1207 | spin_lock(&ubi->wl_lock); |