UBI: prepare for protection tree improvements

This patch modifies @struct ubi_wl_entry and adds union which
contains only one element so far. This is just a preparation
for further changes which will kill the protection tree and
make UBI use a list instead.

Signed-off-by: Xiaochuan-Xu <xiaochuan-xu@cqu.edu.cn>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
Xiaochuan-Xu 2008-12-09 19:44:12 +08:00 committed by Artem Bityutskiy
parent ad5942bad6
commit 23553b2c08
2 changed files with 27 additions and 24 deletions

View File

@ -95,7 +95,7 @@ enum {
/** /**
* struct ubi_wl_entry - wear-leveling entry. * struct ubi_wl_entry - wear-leveling entry.
* @rb: link in the corresponding RB-tree * @u.rb: link in the corresponding (free/used) RB-tree
* @ec: erase counter * @ec: erase counter
* @pnum: physical eraseblock number * @pnum: physical eraseblock number
* *
@ -104,7 +104,9 @@ enum {
* RB-trees. See WL sub-system for details. * RB-trees. See WL sub-system for details.
*/ */
struct ubi_wl_entry { struct ubi_wl_entry {
struct rb_node rb; union {
struct rb_node rb;
} u;
int ec; int ec;
int pnum; int pnum;
}; };

View File

@ -220,7 +220,7 @@ static void wl_tree_add(struct ubi_wl_entry *e, struct rb_root *root)
struct ubi_wl_entry *e1; struct ubi_wl_entry *e1;
parent = *p; parent = *p;
e1 = rb_entry(parent, struct ubi_wl_entry, rb); e1 = rb_entry(parent, struct ubi_wl_entry, u.rb);
if (e->ec < e1->ec) if (e->ec < e1->ec)
p = &(*p)->rb_left; p = &(*p)->rb_left;
@ -235,8 +235,8 @@ static void wl_tree_add(struct ubi_wl_entry *e, struct rb_root *root)
} }
} }
rb_link_node(&e->rb, parent, p); rb_link_node(&e->u.rb, parent, p);
rb_insert_color(&e->rb, root); rb_insert_color(&e->u.rb, root);
} }
/** /**
@ -331,7 +331,7 @@ static int in_wl_tree(struct ubi_wl_entry *e, struct rb_root *root)
while (p) { while (p) {
struct ubi_wl_entry *e1; struct ubi_wl_entry *e1;
e1 = rb_entry(p, struct ubi_wl_entry, rb); e1 = rb_entry(p, struct ubi_wl_entry, u.rb);
if (e->pnum == e1->pnum) { if (e->pnum == e1->pnum) {
ubi_assert(e == e1); ubi_assert(e == e1);
@ -413,14 +413,14 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max)
struct rb_node *p; struct rb_node *p;
struct ubi_wl_entry *e; struct ubi_wl_entry *e;
e = rb_entry(rb_first(root), struct ubi_wl_entry, rb); e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb);
max += e->ec; max += e->ec;
p = root->rb_node; p = root->rb_node;
while (p) { while (p) {
struct ubi_wl_entry *e1; struct ubi_wl_entry *e1;
e1 = rb_entry(p, struct ubi_wl_entry, rb); e1 = rb_entry(p, struct ubi_wl_entry, u.rb);
if (e1->ec >= max) if (e1->ec >= max)
p = p->rb_left; p = p->rb_left;
else { else {
@ -491,12 +491,13 @@ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype)
* 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.
*/ */
first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, rb); first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry,
last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, rb); u.rb);
last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb);
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, rb); struct ubi_wl_entry, u.rb);
else { else {
medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2; medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2;
e = find_wl_entry(&ubi->free, medium_ec); e = find_wl_entry(&ubi->free, medium_ec);
@ -508,7 +509,7 @@ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype)
* For short term data we pick a physical eraseblock with the * For short term data we pick a physical eraseblock with the
* lowest erase counter as we expect it will be erased soon. * lowest erase counter as we expect it will be erased soon.
*/ */
e = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, rb); e = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb);
protect = ST_PROTECTION; protect = ST_PROTECTION;
break; break;
default: default:
@ -522,7 +523,7 @@ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype)
* be protected from being moved for some time. * be protected from being moved for some time.
*/ */
paranoid_check_in_wl_tree(e, &ubi->free); paranoid_check_in_wl_tree(e, &ubi->free);
rb_erase(&e->rb, &ubi->free); rb_erase(&e->u.rb, &ubi->free);
prot_tree_add(ubi, e, pe, protect); prot_tree_add(ubi, e, pe, protect);
dbg_wl("PEB %d EC %d, protection %d", e->pnum, e->ec, protect); dbg_wl("PEB %d EC %d, protection %d", e->pnum, e->ec, protect);
@ -779,7 +780,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
* highly worn-out free physical eraseblock. If the erase * highly worn-out free physical eraseblock. If the erase
* counters differ much enough, start wear-leveling. * counters differ much enough, start wear-leveling.
*/ */
e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, rb); e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb);
e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) {
@ -788,21 +789,21 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
goto out_cancel; goto out_cancel;
} }
paranoid_check_in_wl_tree(e1, &ubi->used); paranoid_check_in_wl_tree(e1, &ubi->used);
rb_erase(&e1->rb, &ubi->used); rb_erase(&e1->u.rb, &ubi->used);
dbg_wl("move PEB %d EC %d to PEB %d EC %d", dbg_wl("move PEB %d EC %d to PEB %d EC %d",
e1->pnum, e1->ec, e2->pnum, e2->ec); e1->pnum, e1->ec, e2->pnum, e2->ec);
} else { } else {
/* Perform scrubbing */ /* Perform scrubbing */
scrubbing = 1; scrubbing = 1;
e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, rb); e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, u.rb);
e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
paranoid_check_in_wl_tree(e1, &ubi->scrub); paranoid_check_in_wl_tree(e1, &ubi->scrub);
rb_erase(&e1->rb, &ubi->scrub); rb_erase(&e1->u.rb, &ubi->scrub);
dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum); dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum);
} }
paranoid_check_in_wl_tree(e2, &ubi->free); paranoid_check_in_wl_tree(e2, &ubi->free);
rb_erase(&e2->rb, &ubi->free); rb_erase(&e2->u.rb, &ubi->free);
ubi->move_from = e1; ubi->move_from = e1;
ubi->move_to = e2; ubi->move_to = e2;
spin_unlock(&ubi->wl_lock); spin_unlock(&ubi->wl_lock);
@ -1012,7 +1013,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi)
* erase counter of free physical eraseblocks is greater then * erase counter of free physical eraseblocks is greater then
* %UBI_WL_THRESHOLD. * %UBI_WL_THRESHOLD.
*/ */
e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, rb); e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb);
e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD))
@ -1214,10 +1215,10 @@ int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture)
} else { } else {
if (in_wl_tree(e, &ubi->used)) { if (in_wl_tree(e, &ubi->used)) {
paranoid_check_in_wl_tree(e, &ubi->used); paranoid_check_in_wl_tree(e, &ubi->used);
rb_erase(&e->rb, &ubi->used); rb_erase(&e->u.rb, &ubi->used);
} else if (in_wl_tree(e, &ubi->scrub)) { } else if (in_wl_tree(e, &ubi->scrub)) {
paranoid_check_in_wl_tree(e, &ubi->scrub); paranoid_check_in_wl_tree(e, &ubi->scrub);
rb_erase(&e->rb, &ubi->scrub); rb_erase(&e->u.rb, &ubi->scrub);
} else { } else {
err = prot_tree_del(ubi, e->pnum); err = prot_tree_del(ubi, e->pnum);
if (err) { if (err) {
@ -1279,7 +1280,7 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum)
if (in_wl_tree(e, &ubi->used)) { if (in_wl_tree(e, &ubi->used)) {
paranoid_check_in_wl_tree(e, &ubi->used); paranoid_check_in_wl_tree(e, &ubi->used);
rb_erase(&e->rb, &ubi->used); rb_erase(&e->u.rb, &ubi->used);
} else { } else {
int err; int err;
@ -1361,11 +1362,11 @@ static void tree_destroy(struct rb_root *root)
else if (rb->rb_right) else if (rb->rb_right)
rb = rb->rb_right; rb = rb->rb_right;
else { else {
e = rb_entry(rb, struct ubi_wl_entry, rb); e = rb_entry(rb, struct ubi_wl_entry, u.rb);
rb = rb_parent(rb); rb = rb_parent(rb);
if (rb) { if (rb) {
if (rb->rb_left == &e->rb) if (rb->rb_left == &e->u.rb)
rb->rb_left = NULL; rb->rb_left = NULL;
else else
rb->rb_right = NULL; rb->rb_right = NULL;