hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/mtd/ubi/wl.c
....@@ -575,6 +575,7 @@
575575 * @vol_id: the volume ID that last used this PEB
576576 * @lnum: the last used logical eraseblock number for the PEB
577577 * @torture: if the physical eraseblock has to be tortured
578
+ * @nested: denotes whether the work_sem is already held
578579 *
579580 * This function returns zero in case of success and a %-ENOMEM in case of
580581 * failure.
....@@ -885,8 +886,11 @@
885886
886887 err = do_sync_erase(ubi, e1, vol_id, lnum, 0);
887888 if (err) {
888
- if (e2)
889
+ if (e2) {
890
+ spin_lock(&ubi->wl_lock);
889891 wl_entry_destroy(ubi, e2);
892
+ spin_unlock(&ubi->wl_lock);
893
+ }
890894 goto out_ro;
891895 }
892896
....@@ -968,11 +972,11 @@
968972 spin_lock(&ubi->wl_lock);
969973 ubi->move_from = ubi->move_to = NULL;
970974 ubi->move_to_put = ubi->wl_scheduled = 0;
975
+ wl_entry_destroy(ubi, e1);
976
+ wl_entry_destroy(ubi, e2);
971977 spin_unlock(&ubi->wl_lock);
972978
973979 ubi_free_vid_buf(vidb);
974
- wl_entry_destroy(ubi, e1);
975
- wl_entry_destroy(ubi, e2);
976980
977981 out_ro:
978982 ubi_ro_mode(ubi);
....@@ -1063,8 +1067,6 @@
10631067 * __erase_worker - physical eraseblock erase worker function.
10641068 * @ubi: UBI device description object
10651069 * @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
10681070 *
10691071 * This function erases a physical eraseblock and perform torture testing if
10701072 * needed. It also takes care about marking the physical eraseblock bad if
....@@ -1119,16 +1121,20 @@
11191121 int err1;
11201122
11211123 /* 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);
11231125 if (err1) {
1126
+ spin_lock(&ubi->wl_lock);
11241127 wl_entry_destroy(ubi, e);
1128
+ spin_unlock(&ubi->wl_lock);
11251129 err = err1;
11261130 goto out_ro;
11271131 }
11281132 return err;
11291133 }
11301134
1135
+ spin_lock(&ubi->wl_lock);
11311136 wl_entry_destroy(ubi, e);
1137
+ spin_unlock(&ubi->wl_lock);
11321138 if (err != -EIO)
11331139 /*
11341140 * If this is not %-EIO, we have no idea what to do. Scheduling
....@@ -1244,6 +1250,18 @@
12441250 retry:
12451251 spin_lock(&ubi->wl_lock);
12461252 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
+ }
12471265 if (e == ubi->move_from) {
12481266 /*
12491267 * User is putting the physical eraseblock which was selected to