aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-10-19 15:00:11 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-10-21 04:20:36 -0400
commitfb22b59b2c38054cc847f6acc5c46daa26dc6dd3 (patch)
tree76025e34f0934b8e7186972e43849dc4a8f19606
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>
-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 30b710216f26..2fbb571b9828 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,
330 return 1; 330 return 1;
331 } 331 }
332 } else { 332 } else {
333 pnum = seb->pnum; 333 if (!seb->copy_flag) {
334 /* It is not a copy, so it is newer */
335 dbg_bld("first PEB %d is newer, copy_flag is unset",
336 pnum);
337 return bitflips << 1;
338 }
334 339
335 vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); 340 vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
336 if (!vh) 341 if (!vh)
337 return -ENOMEM; 342 return -ENOMEM;
338 343
344 pnum = seb->pnum;
339 err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); 345 err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
340 if (err) { 346 if (err) {
341 if (err == UBI_IO_BITFLIPS) 347 if (err == UBI_IO_BITFLIPS)
@@ -350,14 +356,6 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb,
350 } 356 }
351 } 357 }
352 358
353 if (!vh->copy_flag) {
354 /* It is not a copy, so it is newer */
355 dbg_bld("first PEB %d is newer, copy_flag is unset",
356 pnum);
357 err = bitflips << 1;
358 goto out_free_vidh;
359 }
360
361 vid_hdr = vh; 359 vid_hdr = vh;
362 } 360 }
363 361
@@ -516,6 +514,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
516 seb->ec = ec; 514 seb->ec = ec;
517 seb->pnum = pnum; 515 seb->pnum = pnum;
518 seb->scrub = ((cmp_res & 2) || bitflips); 516 seb->scrub = ((cmp_res & 2) || bitflips);
517 seb->copy_flag = vid_hdr->copy_flag;
519 seb->sqnum = sqnum; 518 seb->sqnum = sqnum;
520 519
521 if (sv->highest_lnum == lnum) 520 if (sv->highest_lnum == lnum)
@@ -549,8 +548,9 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
549 seb->ec = ec; 548 seb->ec = ec;
550 seb->pnum = pnum; 549 seb->pnum = pnum;
551 seb->lnum = lnum; 550 seb->lnum = lnum;
552 seb->sqnum = sqnum;
553 seb->scrub = bitflips; 551 seb->scrub = bitflips;
552 seb->copy_flag = vid_hdr->copy_flag;
553 seb->sqnum = sqnum;
554 554
555 if (sv->highest_lnum <= lnum) { 555 if (sv->highest_lnum <= lnum) {
556 sv->highest_lnum = lnum; 556 sv->highest_lnum = lnum;
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h
index 12ac852c993b..a3264f0bef2b 100644
--- a/drivers/mtd/ubi/scan.h
+++ b/drivers/mtd/ubi/scan.h
@@ -30,6 +30,7 @@
30 * @pnum: physical eraseblock number 30 * @pnum: physical eraseblock number
31 * @lnum: logical eraseblock number 31 * @lnum: logical eraseblock number
32 * @scrub: if this physical eraseblock needs scrubbing 32 * @scrub: if this physical eraseblock needs scrubbing
33 * @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB)
33 * @sqnum: sequence number 34 * @sqnum: sequence number
34 * @u: unions RB-tree or @list links 35 * @u: unions RB-tree or @list links
35 * @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects 36 * @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects
@@ -42,7 +43,8 @@ struct ubi_scan_leb {
42 int ec; 43 int ec;
43 int pnum; 44 int pnum;
44 int lnum; 45 int lnum;
45 int scrub; 46 unsigned int scrub:1;
47 unsigned int copy_flag:1;
46 unsigned long long sqnum; 48 unsigned long long sqnum;
47 union { 49 union {
48 struct rb_node rb; 50 struct rb_node rb;