Commit 7eb3aa65 authored by Artem Bityutskiy's avatar Artem Bityutskiy

UBI: fix eraseblock picking criteria

The 'find_wl_entry()' function expects the maximum difference as the second
argument, not the maximum absolute value. So the "unknown" eraseblock picking
was incorrect, as Shmulik Ladkani spotted. This patch fixes the issue.
Reported-by: default avatarShmulik Ladkani <shmulik.ladkani@gmail.com>
Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Reviewed-by: default avatarShmulik Ladkani <shmulik.ladkani@gmail.com>
Cc: stable@kernel.org
parent add8287e
...@@ -390,7 +390,7 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff) ...@@ -390,7 +390,7 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff)
*/ */
int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) int ubi_wl_get_peb(struct ubi_device *ubi, int dtype)
{ {
int err, medium_ec; int err;
struct ubi_wl_entry *e, *first, *last; struct ubi_wl_entry *e, *first, *last;
ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM ||
...@@ -428,7 +428,7 @@ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) ...@@ -428,7 +428,7 @@ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype)
* For unknown data we pick a physical eraseblock with medium * For unknown data we pick a physical eraseblock with medium
* erase counter. But we by no means can pick a physical * erase counter. But we by no means can pick a physical
* eraseblock with erase counter greater or equivalent than the * eraseblock with erase counter greater or equivalent than the
* lowest erase counter plus %WL_FREE_MAX_DIFF. * lowest erase counter plus %WL_FREE_MAX_DIFF/2.
*/ */
first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry,
u.rb); u.rb);
...@@ -437,10 +437,8 @@ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) ...@@ -437,10 +437,8 @@ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype)
if (last->ec - first->ec < WL_FREE_MAX_DIFF) if (last->ec - first->ec < WL_FREE_MAX_DIFF)
e = rb_entry(ubi->free.rb_node, e = rb_entry(ubi->free.rb_node,
struct ubi_wl_entry, u.rb); struct ubi_wl_entry, u.rb);
else { else
medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2; e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2);
e = find_wl_entry(&ubi->free, medium_ec);
}
break; break;
case UBI_SHORTTERM: case UBI_SHORTTERM:
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment