Skip to content

Commit

Permalink
UBI: Add self_check_eba()
Browse files Browse the repository at this point in the history
self_check_eba() compares two ubi_attach_info objects.
Fastmap uses this function for self checks.

Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
  • Loading branch information
Richard Weinberger authored and Artem Bityutskiy committed Oct 3, 2012
1 parent a730665 commit 00abf30
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions drivers/mtd/ubi/eba.c
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,102 @@ static void print_rsvd_warning(struct ubi_device *ubi,
ubi->corr_peb_count);
}

/**
* self_check_eba - run a self check on the EBA table constructed by fastmap.
* @ubi: UBI device description object
* @ai_fastmap: UBI attach info object created by fastmap
* @ai_scan: UBI attach info object created by scanning
*
* Returns < 0 in case of an internal error, 0 otherwise.
* If a bad EBA table entry was found it will be printed out and
* ubi_assert() triggers.
*/
int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
struct ubi_attach_info *ai_scan)
{
int i, j, num_volumes, ret = 0;
int **scan_eba, **fm_eba;
struct ubi_ainf_volume *av;
struct ubi_volume *vol;
struct ubi_ainf_peb *aeb;
struct rb_node *rb;

num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT;

scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL);
if (!scan_eba)
return -ENOMEM;

fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL);
if (!fm_eba) {
kfree(scan_eba);
return -ENOMEM;
}

for (i = 0; i < num_volumes; i++) {
vol = ubi->volumes[i];
if (!vol)
continue;

scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba),
GFP_KERNEL);
if (!scan_eba[i]) {
ret = -ENOMEM;
goto out_free;
}

fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba),
GFP_KERNEL);
if (!fm_eba[i]) {
ret = -ENOMEM;
goto out_free;
}

for (j = 0; j < vol->reserved_pebs; j++)
scan_eba[i][j] = fm_eba[i][j] = UBI_LEB_UNMAPPED;

av = ubi_find_av(ai_scan, idx2vol_id(ubi, i));
if (!av)
continue;

ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
scan_eba[i][aeb->lnum] = aeb->pnum;

av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i));
if (!av)
continue;

ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
fm_eba[i][aeb->lnum] = aeb->pnum;

for (j = 0; j < vol->reserved_pebs; j++) {
if (scan_eba[i][j] != fm_eba[i][j]) {
if (scan_eba[i][j] == UBI_LEB_UNMAPPED ||
fm_eba[i][j] == UBI_LEB_UNMAPPED)
continue;

ubi_err("LEB:%i:%i is PEB:%i instead of %i!",
vol->vol_id, i, fm_eba[i][j],
scan_eba[i][j]);
ubi_assert(0);
}
}
}

out_free:
for (i = 0; i < num_volumes; i++) {
if (!ubi->volumes[i])
continue;

kfree(scan_eba[i]);
kfree(fm_eba[i]);
}

kfree(scan_eba);
kfree(fm_eba);
return ret;
}

/**
* ubi_eba_init - initialize the EBA sub-system using attaching information.
* @ubi: UBI device description object
Expand Down

0 comments on commit 00abf30

Please sign in to comment.