Skip to content

Commit

Permalink
UBI: provide helpers to allocate and free aeb elements
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Boris Brezillon authored and Richard Weinberger committed Oct 2, 2016
1 parent fcbb6af commit 91f4285
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 38 deletions.
69 changes: 51 additions & 18 deletions drivers/mtd/ubi/attach.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,47 @@ static struct ubi_ainf_volume *ubi_find_or_add_av(struct ubi_attach_info *ai,
return find_or_add_av(ai, vol_id, AV_FIND_OR_ADD, created);
}

/**
* ubi_alloc_aeb - allocate an aeb element
* @ai: attaching information
* @pnum: physical eraseblock number
* @ec: erase counter of the physical eraseblock
*
* Allocate an aeb object and initialize the pnum and ec information.
* vol_id and lnum are set to UBI_UNKNOWN, and the other fields are
* initialized to zero.
* Note that the element is not added in any list or RB tree.
*/
struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum,
int ec)
{
struct ubi_ainf_peb *aeb;

aeb = kmem_cache_zalloc(ai->aeb_slab_cache, GFP_KERNEL);
if (!aeb)
return NULL;

aeb->pnum = pnum;
aeb->ec = ec;
aeb->vol_id = UBI_UNKNOWN;
aeb->lnum = UBI_UNKNOWN;

return aeb;
}

/**
* ubi_free_aeb - free an aeb element
* @ai: attaching information
* @aeb: the element to free
*
* Free an aeb object. The caller must have removed the element from any list
* or RB tree.
*/
void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb)
{
kmem_cache_free(ai->aeb_slab_cache, aeb);
}

/**
* add_to_list - add physical eraseblock to a list.
* @ai: attaching information
Expand Down Expand Up @@ -217,14 +258,12 @@ static int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id,
} else
BUG();

aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
aeb = ubi_alloc_aeb(ai, pnum, ec);
if (!aeb)
return -ENOMEM;

aeb->pnum = pnum;
aeb->vol_id = vol_id;
aeb->lnum = lnum;
aeb->ec = ec;
if (to_head)
list_add(&aeb->u.list, list);
else
Expand All @@ -249,13 +288,11 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec)

dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec);

aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
aeb = ubi_alloc_aeb(ai, pnum, ec);
if (!aeb)
return -ENOMEM;

ai->corr_peb_count += 1;
aeb->pnum = pnum;
aeb->ec = ec;
list_add(&aeb->u.list, &ai->corr);
return 0;
}
Expand All @@ -278,14 +315,12 @@ static int add_fastmap(struct ubi_attach_info *ai, int pnum,
{
struct ubi_ainf_peb *aeb;

aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
aeb = ubi_alloc_aeb(ai, pnum, ec);
if (!aeb)
return -ENOMEM;

aeb->pnum = pnum;
aeb->vol_id = be32_to_cpu(vid_hdr->vol_id);
aeb->sqnum = be64_to_cpu(vid_hdr->sqnum);
aeb->ec = ec;
list_add(&aeb->u.list, &ai->fastmap);

dbg_bld("add to fastmap list: PEB %d, vol_id %d, sqnum: %llu", pnum,
Expand Down Expand Up @@ -667,12 +702,10 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
if (err)
return err;

aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
aeb = ubi_alloc_aeb(ai, pnum, ec);
if (!aeb)
return -ENOMEM;

aeb->ec = ec;
aeb->pnum = pnum;
aeb->vol_id = vol_id;
aeb->lnum = lnum;
aeb->scrub = bitflips;
Expand Down Expand Up @@ -1278,7 +1311,7 @@ static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av,
if (list)
list_add_tail(&aeb->u.list, list);
else
kmem_cache_free(ai->aeb_slab_cache, aeb);
ubi_free_aeb(ai, aeb);
}
}
kfree(av);
Expand All @@ -1296,23 +1329,23 @@ static void destroy_ai(struct ubi_attach_info *ai)

list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) {
list_del(&aeb->u.list);
kmem_cache_free(ai->aeb_slab_cache, aeb);
ubi_free_aeb(ai, aeb);
}
list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) {
list_del(&aeb->u.list);
kmem_cache_free(ai->aeb_slab_cache, aeb);
ubi_free_aeb(ai, aeb);
}
list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) {
list_del(&aeb->u.list);
kmem_cache_free(ai->aeb_slab_cache, aeb);
ubi_free_aeb(ai, aeb);
}
list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) {
list_del(&aeb->u.list);
kmem_cache_free(ai->aeb_slab_cache, aeb);
ubi_free_aeb(ai, aeb);
}
list_for_each_entry_safe(aeb, aeb_tmp, &ai->fastmap, u.list) {
list_del(&aeb->u.list);
kmem_cache_free(ai->aeb_slab_cache, aeb);
ubi_free_aeb(ai, aeb);
}

/* Destroy the volume RB-tree */
Expand Down
28 changes: 10 additions & 18 deletions drivers/mtd/ubi/fastmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,10 @@ static int add_aeb(struct ubi_attach_info *ai, struct list_head *list,
{
struct ubi_ainf_peb *aeb;

aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
aeb = ubi_alloc_aeb(ai, pnum, ec);
if (!aeb)
return -ENOMEM;

aeb->pnum = pnum;
aeb->ec = ec;
aeb->lnum = -1;
aeb->scrub = scrub;
aeb->copy_flag = aeb->sqnum = 0;
Expand Down Expand Up @@ -276,7 +274,7 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
*/
if (aeb->pnum == new_aeb->pnum) {
ubi_assert(aeb->lnum == new_aeb->lnum);
kmem_cache_free(ai->aeb_slab_cache, new_aeb);
ubi_free_aeb(ai, new_aeb);

return 0;
}
Expand All @@ -287,13 +285,10 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,

/* new_aeb is newer */
if (cmp_res & 1) {
victim = kmem_cache_alloc(ai->aeb_slab_cache,
GFP_KERNEL);
victim = ubi_alloc_aeb(ai, aeb->ec, aeb->pnum);
if (!victim)
return -ENOMEM;

victim->ec = aeb->ec;
victim->pnum = aeb->pnum;
list_add_tail(&victim->u.list, &ai->erase);

if (av->highest_lnum == be32_to_cpu(new_vh->lnum))
Expand All @@ -307,7 +302,7 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
aeb->pnum = new_aeb->pnum;
aeb->copy_flag = new_vh->copy_flag;
aeb->scrub = new_aeb->scrub;
kmem_cache_free(ai->aeb_slab_cache, new_aeb);
ubi_free_aeb(ai, new_aeb);

/* new_aeb is older */
} else {
Expand Down Expand Up @@ -353,7 +348,7 @@ static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai,
struct ubi_ainf_volume *av;

if (vol_id == UBI_FM_SB_VOLUME_ID || vol_id == UBI_FM_DATA_VOLUME_ID) {
kmem_cache_free(ai->aeb_slab_cache, new_aeb);
ubi_free_aeb(ai, new_aeb);

return 0;
}
Expand All @@ -362,7 +357,7 @@ static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai,
av = ubi_find_av(ai, vol_id);
if (!av) {
ubi_err(ubi, "orphaned volume in fastmap pool!");
kmem_cache_free(ai->aeb_slab_cache, new_aeb);
ubi_free_aeb(ai, new_aeb);
return UBI_BAD_FASTMAP;
}

Expand Down Expand Up @@ -390,7 +385,7 @@ static void unmap_peb(struct ubi_attach_info *ai, int pnum)
if (aeb->pnum == pnum) {
rb_erase(&aeb->u.rb, &av->root);
av->leb_count--;
kmem_cache_free(ai->aeb_slab_cache, aeb);
ubi_free_aeb(ai, aeb);
return;
}
}
Expand Down Expand Up @@ -485,15 +480,12 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
if (err == UBI_IO_BITFLIPS)
scrub = 1;

new_aeb = kmem_cache_alloc(ai->aeb_slab_cache,
GFP_KERNEL);
new_aeb = ubi_alloc_aeb(ai, pnum, be64_to_cpu(ech->ec));
if (!new_aeb) {
ret = -ENOMEM;
goto out;
}

new_aeb->ec = be64_to_cpu(ech->ec);
new_aeb->pnum = pnum;
new_aeb->lnum = be32_to_cpu(vh->lnum);
new_aeb->sqnum = be64_to_cpu(vh->sqnum);
new_aeb->copy_flag = vh->copy_flag;
Expand Down Expand Up @@ -800,11 +792,11 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
fail:
list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) {
list_del(&tmp_aeb->u.list);
kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
ubi_free_aeb(ai, tmp_aeb);
}
list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
list_del(&tmp_aeb->u.list);
kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
ubi_free_aeb(ai, tmp_aeb);
}

return ret;
Expand Down
3 changes: 3 additions & 0 deletions drivers/mtd/ubi/ubi.h
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,9 @@ extern struct mutex ubi_devices_mutex;
extern struct blocking_notifier_head ubi_notifiers;

/* attach.c */
struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum,
int ec);
void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb);
int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips);
struct ubi_ainf_volume *ubi_add_av(struct ubi_attach_info *ai, int vol_id);
Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/ubi/vtbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *ai,
* of this LEB as it will be deleted and freed in 'ubi_add_to_av()'.
*/
err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0);
kmem_cache_free(ai->aeb_slab_cache, new_aeb);
ubi_free_aeb(ai, new_aeb);
ubi_free_vid_hdr(ubi, vid_hdr);
return err;

Expand All @@ -351,7 +351,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *ai,
list_add(&new_aeb->u.list, &ai->erase);
goto retry;
}
kmem_cache_free(ai->aeb_slab_cache, new_aeb);
ubi_free_aeb(ai, new_aeb);
out_free:
ubi_free_vid_hdr(ubi, vid_hdr);
return err;
Expand Down

0 comments on commit 91f4285

Please sign in to comment.