[PATCH 04/22] UBI: Fastmap: Store scrub list in fastmap

From: Richard Weinberger
Date: Mon Jun 18 2012 - 12:23:51 EST


If scrub work is pending while writing the fastmap we have to
store it into the fastmap otherwise we'd leak PEBs.

Signed-off-by: Richard Weinberger <richard@xxxxxx>
---
drivers/mtd/ubi/fastmap.c | 26 ++++++++++++++++++++++++++
drivers/mtd/ubi/ubi-media.h | 3 ++-
2 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 9ed4723..bc29835 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -560,6 +560,17 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
be32_to_cpu(fmec->ec), 0);
}

+ /* read EC values from scrub list */
+ for (i = 0; i < be32_to_cpu(fmhdr->scrub_peb_count); i++) {
+ fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmec);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+
+ add_aeb(ai, &used, be32_to_cpu(fmec->pnum),
+ be32_to_cpu(fmec->ec), 1);
+ }
+
ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count);
ai->bad_peb_count = be32_to_cpu(fmhdr->bad_peb_count);

@@ -1016,6 +1027,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
struct ubi_volume *vol;
struct ubi_vid_hdr *avhdr, *dvhdr;
int ret, i, j, free_peb_count, used_peb_count, vol_count;
+ int scrub_peb_count;

fm_raw = vzalloc(new_fm->size);
if (!fm_raw) {
@@ -1055,6 +1067,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
fmh->magic = cpu_to_be32(UBI_FM_HDR_MAGIC);
free_peb_count = 0;
used_peb_count = 0;
+ scrub_peb_count = 0;
vol_count = 0;

fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
@@ -1099,6 +1112,19 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
}
fmh->used_peb_count = cpu_to_be32(used_peb_count);

+ for (node = rb_first(&ubi->scrub); node; node = rb_next(node)) {
+ wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
+ fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+ fec->pnum = cpu_to_be32(wl_e->pnum);
+ fec->ec = cpu_to_be32(wl_e->ec);
+
+ scrub_peb_count++;
+ fm_pos += sizeof(*fec);
+ ubi_assert(fm_pos <= new_fm->size);
+ }
+ fmh->scrub_peb_count = cpu_to_be32(scrub_peb_count);
+
for (i = 0; i < UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT; i++) {
vol = ubi->volumes[i];

diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h
index a36748c..bea8c95 100644
--- a/drivers/mtd/ubi/ubi-media.h
+++ b/drivers/mtd/ubi/ubi-media.h
@@ -440,9 +440,10 @@ struct ubi_fm_hdr {
__be32 magic;
__be32 free_peb_count;
__be32 used_peb_count;
+ __be32 scrub_peb_count;
__be32 vol_count;
__be32 bad_peb_count;
- __u8 padding[12];
+ __u8 padding[8];
} __packed;

/* struct ubi_fm_hdr is followed by struct ubi_fm_scan_pool */
--
1.7.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/