summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-10-19 22:00:11 +0300
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-10-21 11:20:36 +0300
commitfb22b59b2c38054cc847f6acc5c46daa26dc6dd3 (patch)
tree76025e34f0934b8e7186972e43849dc4a8f19606 /drivers/mtd/ubi
parent5fc01ab6934c43b42c41bc753fe1123c16d7f38f (diff)
UBI: remember copy_flag while scanning
While scanning the flash we read all VID headers and store some important information in 'struct ubi_scan_leb'. Store also the 'copy_flag' value there as it is needed when comparing LEBs. We do not increase memory consumption because this is just one bit and we have plenty of spare bits in 'struct ubi_scan_leb' (sizeof(struct ubi_scan_leb) is 48 both with and without this patch). Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r--drivers/mtd/ubi/scan.c20
-rw-r--r--drivers/mtd/ubi/scan.h4
2 files changed, 13 insertions, 11 deletions
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 30b710216f2..2fbb571b982 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -330,12 +330,18 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb,
return 1;
}
} else {
- pnum = seb->pnum;
+ if (!seb->copy_flag) {
+ /* It is not a copy, so it is newer */
+ dbg_bld("first PEB %d is newer, copy_flag is unset",
+ pnum);
+ return bitflips << 1;
+ }
vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
if (!vh)
return -ENOMEM;
+ pnum = seb->pnum;
err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
if (err) {
if (err == UBI_IO_BITFLIPS)
@@ -350,14 +356,6 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb,
}
}
- if (!vh->copy_flag) {
- /* It is not a copy, so it is newer */
- dbg_bld("first PEB %d is newer, copy_flag is unset",
- pnum);
- err = bitflips << 1;
- goto out_free_vidh;
- }
-
vid_hdr = vh;
}
@@ -516,6 +514,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
seb->ec = ec;
seb->pnum = pnum;
seb->scrub = ((cmp_res & 2) || bitflips);
+ seb->copy_flag = vid_hdr->copy_flag;
seb->sqnum = sqnum;
if (sv->highest_lnum == lnum)
@@ -549,8 +548,9 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
seb->ec = ec;
seb->pnum = pnum;
seb->lnum = lnum;
- seb->sqnum = sqnum;
seb->scrub = bitflips;
+ seb->copy_flag = vid_hdr->copy_flag;
+ seb->sqnum = sqnum;
if (sv->highest_lnum <= lnum) {
sv->highest_lnum = lnum;
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h
index 12ac852c993..a3264f0bef2 100644
--- a/drivers/mtd/ubi/scan.h
+++ b/drivers/mtd/ubi/scan.h
@@ -30,6 +30,7 @@
* @pnum: physical eraseblock number
* @lnum: logical eraseblock number
* @scrub: if this physical eraseblock needs scrubbing
+ * @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB)
* @sqnum: sequence number
* @u: unions RB-tree or @list links
* @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects
@@ -42,7 +43,8 @@ struct ubi_scan_leb {
int ec;
int pnum;
int lnum;
- int scrub;
+ unsigned int scrub:1;
+ unsigned int copy_flag:1;
unsigned long long sqnum;
union {
struct rb_node rb;