.. | .. |
---|
575 | 575 | * @vol_id: the volume ID that last used this PEB |
---|
576 | 576 | * @lnum: the last used logical eraseblock number for the PEB |
---|
577 | 577 | * @torture: if the physical eraseblock has to be tortured |
---|
| 578 | + * @nested: denotes whether the work_sem is already held |
---|
578 | 579 | * |
---|
579 | 580 | * This function returns zero in case of success and a %-ENOMEM in case of |
---|
580 | 581 | * failure. |
---|
.. | .. |
---|
885 | 886 | |
---|
886 | 887 | err = do_sync_erase(ubi, e1, vol_id, lnum, 0); |
---|
887 | 888 | if (err) { |
---|
888 | | - if (e2) |
---|
| 889 | + if (e2) { |
---|
| 890 | + spin_lock(&ubi->wl_lock); |
---|
889 | 891 | wl_entry_destroy(ubi, e2); |
---|
| 892 | + spin_unlock(&ubi->wl_lock); |
---|
| 893 | + } |
---|
890 | 894 | goto out_ro; |
---|
891 | 895 | } |
---|
892 | 896 | |
---|
.. | .. |
---|
968 | 972 | spin_lock(&ubi->wl_lock); |
---|
969 | 973 | ubi->move_from = ubi->move_to = NULL; |
---|
970 | 974 | ubi->move_to_put = ubi->wl_scheduled = 0; |
---|
| 975 | + wl_entry_destroy(ubi, e1); |
---|
| 976 | + wl_entry_destroy(ubi, e2); |
---|
971 | 977 | spin_unlock(&ubi->wl_lock); |
---|
972 | 978 | |
---|
973 | 979 | ubi_free_vid_buf(vidb); |
---|
974 | | - wl_entry_destroy(ubi, e1); |
---|
975 | | - wl_entry_destroy(ubi, e2); |
---|
976 | 980 | |
---|
977 | 981 | out_ro: |
---|
978 | 982 | ubi_ro_mode(ubi); |
---|
.. | .. |
---|
1063 | 1067 | * __erase_worker - physical eraseblock erase worker function. |
---|
1064 | 1068 | * @ubi: UBI device description object |
---|
1065 | 1069 | * @wl_wrk: the work object |
---|
1066 | | - * @shutdown: non-zero if the worker has to free memory and exit |
---|
1067 | | - * because the WL sub-system is shutting down |
---|
1068 | 1070 | * |
---|
1069 | 1071 | * This function erases a physical eraseblock and perform torture testing if |
---|
1070 | 1072 | * needed. It also takes care about marking the physical eraseblock bad if |
---|
.. | .. |
---|
1119 | 1121 | int err1; |
---|
1120 | 1122 | |
---|
1121 | 1123 | /* Re-schedule the LEB for erasure */ |
---|
1122 | | - err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false); |
---|
| 1124 | + err1 = schedule_erase(ubi, e, vol_id, lnum, 0, true); |
---|
1123 | 1125 | if (err1) { |
---|
| 1126 | + spin_lock(&ubi->wl_lock); |
---|
1124 | 1127 | wl_entry_destroy(ubi, e); |
---|
| 1128 | + spin_unlock(&ubi->wl_lock); |
---|
1125 | 1129 | err = err1; |
---|
1126 | 1130 | goto out_ro; |
---|
1127 | 1131 | } |
---|
1128 | 1132 | return err; |
---|
1129 | 1133 | } |
---|
1130 | 1134 | |
---|
| 1135 | + spin_lock(&ubi->wl_lock); |
---|
1131 | 1136 | wl_entry_destroy(ubi, e); |
---|
| 1137 | + spin_unlock(&ubi->wl_lock); |
---|
1132 | 1138 | if (err != -EIO) |
---|
1133 | 1139 | /* |
---|
1134 | 1140 | * If this is not %-EIO, we have no idea what to do. Scheduling |
---|
.. | .. |
---|
1244 | 1250 | retry: |
---|
1245 | 1251 | spin_lock(&ubi->wl_lock); |
---|
1246 | 1252 | e = ubi->lookuptbl[pnum]; |
---|
| 1253 | + if (!e) { |
---|
| 1254 | + /* |
---|
| 1255 | + * This wl entry has been removed for some errors by other |
---|
| 1256 | + * process (eg. wear leveling worker), corresponding process |
---|
| 1257 | + * (except __erase_worker, which cannot concurrent with |
---|
| 1258 | + * ubi_wl_put_peb) will set ubi ro_mode at the same time, |
---|
| 1259 | + * just ignore this wl entry. |
---|
| 1260 | + */ |
---|
| 1261 | + spin_unlock(&ubi->wl_lock); |
---|
| 1262 | + up_read(&ubi->fm_protect); |
---|
| 1263 | + return 0; |
---|
| 1264 | + } |
---|
1247 | 1265 | if (e == ubi->move_from) { |
---|
1248 | 1266 | /* |
---|
1249 | 1267 | * User is putting the physical eraseblock which was selected to |
---|