@@ -1060,9 +1060,8 @@ static int ensure_wear_leveling(struct ubi_device *ubi)
1060
1060
static int erase_worker (struct ubi_device * ubi , struct ubi_work * wl_wrk ,
1061
1061
int cancel )
1062
1062
{
1063
- int err ;
1064
1063
struct ubi_wl_entry * e = wl_wrk -> e ;
1065
- int pnum = e -> pnum ;
1064
+ int pnum = e -> pnum , err , need ;
1066
1065
1067
1066
if (cancel ) {
1068
1067
dbg_wl ("cancel erasure of PEB %d EC %d" , pnum , e -> ec );
@@ -1097,62 +1096,70 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
1097
1096
kfree (wl_wrk );
1098
1097
kmem_cache_free (wl_entries_slab , e );
1099
1098
1100
- if (err != - EIO ) {
1099
+ if (err == - EINTR || err == - ENOMEM || err == - EAGAIN ||
1100
+ err == - EBUSY ) {
1101
+ int err1 ;
1102
+
1103
+ /* Re-schedule the LEB for erasure */
1104
+ err1 = schedule_erase (ubi , e , 0 );
1105
+ if (err1 ) {
1106
+ err = err1 ;
1107
+ goto out_ro ;
1108
+ }
1109
+ return err ;
1110
+ } else if (err != - EIO ) {
1101
1111
/*
1102
1112
* If this is not %-EIO, we have no idea what to do. Scheduling
1103
1113
* this physical eraseblock for erasure again would cause
1104
1114
* errors again and again. Well, lets switch to RO mode.
1105
1115
*/
1106
- ubi_ro_mode (ubi );
1107
- return err ;
1116
+ goto out_ro ;
1108
1117
}
1109
1118
1110
1119
/* It is %-EIO, the PEB went bad */
1111
1120
1112
1121
if (!ubi -> bad_allowed ) {
1113
1122
ubi_err ("bad physical eraseblock %d detected" , pnum );
1114
- ubi_ro_mode (ubi );
1115
- err = - EIO ;
1116
- } else {
1117
- int need ;
1118
-
1119
- spin_lock (& ubi -> volumes_lock );
1120
- need = ubi -> beb_rsvd_level - ubi -> beb_rsvd_pebs + 1 ;
1121
- if (need > 0 ) {
1122
- need = ubi -> avail_pebs >= need ? need : ubi -> avail_pebs ;
1123
- ubi -> avail_pebs -= need ;
1124
- ubi -> rsvd_pebs += need ;
1125
- ubi -> beb_rsvd_pebs += need ;
1126
- if (need > 0 )
1127
- ubi_msg ("reserve more %d PEBs" , need );
1128
- }
1123
+ goto out_ro ;
1124
+ }
1129
1125
1130
- if (ubi -> beb_rsvd_pebs == 0 ) {
1131
- spin_unlock (& ubi -> volumes_lock );
1132
- ubi_err ("no reserved physical eraseblocks" );
1133
- ubi_ro_mode (ubi );
1134
- return - EIO ;
1135
- }
1126
+ spin_lock (& ubi -> volumes_lock );
1127
+ need = ubi -> beb_rsvd_level - ubi -> beb_rsvd_pebs + 1 ;
1128
+ if (need > 0 ) {
1129
+ need = ubi -> avail_pebs >= need ? need : ubi -> avail_pebs ;
1130
+ ubi -> avail_pebs -= need ;
1131
+ ubi -> rsvd_pebs += need ;
1132
+ ubi -> beb_rsvd_pebs += need ;
1133
+ if (need > 0 )
1134
+ ubi_msg ("reserve more %d PEBs" , need );
1135
+ }
1136
1136
1137
+ if (ubi -> beb_rsvd_pebs == 0 ) {
1137
1138
spin_unlock (& ubi -> volumes_lock );
1138
- ubi_msg ("mark PEB %d as bad" , pnum );
1139
+ ubi_err ("no reserved physical eraseblocks" );
1140
+ goto out_ro ;
1141
+ }
1139
1142
1140
- err = ubi_io_mark_bad (ubi , pnum );
1141
- if (err ) {
1142
- ubi_ro_mode (ubi );
1143
- return err ;
1144
- }
1143
+ spin_unlock (& ubi -> volumes_lock );
1144
+ ubi_msg ("mark PEB %d as bad" , pnum );
1145
1145
1146
- spin_lock (& ubi -> volumes_lock );
1147
- ubi -> beb_rsvd_pebs -= 1 ;
1148
- ubi -> bad_peb_count += 1 ;
1149
- ubi -> good_peb_count -= 1 ;
1150
- ubi_calculate_reserved (ubi );
1151
- if (ubi -> beb_rsvd_pebs == 0 )
1152
- ubi_warn ("last PEB from the reserved pool was used" );
1153
- spin_unlock (& ubi -> volumes_lock );
1154
- }
1146
+ err = ubi_io_mark_bad (ubi , pnum );
1147
+ if (err )
1148
+ goto out_ro ;
1149
+
1150
+ spin_lock (& ubi -> volumes_lock );
1151
+ ubi -> beb_rsvd_pebs -= 1 ;
1152
+ ubi -> bad_peb_count += 1 ;
1153
+ ubi -> good_peb_count -= 1 ;
1154
+ ubi_calculate_reserved (ubi );
1155
+ if (ubi -> beb_rsvd_pebs == 0 )
1156
+ ubi_warn ("last PEB from the reserved pool was used" );
1157
+ spin_unlock (& ubi -> volumes_lock );
1158
+
1159
+ return err ;
1155
1160
1161
+ out_ro :
1162
+ ubi_ro_mode (ubi );
1156
1163
return err ;
1157
1164
}
1158
1165
0 commit comments