mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 10:19:47 +00:00
UBI: Add self_check_eba()
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>
This commit is contained in:
parent
a730665370
commit
00abf30415
1 changed files with 96 additions and 0 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue