aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@free-electrons.com>2016-09-16 10:59:18 -0400
committerRichard Weinberger <richard@nod.at>2016-10-02 16:48:14 -0400
commit91f4285fe389a2729efcd5db642d7652d8f27a40 (patch)
treeb2c5374b3457c9a8b955b3a63d3651e2cfb1736b
parentfcbb6af17bda4b3856a1f4c302da5d0d7bf9a0f9 (diff)
UBI: provide helpers to allocate and free aeb elements
This not only hides the aeb allocation internals (which is always good in case we ever want to change the allocation system), but also helps us factorize the initialization of some common fields (ec and pnum). Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Signed-off-by: Richard Weinberger <richard@nod.at>
-rw-r--r--drivers/mtd/ubi/attach.c69
-rw-r--r--drivers/mtd/ubi/fastmap.c28
-rw-r--r--drivers/mtd/ubi/ubi.h3
-rw-r--r--drivers/mtd/ubi/vtbl.c4
4 files changed, 66 insertions, 38 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 */
195struct 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 */
220void 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 */
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 7a07b8b53081..25e80a749a52 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -145,12 +145,10 @@ static int add_aeb(struct ubi_attach_info *ai, struct list_head *list,
145{ 145{
146 struct ubi_ainf_peb *aeb; 146 struct ubi_ainf_peb *aeb;
147 147
148 aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); 148 aeb = ubi_alloc_aeb(ai, pnum, ec);
149 if (!aeb) 149 if (!aeb)
150 return -ENOMEM; 150 return -ENOMEM;
151 151
152 aeb->pnum = pnum;
153 aeb->ec = ec;
154 aeb->lnum = -1; 152 aeb->lnum = -1;
155 aeb->scrub = scrub; 153 aeb->scrub = scrub;
156 aeb->copy_flag = aeb->sqnum = 0; 154 aeb->copy_flag = aeb->sqnum = 0;
@@ -276,7 +274,7 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
276 */ 274 */
277 if (aeb->pnum == new_aeb->pnum) { 275 if (aeb->pnum == new_aeb->pnum) {
278 ubi_assert(aeb->lnum == new_aeb->lnum); 276 ubi_assert(aeb->lnum == new_aeb->lnum);
279 kmem_cache_free(ai->aeb_slab_cache, new_aeb); 277 ubi_free_aeb(ai, new_aeb);
280 278
281 return 0; 279 return 0;
282 } 280 }
@@ -287,13 +285,10 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
287 285
288 /* new_aeb is newer */ 286 /* new_aeb is newer */
289 if (cmp_res & 1) { 287 if (cmp_res & 1) {
290 victim = kmem_cache_alloc(ai->aeb_slab_cache, 288 victim = ubi_alloc_aeb(ai, aeb->ec, aeb->pnum);
291 GFP_KERNEL);
292 if (!victim) 289 if (!victim)
293 return -ENOMEM; 290 return -ENOMEM;
294 291
295 victim->ec = aeb->ec;
296 victim->pnum = aeb->pnum;
297 list_add_tail(&victim->u.list, &ai->erase); 292 list_add_tail(&victim->u.list, &ai->erase);
298 293
299 if (av->highest_lnum == be32_to_cpu(new_vh->lnum)) 294 if (av->highest_lnum == be32_to_cpu(new_vh->lnum))
@@ -307,7 +302,7 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
307 aeb->pnum = new_aeb->pnum; 302 aeb->pnum = new_aeb->pnum;
308 aeb->copy_flag = new_vh->copy_flag; 303 aeb->copy_flag = new_vh->copy_flag;
309 aeb->scrub = new_aeb->scrub; 304 aeb->scrub = new_aeb->scrub;
310 kmem_cache_free(ai->aeb_slab_cache, new_aeb); 305 ubi_free_aeb(ai, new_aeb);
311 306
312 /* new_aeb is older */ 307 /* new_aeb is older */
313 } else { 308 } else {
@@ -353,7 +348,7 @@ static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai,
353 struct ubi_ainf_volume *av; 348 struct ubi_ainf_volume *av;
354 349
355 if (vol_id == UBI_FM_SB_VOLUME_ID || vol_id == UBI_FM_DATA_VOLUME_ID) { 350 if (vol_id == UBI_FM_SB_VOLUME_ID || vol_id == UBI_FM_DATA_VOLUME_ID) {
356 kmem_cache_free(ai->aeb_slab_cache, new_aeb); 351 ubi_free_aeb(ai, new_aeb);
357 352
358 return 0; 353 return 0;
359 } 354 }
@@ -362,7 +357,7 @@ static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai,
362 av = ubi_find_av(ai, vol_id); 357 av = ubi_find_av(ai, vol_id);
363 if (!av) { 358 if (!av) {
364 ubi_err(ubi, "orphaned volume in fastmap pool!"); 359 ubi_err(ubi, "orphaned volume in fastmap pool!");
365 kmem_cache_free(ai->aeb_slab_cache, new_aeb); 360 ubi_free_aeb(ai, new_aeb);
366 return UBI_BAD_FASTMAP; 361 return UBI_BAD_FASTMAP;
367 } 362 }
368 363
@@ -390,7 +385,7 @@ static void unmap_peb(struct ubi_attach_info *ai, int pnum)
390 if (aeb->pnum == pnum) { 385 if (aeb->pnum == pnum) {
391 rb_erase(&aeb->u.rb, &av->root); 386 rb_erase(&aeb->u.rb, &av->root);
392 av->leb_count--; 387 av->leb_count--;
393 kmem_cache_free(ai->aeb_slab_cache, aeb); 388 ubi_free_aeb(ai, aeb);
394 return; 389 return;
395 } 390 }
396 } 391 }
@@ -485,15 +480,12 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
485 if (err == UBI_IO_BITFLIPS) 480 if (err == UBI_IO_BITFLIPS)
486 scrub = 1; 481 scrub = 1;
487 482
488 new_aeb = kmem_cache_alloc(ai->aeb_slab_cache, 483 new_aeb = ubi_alloc_aeb(ai, pnum, be64_to_cpu(ech->ec));
489 GFP_KERNEL);
490 if (!new_aeb) { 484 if (!new_aeb) {
491 ret = -ENOMEM; 485 ret = -ENOMEM;
492 goto out; 486 goto out;
493 } 487 }
494 488
495 new_aeb->ec = be64_to_cpu(ech->ec);
496 new_aeb->pnum = pnum;
497 new_aeb->lnum = be32_to_cpu(vh->lnum); 489 new_aeb->lnum = be32_to_cpu(vh->lnum);
498 new_aeb->sqnum = be64_to_cpu(vh->sqnum); 490 new_aeb->sqnum = be64_to_cpu(vh->sqnum);
499 new_aeb->copy_flag = vh->copy_flag; 491 new_aeb->copy_flag = vh->copy_flag;
@@ -800,11 +792,11 @@ fail_bad:
800fail: 792fail:
801 list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) { 793 list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) {
802 list_del(&tmp_aeb->u.list); 794 list_del(&tmp_aeb->u.list);
803 kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); 795 ubi_free_aeb(ai, tmp_aeb);
804 } 796 }
805 list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { 797 list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
806 list_del(&tmp_aeb->u.list); 798 list_del(&tmp_aeb->u.list);
807 kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); 799 ubi_free_aeb(ai, tmp_aeb);
808 } 800 }
809 801
810 return ret; 802 return ret;
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index fce142666bf3..f22c6c2e980f 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -792,6 +792,9 @@ extern struct mutex ubi_devices_mutex;
792extern struct blocking_notifier_head ubi_notifiers; 792extern struct blocking_notifier_head ubi_notifiers;
793 793
794/* attach.c */ 794/* attach.c */
795struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum,
796 int ec);
797void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb);
795int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, 798int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
796 int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); 799 int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips);
797struct ubi_ainf_volume *ubi_add_av(struct ubi_attach_info *ai, int vol_id); 800struct ubi_ainf_volume *ubi_add_av(struct ubi_attach_info *ai, int vol_id);
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index d85c19762160..9e1457708cbf 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -338,7 +338,7 @@ retry:
338 * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'. 338 * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'.
339 */ 339 */
340 err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); 340 err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0);
341 kmem_cache_free(ai->aeb_slab_cache, new_aeb); 341 ubi_free_aeb(ai, new_aeb);
342 ubi_free_vid_hdr(ubi, vid_hdr); 342 ubi_free_vid_hdr(ubi, vid_hdr);
343 return err; 343 return err;
344 344
@@ -351,7 +351,7 @@ write_error:
351 list_add(&new_aeb->u.list, &ai->erase); 351 list_add(&new_aeb->u.list, &ai->erase);
352 goto retry; 352 goto retry;
353 } 353 }
354 kmem_cache_free(ai->aeb_slab_cache, new_aeb); 354 ubi_free_aeb(ai, new_aeb);
355out_free: 355out_free:
356 ubi_free_vid_hdr(ubi, vid_hdr); 356 ubi_free_vid_hdr(ubi, vid_hdr);
357 return err; 357 return err;