diff options
Diffstat (limited to 'drivers/mtd/ubi/attach.c')
-rw-r--r-- | drivers/mtd/ubi/attach.c | 69 |
1 files changed, 51 insertions, 18 deletions
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 5692b4ce0d9c..82b30c959a28 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c | |||
@@ -182,6 +182,47 @@ static struct ubi_ainf_volume *ubi_find_or_add_av(struct ubi_attach_info *ai, | |||
182 | } | 182 | } |
183 | 183 | ||
184 | /** | 184 | /** |
185 | * ubi_alloc_aeb - allocate an aeb element | ||
186 | * @ai: attaching information | ||
187 | * @pnum: physical eraseblock number | ||
188 | * @ec: erase counter of the physical eraseblock | ||
189 | * | ||
190 | * Allocate an aeb object and initialize the pnum and ec information. | ||
191 | * vol_id and lnum are set to UBI_UNKNOWN, and the other fields are | ||
192 | * initialized to zero. | ||
193 | * Note that the element is not added in any list or RB tree. | ||
194 | */ | ||
195 | struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum, | ||
196 | int ec) | ||
197 | { | ||
198 | struct ubi_ainf_peb *aeb; | ||
199 | |||
200 | aeb = kmem_cache_zalloc(ai->aeb_slab_cache, GFP_KERNEL); | ||
201 | if (!aeb) | ||
202 | return NULL; | ||
203 | |||
204 | aeb->pnum = pnum; | ||
205 | aeb->ec = ec; | ||
206 | aeb->vol_id = UBI_UNKNOWN; | ||
207 | aeb->lnum = UBI_UNKNOWN; | ||
208 | |||
209 | return aeb; | ||
210 | } | ||
211 | |||
212 | /** | ||
213 | * ubi_free_aeb - free an aeb element | ||
214 | * @ai: attaching information | ||
215 | * @aeb: the element to free | ||
216 | * | ||
217 | * Free an aeb object. The caller must have removed the element from any list | ||
218 | * or RB tree. | ||
219 | */ | ||
220 | void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb) | ||
221 | { | ||
222 | kmem_cache_free(ai->aeb_slab_cache, aeb); | ||
223 | } | ||
224 | |||
225 | /** | ||
185 | * add_to_list - add physical eraseblock to a list. | 226 | * add_to_list - add physical eraseblock to a list. |
186 | * @ai: attaching information | 227 | * @ai: attaching information |
187 | * @pnum: physical eraseblock number to add | 228 | * @pnum: physical eraseblock number to add |
@@ -217,14 +258,12 @@ static int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id, | |||
217 | } else | 258 | } else |
218 | BUG(); | 259 | BUG(); |
219 | 260 | ||
220 | aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); | 261 | aeb = ubi_alloc_aeb(ai, pnum, ec); |
221 | if (!aeb) | 262 | if (!aeb) |
222 | return -ENOMEM; | 263 | return -ENOMEM; |
223 | 264 | ||
224 | aeb->pnum = pnum; | ||
225 | aeb->vol_id = vol_id; | 265 | aeb->vol_id = vol_id; |
226 | aeb->lnum = lnum; | 266 | aeb->lnum = lnum; |
227 | aeb->ec = ec; | ||
228 | if (to_head) | 267 | if (to_head) |
229 | list_add(&aeb->u.list, list); | 268 | list_add(&aeb->u.list, list); |
230 | else | 269 | else |
@@ -249,13 +288,11 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) | |||
249 | 288 | ||
250 | dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); | 289 | dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); |
251 | 290 | ||
252 | aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); | 291 | aeb = ubi_alloc_aeb(ai, pnum, ec); |
253 | if (!aeb) | 292 | if (!aeb) |
254 | return -ENOMEM; | 293 | return -ENOMEM; |
255 | 294 | ||
256 | ai->corr_peb_count += 1; | 295 | ai->corr_peb_count += 1; |
257 | aeb->pnum = pnum; | ||
258 | aeb->ec = ec; | ||
259 | list_add(&aeb->u.list, &ai->corr); | 296 | list_add(&aeb->u.list, &ai->corr); |
260 | return 0; | 297 | return 0; |
261 | } | 298 | } |
@@ -278,14 +315,12 @@ static int add_fastmap(struct ubi_attach_info *ai, int pnum, | |||
278 | { | 315 | { |
279 | struct ubi_ainf_peb *aeb; | 316 | struct ubi_ainf_peb *aeb; |
280 | 317 | ||
281 | aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); | 318 | aeb = ubi_alloc_aeb(ai, pnum, ec); |
282 | if (!aeb) | 319 | if (!aeb) |
283 | return -ENOMEM; | 320 | return -ENOMEM; |
284 | 321 | ||
285 | aeb->pnum = pnum; | ||
286 | aeb->vol_id = be32_to_cpu(vid_hdr->vol_id); | 322 | aeb->vol_id = be32_to_cpu(vid_hdr->vol_id); |
287 | aeb->sqnum = be64_to_cpu(vid_hdr->sqnum); | 323 | aeb->sqnum = be64_to_cpu(vid_hdr->sqnum); |
288 | aeb->ec = ec; | ||
289 | list_add(&aeb->u.list, &ai->fastmap); | 324 | list_add(&aeb->u.list, &ai->fastmap); |
290 | 325 | ||
291 | dbg_bld("add to fastmap list: PEB %d, vol_id %d, sqnum: %llu", pnum, | 326 | dbg_bld("add to fastmap list: PEB %d, vol_id %d, sqnum: %llu", pnum, |
@@ -667,12 +702,10 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, | |||
667 | if (err) | 702 | if (err) |
668 | return err; | 703 | return err; |
669 | 704 | ||
670 | aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); | 705 | aeb = ubi_alloc_aeb(ai, pnum, ec); |
671 | if (!aeb) | 706 | if (!aeb) |
672 | return -ENOMEM; | 707 | return -ENOMEM; |
673 | 708 | ||
674 | aeb->ec = ec; | ||
675 | aeb->pnum = pnum; | ||
676 | aeb->vol_id = vol_id; | 709 | aeb->vol_id = vol_id; |
677 | aeb->lnum = lnum; | 710 | aeb->lnum = lnum; |
678 | aeb->scrub = bitflips; | 711 | aeb->scrub = bitflips; |
@@ -1278,7 +1311,7 @@ static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av, | |||
1278 | if (list) | 1311 | if (list) |
1279 | list_add_tail(&aeb->u.list, list); | 1312 | list_add_tail(&aeb->u.list, list); |
1280 | else | 1313 | else |
1281 | kmem_cache_free(ai->aeb_slab_cache, aeb); | 1314 | ubi_free_aeb(ai, aeb); |
1282 | } | 1315 | } |
1283 | } | 1316 | } |
1284 | kfree(av); | 1317 | kfree(av); |
@@ -1296,23 +1329,23 @@ static void destroy_ai(struct ubi_attach_info *ai) | |||
1296 | 1329 | ||
1297 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { | 1330 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { |
1298 | list_del(&aeb->u.list); | 1331 | list_del(&aeb->u.list); |
1299 | kmem_cache_free(ai->aeb_slab_cache, aeb); | 1332 | ubi_free_aeb(ai, aeb); |
1300 | } | 1333 | } |
1301 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { | 1334 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { |
1302 | list_del(&aeb->u.list); | 1335 | list_del(&aeb->u.list); |
1303 | kmem_cache_free(ai->aeb_slab_cache, aeb); | 1336 | ubi_free_aeb(ai, aeb); |
1304 | } | 1337 | } |
1305 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { | 1338 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { |
1306 | list_del(&aeb->u.list); | 1339 | list_del(&aeb->u.list); |
1307 | kmem_cache_free(ai->aeb_slab_cache, aeb); | 1340 | ubi_free_aeb(ai, aeb); |
1308 | } | 1341 | } |
1309 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { | 1342 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { |
1310 | list_del(&aeb->u.list); | 1343 | list_del(&aeb->u.list); |
1311 | kmem_cache_free(ai->aeb_slab_cache, aeb); | 1344 | ubi_free_aeb(ai, aeb); |
1312 | } | 1345 | } |
1313 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->fastmap, u.list) { | 1346 | list_for_each_entry_safe(aeb, aeb_tmp, &ai->fastmap, u.list) { |
1314 | list_del(&aeb->u.list); | 1347 | list_del(&aeb->u.list); |
1315 | kmem_cache_free(ai->aeb_slab_cache, aeb); | 1348 | ubi_free_aeb(ai, aeb); |
1316 | } | 1349 | } |
1317 | 1350 | ||
1318 | /* Destroy the volume RB-tree */ | 1351 | /* Destroy the volume RB-tree */ |