ubi: suspicious calculation in 'ubi_wl_get_peb'

Artem Bityutskiy dedekind1 at gmail.com
Wed Mar 7 12:20:08 EST 2012


On Fri, 2012-02-17 at 15:38 +0200, Shmulik Ladkani wrote:
> -			e = find_wl_entry(&ubi->free, medium_ec);
> +			e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2)
> 
> Did I get something wrong?

Yeah, I think you are right. Now I am completely convinced we should
remove this "short/long-term" stuff because this did even work
correctly :-)

CCint Richard - I happened to suggest the removal to him earlier today.

What do you think about these untested fixes (also attached):

From: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Date: Wed, 7 Mar 2012 18:56:29 +0200
Subject: [PATCH 1/2] UBI: fix documentation and improve readability

The "max" parameter of 'find_wl_entry()' was documented incorrectly and
it actually means the maximum possible difference, not the maximum absolute
value. Rename it to "diff" instead, and amend the documentation.

Reported-by: Shmulik Ladkani <shmulik.ladkani at gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
---
 drivers/mtd/ubi/wl.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 0696e36..10d7b98 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -350,18 +350,19 @@ static void prot_queue_add(struct ubi_device *ubi, struct ubi_wl_entry *e)
 /**
  * find_wl_entry - find wear-leveling entry closest to certain erase counter.
  * @root: the RB-tree where to look for
- * @max: highest possible erase counter
+ * @diff: highest possible erase counter difference
  *
  * This function looks for a wear leveling entry with erase counter closest to
- * @max and less than @max.
+ * min + @diff, where min is the currently smallest erase counter.
  */
-static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max)
+static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff)
 {
 	struct rb_node *p;
 	struct ubi_wl_entry *e;
+	int max;
 
 	e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb);
-	max += e->ec;
+	max = e->ec + diff;
 
 	p = root->rb_node;
 	while (p) {
-- 
1.7.9.1

From: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Date: Wed, 7 Mar 2012 19:08:36 +0200
Subject: [PATCH 2/2] 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: Shmulik Ladkani <shmulik.ladkani at gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Cc: stable at kernel.org
---
 drivers/mtd/ubi/wl.c |    8 +++-----
 1 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 10d7b98..051cb3a 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -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 err, medium_ec;
+	int err;
 	struct ubi_wl_entry *e, *first, *last;
 
 	ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM ||
@@ -437,10 +437,8 @@ retry:
 		if (last->ec - first->ec < WL_FREE_MAX_DIFF)
 			e = rb_entry(ubi->free.rb_node,
 					struct ubi_wl_entry, u.rb);
-		else {
-			medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2;
-			e = find_wl_entry(&ubi->free, medium_ec);
-		}
+		else
+			e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2);
 		break;
 	case UBI_SHORTTERM:
 		/*
-- 
1.7.9.1

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-UBI-fix-documentation-and-improve-readability.patch
Type: text/x-patch
Size: 1773 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20120307/2d181f63/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-UBI-fix-eraseblock-picking-criteria.patch
Type: text/x-patch
Size: 1810 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20120307/2d181f63/attachment-0001.bin>


More information about the linux-mtd mailing list