Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+13 -11
+10 -10
drivers/mtd/ubi/scan.c
··· 330 330 return 1; 331 331 } 332 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 340 vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); 336 341 if (!vh) 337 342 return -ENOMEM; 338 343 344 + pnum = seb->pnum; 339 345 err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); 340 346 if (err) { 341 347 if (err == UBI_IO_BITFLIPS) ··· 354 348 355 349 goto out_free_vidh; 356 350 } 357 - } 358 - 359 - if (!vh->copy_flag) { 360 - /* It is not a copy, so it is newer */ 361 - dbg_bld("first PEB %d is newer, copy_flag is unset", 362 - pnum); 363 - err = bitflips << 1; 364 - goto out_free_vidh; 365 351 } 366 352 367 353 vid_hdr = vh; ··· 514 516 seb->ec = ec; 515 517 seb->pnum = pnum; 516 518 seb->scrub = ((cmp_res & 2) || bitflips); 519 + seb->copy_flag = vid_hdr->copy_flag; 517 520 seb->sqnum = sqnum; 518 521 519 522 if (sv->highest_lnum == lnum) ··· 548 549 seb->ec = ec; 549 550 seb->pnum = pnum; 550 551 seb->lnum = lnum; 551 - seb->sqnum = sqnum; 552 552 seb->scrub = bitflips; 553 + seb->copy_flag = vid_hdr->copy_flag; 554 + seb->sqnum = sqnum; 553 555 554 556 if (sv->highest_lnum <= lnum) { 555 557 sv->highest_lnum = lnum;
+3 -1
drivers/mtd/ubi/scan.h
··· 30 30 * @pnum: physical eraseblock number 31 31 * @lnum: logical eraseblock number 32 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 34 * @sqnum: sequence number 34 35 * @u: unions RB-tree or @list links 35 36 * @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects ··· 43 42 int ec; 44 43 int pnum; 45 44 int lnum; 46 - int scrub; 45 + unsigned int scrub:1; 46 + unsigned int copy_flag:1; 47 47 unsigned long long sqnum; 48 48 union { 49 49 struct rb_node rb;