linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* UBI Fastmap updates
@ 2012-06-18 16:18 Richard Weinberger
  2012-06-18 16:18 ` [PATCH 01/22] UBI: Fastmap: Add EBA selfcheck Richard Weinberger
                   ` (20 more replies)
  0 siblings, 21 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy

This is the next round of UBI fastmap updates.
It contains mostly fixes.

The highlights are:
- ubi_wl_flush() is no longer needed before creating the fastmap
- It passes all tests (ubi-tests, my own tests) with bit flit emulation and UBI self checks enabled.
- If UBI self checks are enabled UBI is able to proof the correctness of an EBA created from by fastmap.
- Endianness has been successfully tested (using qemu-x86 and qemu-ppc)

If you want to test fastmap you can use my git repo:
git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubi2.git ubi2/v11

Please don't get confused with the release number, v11 is the internal release.

Fastmap has been tested on PPC, ARM, x86 on both real hardware and emulation using qemu.
To catch race conditions lots of tests have been done on a very fast x86 multi core machine.
So far nothing exploded. :-)
I'll send my fastmap torture script plus a paranoia patch in a separate mail.

Enjoy!
//richard

[PATCH 01/22] UBI: Fastmap: Add EBA selfcheck
[PATCH 02/22] UBI: Fastmap: Fix NULL pointer bug
[PATCH 03/22] UBI: Fastmap: Keep fastmap after attaching
[PATCH 04/22] UBI: Fastmap: Store scrub list in fastmap
[PATCH 05/22] UBI: Fastmap: Rework ubi_wl_put_fm_peb()
[PATCH 06/22] UBI: Fastmap: Make EBA table self check depend on
[PATCH 07/22] UBI: Fastmap: Fix build (a left over from the ai->fm
[PATCH 08/22] Revert "UBI: Fastmap: Check for duplicated PEBs in
[PATCH 09/22] UBI: Fastmap: Fix PEB count assert
[PATCH 10/22] UBI: Fastmap: Remove more useless new lines
[PATCH 11/22] UBI: Fastmap: Get rid of ubi_wl_flush() in
[PATCH 12/22] UBI: Fastmap: Locking fixes
[PATCH 13/22] UBI: Fastmap: Fix EC values
[PATCH 14/22] UBI: Fastmap: Fix copy&paste error
[PATCH 15/22] UBI: Fastmap: Kill old fastmap in case of a failure
[PATCH 16/22] UBI: Fastmap: Fix loglevel
[PATCH 17/22] UBI: Fastmap: Add comments to new functions
[PATCH 18/22] UBI: Fastmap: Rename "early PEB" to "anchor PEB".
[PATCH 19/22] UBI: Fastmap: Init fm_sem
[PATCH 20/22] UBI: Fastmap: Use good_peb_count in assert
[PATCH 21/22] UBI: Fastmap: Fix and explain duplicated PEBs
[PATCH 22/22] UBI: Fastmap: Replace crc32_be() with crc32()

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 01/22] UBI: Fastmap: Add EBA selfcheck
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 02/22] UBI: Fastmap: Fix NULL pointer bug Richard Weinberger
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Using this self-check it's possible to proof Fastmap's
correctness.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/attach.c |   16 +++++++++
 drivers/mtd/ubi/eba.c    |   84 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/ubi/ubi.h    |    2 +
 3 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index 4c6b97b..1573d94 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -1262,6 +1262,22 @@ int ubi_attach(struct ubi_device *ubi)
 	if (err)
 		goto out_wl;
 
+	if (ai->fm) {
+		struct ubi_attach_info *scan_ai;
+		scan_ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
+		if (!scan_ai)
+			goto out_ai;
+
+		err = scan_all(ubi, scan_ai);
+		if (err) {
+			kfree(scan_ai);
+			goto out_ai;
+		}
+
+		self_check_eba(ubi, ai, scan_ai);
+		ubi_destroy_ai(ubi, scan_ai);
+	}
+
 	ubi_destroy_ai(ubi, ai);
 
 	/* TODO: UBI auto formats the flash if it is empty (see ubi->is_empty).
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 654f121..d112b10 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -1204,6 +1204,90 @@ static void print_rsvd_warning(struct ubi_device *ubi,
 			ubi->corr_peb_count);
 }
 
+int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
+		   struct ubi_attach_info *ai_scan)
+{
+	int i, j, num_volumes, ret = 0;
+	int **scan_eba, **fm_eba;
+	struct ubi_ainf_volume *av;
+	struct ubi_volume *vol;
+	struct ubi_ainf_peb *aeb;
+	struct rb_node *rb;
+
+	num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT;
+
+	scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL);
+	if (!scan_eba)
+		return -ENOMEM;
+
+	fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL);
+	if (!fm_eba) {
+		kfree(scan_eba);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < num_volumes; i++) {
+		vol = ubi->volumes[i];
+		if (!vol)
+			continue;
+
+		scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba),
+				      GFP_KERNEL);
+		if (!scan_eba[i]) {
+			ret = -ENOMEM;
+			goto out_free;
+		}
+
+		fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba),
+				    GFP_KERNEL);
+		if (!scan_eba[i]) {
+			ret = -ENOMEM;
+			goto out_free;
+		}
+
+		for (j = 0; j < vol->reserved_pebs; j++)
+			scan_eba[i][j] = fm_eba[i][j] = UBI_LEB_UNMAPPED;
+
+		av = ubi_find_av(ai_scan, idx2vol_id(ubi, i));
+		if (!av)
+			continue;
+
+		ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
+			scan_eba[i][aeb->lnum] = aeb->pnum;
+
+		av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i));
+		if (!av)
+			continue;
+
+		ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
+			fm_eba[i][aeb->lnum] = aeb->pnum;
+
+		for (j = 0; j < vol->reserved_pebs; j++) {
+			if (scan_eba[i][j] != fm_eba[i][j]) {
+				if (scan_eba[i][j] == UBI_LEB_UNMAPPED)
+					continue;
+
+				ubi_err("LEB:%i is mapped to PEB:%i instead of PEB:%i!", i, fm_eba[i][j], scan_eba[i][j]);
+				BUG();
+			}
+		}
+	}
+
+out_free:
+	for (i = 0; i < num_volumes; i++) {
+		if (!ubi->volumes[i])
+			continue;
+
+		kfree(scan_eba[i]);
+		kfree(fm_eba[i]);
+	}
+
+	kfree(scan_eba);
+	kfree(fm_eba);
+
+	return ret;
+}
+
 /**
  * ubi_eba_init - initialize the EBA sub-system using attaching information.
  * @ubi: UBI device description object
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index ba6bfd1..f4bd3c9 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -723,6 +723,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
 		     struct ubi_vid_hdr *vid_hdr);
 int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
 unsigned long long ubi_next_sqnum(struct ubi_device *ubi);
+int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
+		   struct ubi_attach_info *ai_scan);
 
 /* wl.c */
 int ubi_wl_get_peb(struct ubi_device *ubi);
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 02/22] UBI: Fastmap: Fix NULL pointer bug
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
  2012-06-18 16:18 ` [PATCH 01/22] UBI: Fastmap: Add EBA selfcheck Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 03/22] UBI: Fastmap: Keep fastmap after attaching Richard Weinberger
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 8b033e5..5bbf1e3 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -1290,11 +1290,14 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 				goto err;
 			}
 
-			tmp_e->pnum = old_fm->e[0]->pnum;
-			tmp_e->ec = old_fm->e[0]->ec;
+			new_fm->e[0]->pnum = old_fm->e[0]->pnum;
+			new_fm->e[0]->ec = old_fm->e[0]->ec;
 		} else {
 			/* we've got a new early PEB, return the old one */
 			ubi_wl_put_fm_peb(ubi, old_fm->e[0], 0);
+
+			new_fm->e[0]->pnum = tmp_e->pnum;
+			new_fm->e[0]->ec = tmp_e->ec;
 		}
 
 		/* return all other fastmap block to the wl system */
@@ -1307,10 +1310,10 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 
 			goto err;
 		}
-	}
 
-	new_fm->e[0]->pnum = tmp_e->pnum;
-	new_fm->e[0]->ec = tmp_e->ec;
+		new_fm->e[0]->pnum = tmp_e->pnum;
+		new_fm->e[0]->ec = tmp_e->ec;
+	}
 
 	if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) {
 		ubi_err("fastmap too large");
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 03/22] UBI: Fastmap: Keep fastmap after attaching
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
  2012-06-18 16:18 ` [PATCH 01/22] UBI: Fastmap: Add EBA selfcheck Richard Weinberger
  2012-06-18 16:18 ` [PATCH 02/22] UBI: Fastmap: Fix NULL pointer bug Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 04/22] UBI: Fastmap: Store scrub list in fastmap Richard Weinberger
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/attach.c  |   14 +---------
 drivers/mtd/ubi/fastmap.c |   67 ++++++++++++++++++++++-----------------------
 drivers/mtd/ubi/ubi.h     |    2 -
 3 files changed, 34 insertions(+), 49 deletions(-)

diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index 1573d94..9ae66e4 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -1262,7 +1262,7 @@ int ubi_attach(struct ubi_device *ubi)
 	if (err)
 		goto out_wl;
 
-	if (ai->fm) {
+	if (ubi->fm) {
 		struct ubi_attach_info *scan_ai;
 		scan_ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
 		if (!scan_ai)
@@ -1385,18 +1385,6 @@ void ubi_destroy_ai(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	if (ai->aeb_slab_cache)
 		kmem_cache_destroy(ai->aeb_slab_cache);
 
-	/* Return all PEBs back to the WL sub-system */
-	if (ai->fm) {
-		int i, torture;
-
-		for (i = 0; i < ai->fm->used_blocks; i++) {
-			torture = ai->fm->to_be_tortured[i];
-			ubi_wl_put_fm_peb(ubi, ai->fm->e[i], torture);
-		}
-
-		kfree(ai->fm);
-	}
-
 	kfree(ai);
 }
 
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 5bbf1e3..9ed4723 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -774,6 +774,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	struct ubi_fm_sb *fmsb;
 	struct ubi_vid_hdr *vh;
 	struct ubi_ec_hdr *ech;
+	struct ubi_fastmap_layout *fm;
 	int i, used_blocks, pnum, sb_pnum = 0, ret = 0;
 	void *fm_raw = NULL;
 	size_t fm_size;
@@ -792,8 +793,8 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 		goto out;
 	}
 
-	ai->fm = kzalloc(sizeof(*ai->fm), GFP_KERNEL);
-	if (!ai->fm) {
+	fm = kzalloc(sizeof(*fm), GFP_KERNEL);
+	if (!fm) {
 		ret = -ENOMEM;
 		kfree(fmsb);
 		goto free_raw;
@@ -802,10 +803,10 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	ret = ubi_io_read(ubi, fmsb, sb_pnum, ubi->leb_start, sizeof(*fmsb));
 	if (ret && ret != UBI_IO_BITFLIPS) {
 		kfree(fmsb);
-		kfree(ai->fm);
+		kfree(fm);
 		goto out;
 	} else if (ret == UBI_IO_BITFLIPS)
-		ai->fm->to_be_tortured[0] = 1;
+		fm->to_be_tortured[0] = 1;
 
 	if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) {
 		/* TODO: not urgent, but examine all the error messages and
@@ -818,7 +819,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 		ubi_err("super block magic does not match");
 		ret = UBI_BAD_FASTMAP;
 		kfree(fmsb);
-		kfree(ai->fm);
+		kfree(fm);
 		goto out;
 	}
 
@@ -826,7 +827,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 		ubi_err("unknown fastmap format version!");
 		ret = UBI_BAD_FASTMAP;
 		kfree(fmsb);
-		kfree(ai->fm);
+		kfree(fm);
 		goto out;
 	}
 
@@ -835,7 +836,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 		ubi_err("number of fastmap blocks is invalid");
 		ret = UBI_BAD_FASTMAP;
 		kfree(fmsb);
-		kfree(ai->fm);
+		kfree(fm);
 		goto out;
 	}
 
@@ -845,7 +846,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	if (!fm_raw) {
 		ret = -ENOMEM;
 		kfree(fmsb);
-		kfree(ai->fm);
+		kfree(fm);
 		goto out;
 	}
 
@@ -853,7 +854,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	if (!ech) {
 		ret = -ENOMEM;
 		kfree(fmsb);
-		kfree(ai->fm);
+		kfree(fm);
 		goto free_raw;
 	}
 
@@ -861,7 +862,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	if (!vh) {
 		ret = -ENOMEM;
 		kfree(fmsb);
-		kfree(ai->fm);
+		kfree(fm);
 		kfree(ech);
 		goto free_raw;
 	}
@@ -871,7 +872,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 
 		if (ubi_io_is_bad(ubi, pnum)) {
 			ret = UBI_BAD_FASTMAP;
-			kfree(ai->fm);
+			kfree(fm);
 			kfree(fmsb);
 			goto free_hdr;
 		}
@@ -883,10 +884,10 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 			if (ret > 0)
 				ret = UBI_BAD_FASTMAP;
 			kfree(fmsb);
-			kfree(ai->fm);
+			kfree(fm);
 			goto free_hdr;
 		} else if (ret == UBI_IO_BITFLIPS)
-			ai->fm->to_be_tortured[i] = 1;
+			fm->to_be_tortured[i] = 1;
 
 		if (!ubi->image_seq)
 			ubi->image_seq = be32_to_cpu(ech->image_seq);
@@ -894,7 +895,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 		if (be32_to_cpu(ech->image_seq) != ubi->image_seq) {
 			ret = UBI_BAD_FASTMAP;
 			kfree(fmsb);
-			kfree(ai->fm);
+			kfree(fm);
 			goto free_hdr;
 		}
 
@@ -903,7 +904,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 			ubi_err("unable to read fastmap block# %i (PEB: %i)",
 				i, pnum);
 			kfree(fmsb);
-			kfree(ai->fm);
+			kfree(fm);
 			goto free_hdr;
 		}
 
@@ -911,7 +912,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 			if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) {
 				ret = UBI_BAD_FASTMAP;
 				kfree(fmsb);
-				kfree(ai->fm);
+				kfree(fm);
 				goto free_hdr;
 			}
 		} else {
@@ -931,7 +932,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 			ubi_err("unable to read fastmap block# %i (PEB: %i)",
 				i, pnum);
 			kfree(fmsb);
-			kfree(ai->fm);
+			kfree(fm);
 			goto free_hdr;
 		}
 	}
@@ -945,7 +946,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	if (crc != tmp_crc) {
 		ubi_err("fastmap data CRC is invalid");
 		ret = UBI_BAD_FASTMAP;
-		kfree(ai->fm);
+		kfree(fm);
 		goto free_hdr;
 	}
 
@@ -955,12 +956,12 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	if (ret) {
 		if (ret > 0)
 			ret = UBI_BAD_FASTMAP;
-		kfree(ai->fm);
+		kfree(fm);
 		goto free_hdr;
 	}
 
-	ai->fm->size = fm_size;
-	ai->fm->used_blocks = used_blocks;
+	fm->size = fm_size;
+	fm->used_blocks = used_blocks;
 
 	for (i = 0; i < used_blocks; i++) {
 		struct ubi_wl_entry *e;
@@ -968,19 +969,21 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai)
 		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
 		if (!e) {
 			while (i--)
-				kfree(ai->fm->e[i]);
+				kfree(fm->e[i]);
 
-			kfree(ai->fm);
-			ai->fm = NULL;
+			kfree(fm);
+			fm = NULL;
 			ret = -ENOMEM;
 			goto free_hdr;
 		}
 
 		e->pnum = be32_to_cpu(fmsb->block_loc[i]);
 		e->ec = be32_to_cpu(fmsb->block_ec[i]);
-		ai->fm->e[i] = e;
+		fm->e[i] = e;
 	}
 
+	ubi->fm = fm;
+
 free_hdr:
 	ubi_free_vid_hdr(ubi, vh);
 	kfree(ech);
@@ -1294,7 +1297,8 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 			new_fm->e[0]->ec = old_fm->e[0]->ec;
 		} else {
 			/* we've got a new early PEB, return the old one */
-			ubi_wl_put_fm_peb(ubi, old_fm->e[0], 0);
+			ubi_wl_put_fm_peb(ubi, old_fm->e[0],
+					  old_fm->to_be_tortured[0]);
 
 			new_fm->e[0]->pnum = tmp_e->pnum;
 			new_fm->e[0]->ec = tmp_e->ec;
@@ -1302,7 +1306,8 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 
 		/* return all other fastmap block to the wl system */
 		for (i = 1; i < old_fm->used_blocks; i++)
-			ubi_wl_put_fm_peb(ubi, old_fm->e[i], 0);
+			ubi_wl_put_fm_peb(ubi, old_fm->e[i],
+					  old_fm->to_be_tortured[i]);
 	} else {
 		if (!tmp_e) {
 			ubi_err("could not find an early PEB");
@@ -1346,13 +1351,7 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 		new_fm->e[i]->ec = tmp_e->ec;
 	}
 
-	if (old_fm) {
-		for (i = 0; i < old_fm->used_blocks; i++)
-			kfree(old_fm->e[i]);
-
-		kfree(old_fm);
-	}
-
+	kfree(old_fm);
 	/* Ensure that the PEBs of the old fastmap got erased and added to the
 	 * free list before we write the fastmap. Otherwise fastmp does not
 	 * see these PEBs and we leak them.
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index f4bd3c9..dcbc420 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -625,7 +625,6 @@ struct ubi_ainf_volume {
  * @ec_sum: a temporary variable used when calculating @mean_ec
  * @ec_count: a temporary variable used when calculating @mean_ec
  * @aeb_slab_cache: slab cache for &struct ubi_ainf_peb objects
- * @fm: the fastmap used for attaching
  *
  * This data structure contains the result of attaching an MTD device and may
  * be used by other UBI sub-systems to build final UBI data structures, further
@@ -652,7 +651,6 @@ struct ubi_attach_info {
 	uint64_t ec_sum;
 	int ec_count;
 	struct kmem_cache *aeb_slab_cache;
-	struct ubi_fastmap_layout *fm;
 };
 
 #include "debug.h"
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 04/22] UBI: Fastmap: Store scrub list in fastmap
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (2 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 03/22] UBI: Fastmap: Keep fastmap after attaching Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 05/22] UBI: Fastmap: Rework ubi_wl_put_fm_peb() Richard Weinberger
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

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@nod.at>
---
 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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 05/22] UBI: Fastmap: Rework ubi_wl_put_fm_peb()
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (3 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 04/22] UBI: Fastmap: Store scrub list in fastmap Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 06/22] UBI: Fastmap: Make EBA table self check depend on chk_gen Richard Weinberger
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/wl.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index a64cd83..369e07f 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -827,13 +827,14 @@ static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
  *
  * see: ubi_wl_put_peb()
  */
-int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *used_e,
-    int torture)
+int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *fm_e,
+		      int torture)
 {
 	struct ubi_wl_entry *e;
-	int pnum = used_e->pnum;
+	int pnum = fm_e->pnum;
 
 	dbg_wl("PEB %d", pnum);
+
 	ubi_assert(pnum >= 0);
 	ubi_assert(pnum < ubi->peb_count);
 
@@ -845,11 +846,11 @@ int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *used_e,
 	 * has never seen any PEB used by the original fastmap.
 	 */
 	if (!e) {
-		e = used_e;
-
+		e = fm_e;
 		ubi_assert(e->ec);
 		ubi->lookuptbl[pnum] = e;
-	}
+	} else
+		kfree(fm_e);
 
 	spin_unlock(&ubi->wl_lock);
 
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 06/22] UBI: Fastmap: Make EBA table self check depend on chk_gen
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (4 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 05/22] UBI: Fastmap: Rework ubi_wl_put_fm_peb() Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 07/22] UBI: Fastmap: Fix build (a left over from the ai->fm removal) Richard Weinberger
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/attach.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index 9ae66e4..5cba456 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -1262,7 +1262,7 @@ int ubi_attach(struct ubi_device *ubi)
 	if (err)
 		goto out_wl;
 
-	if (ubi->fm) {
+	if (ubi->fm && ubi->dbg->chk_gen) {
 		struct ubi_attach_info *scan_ai;
 		scan_ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
 		if (!scan_ai)
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 07/22] UBI: Fastmap: Fix build (a left over from the ai->fm removal)
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (5 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 06/22] UBI: Fastmap: Make EBA table self check depend on chk_gen Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 08/22] Revert "UBI: Fastmap: Check for duplicated PEBs in add_aeb()" Richard Weinberger
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/wl.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 369e07f..4d9384b 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1727,8 +1727,8 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
 
 	dbg_wl("found %i PEBs", found_pebs);
 
-	if (ai->fm)
-		ubi_assert(ubi->peb_count == found_pebs + ai->fm->used_blocks);
+	if (ubi->fm)
+		ubi_assert(ubi->peb_count == found_pebs + ubi->fm->used_blocks);
 	else
 		ubi_assert(ubi->peb_count == found_pebs);
 
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 08/22] Revert "UBI: Fastmap: Check for duplicated PEBs in add_aeb()"
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (6 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 07/22] UBI: Fastmap: Fix build (a left over from the ai->fm removal) Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 09/22] UBI: Fastmap: Fix PEB count assert Richard Weinberger
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

This reverts commit 95bbb0d1b2ea86103edfdd4b07ddfb058b1e0eff.

That check is no longer needed.
It must not happen that fastmap creates duplicates.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index bc29835..caefcb3 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -54,10 +54,6 @@ static int add_aeb(struct ubi_attach_info *ai, struct list_head *list,
 {
 	struct ubi_ainf_peb *aeb;
 
-	list_for_each_entry(aeb, list, u.list)
-		if (aeb->pnum == pnum)
-			return 0;
-
 	aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
 	if (!aeb)
 		return -ENOMEM;
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 09/22] UBI: Fastmap: Fix PEB count assert
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (7 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 08/22] Revert "UBI: Fastmap: Check for duplicated PEBs in add_aeb()" Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 10/22] UBI: Fastmap: Remove more useless new lines Richard Weinberger
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Use also the bad PEB count value, otherwise the assert will fail
if the FLASH has bad blocks.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/wl.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 4d9384b..58d74e4 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1728,9 +1728,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	dbg_wl("found %i PEBs", found_pebs);
 
 	if (ubi->fm)
-		ubi_assert(ubi->peb_count == found_pebs + ubi->fm->used_blocks);
+		ubi_assert(ubi->peb_count - ubi->bad_peb_count == \
+			   found_pebs + ubi->fm->used_blocks);
 	else
-		ubi_assert(ubi->peb_count == found_pebs);
+		ubi_assert(ubi->peb_count - ubi->bad_peb_count == found_pebs);
 
 	if (ubi->avail_pebs < WL_RESERVED_PEBS) {
 		ubi_err("no enough physical eraseblocks (%d, need %d)",
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 10/22] UBI: Fastmap: Remove more useless new lines
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (8 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 09/22] UBI: Fastmap: Fix PEB count assert Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 11/22] UBI: Fastmap: Get rid of ubi_wl_flush() in ubi_update_fastmap() Richard Weinberger
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index caefcb3..8aa43e8 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -1272,7 +1272,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 			ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
 			if (!ec_hdr) {
 				ret = -ENOMEM;
-
 				goto err;
 			}
 
@@ -1282,7 +1281,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 			if (ret && ret != UBI_IO_BITFLIPS) {
 				ubi_err("unable to read EC header");
 				kfree(ec_hdr);
-
 				goto err;
 			}
 
@@ -1291,7 +1289,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 			if (ret < 0) {
 				ubi_err("unable to erase old SB");
 				kfree(ec_hdr);
-
 				goto err;
 			}
 
@@ -1301,7 +1298,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 				ubi_err("erase counter overflow!");
 				kfree(ec_hdr);
 				ret = -EINVAL;
-
 				goto err;
 			}
 
@@ -1311,7 +1307,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 			kfree(ec_hdr);
 			if (ret) {
 				ubi_err("unable to write new EC header");
-
 				goto err;
 			}
 
@@ -1334,7 +1329,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 		if (!tmp_e) {
 			ubi_err("could not find an early PEB");
 			ret = -ENOSPC;
-
 			goto err;
 		}
 
@@ -1345,7 +1339,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 	if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) {
 		ubi_err("fastmap too large");
 		ret = -ENOSPC;
-
 		goto err;
 	}
 
@@ -1365,7 +1358,6 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 				kfree(new_fm->e[i]);
 			}
 			ret = -ENOSPC;
-
 			goto err;
 		}
 
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 11/22] UBI: Fastmap: Get rid of ubi_wl_flush() in ubi_update_fastmap()
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (9 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 10/22] UBI: Fastmap: Remove more useless new lines Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 12/22] UBI: Fastmap: Locking fixes Richard Weinberger
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c   |   76 ++++++++++++++++++++++++++++++++++--------
 drivers/mtd/ubi/ubi-media.h |    8 +++--
 drivers/mtd/ubi/ubi.h       |   21 ++++++++++++
 drivers/mtd/ubi/wl.c        |   32 ++++++------------
 4 files changed, 98 insertions(+), 39 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 8aa43e8..ff09fd4 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -348,7 +348,7 @@ static void unmap_peb(struct ubi_attach_info *ai, int pnum)
  */
 static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
 		     int *pebs, int pool_size, unsigned long long *max_sqnum,
-		     struct list_head *eba_orphans)
+		     struct list_head *eba_orphans, struct list_head *free)
 {
 	struct ubi_vid_hdr *vh;
 	struct ubi_ec_hdr *ech;
@@ -402,9 +402,9 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
 			unmap_peb(ai, pnum);
 			dbg_bld("Adding PEB to free: %i", pnum);
 			if (err == UBI_IO_FF_BITFLIPS)
-				add_aeb(ai, &ai->free, pnum, ec, 1);
+				add_aeb(ai, free, pnum, ec, 1);
 			else
-				add_aeb(ai, &ai->free, pnum, ec, 0);
+				add_aeb(ai, free, pnum, ec, 0);
 			continue;
 		} else if (err == 0 || err == UBI_IO_BITFLIPS) {
 			dbg_bld("Found non empty PEB:%i in pool", pnum);
@@ -471,7 +471,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
 			      struct ubi_attach_info *ai,
 			      void *fm_raw, size_t fm_size)
 {
-	struct list_head used, eba_orphans;
+	struct list_head used, eba_orphans, free;
 	struct ubi_ainf_volume *av;
 	struct ubi_ainf_peb *aeb, *tmp_aeb, *_tmp_aeb;
 	struct ubi_ec_hdr *ech;
@@ -486,6 +486,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
 	unsigned long long max_sqnum = 0;
 
 	INIT_LIST_HEAD(&used);
+	INIT_LIST_HEAD(&free);
 	INIT_LIST_HEAD(&eba_orphans);
 	INIT_LIST_HEAD(&ai->corr);
 	INIT_LIST_HEAD(&ai->free);
@@ -567,6 +568,17 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
 			be32_to_cpu(fmec->ec), 1);
 	}
 
+	/* read EC values from erase list */
+	for (i = 0; i < be32_to_cpu(fmhdr->erase_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, &ai->erase, 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);
 
@@ -683,12 +695,12 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
 	}
 
 	ret = scan_pool(ubi, ai, fmpl1->pebs, be32_to_cpu(fmpl1->size),
-			&max_sqnum, &eba_orphans);
+			&max_sqnum, &eba_orphans, &free);
 	if (ret)
 		goto fail;
 
 	ret = scan_pool(ubi, ai, fmpl2->pebs, be32_to_cpu(fmpl2->size),
-			&max_sqnum, &eba_orphans);
+			&max_sqnum, &eba_orphans, &free);
 	if (ret)
 		goto fail;
 
@@ -697,11 +709,30 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
 
 	list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) {
 		list_del(&tmp_aeb->u.list);
-		dbg_bld("moving PEB from used to erase: %i", tmp_aeb->pnum);
+		ubi_msg("moving PEB from used to erase: %i", tmp_aeb->pnum);
 		add_aeb(ai, &ai->erase, tmp_aeb->pnum, tmp_aeb->ec, 0);
 		kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
 	}
 
+	if (list_empty(&free))
+		goto out;
+
+	list_for_each_entry(aeb, &ai->free, u.list) {
+		list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
+			if (aeb->pnum == tmp_aeb->pnum) {
+				aeb->scrub = tmp_aeb->scrub;
+				list_del(&tmp_aeb->u.list);
+				kfree(tmp_aeb);
+				continue;
+			}
+		}
+	}
+
+	list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
+		list_del(&tmp_aeb->u.list);
+		list_add_tail(&tmp_aeb->u.list, &ai->free);
+	}
+out:
 	return 0;
 
 fail_bad:
@@ -1022,8 +1053,9 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
 	struct ubi_wl_entry *wl_e;
 	struct ubi_volume *vol;
 	struct ubi_vid_hdr *avhdr, *dvhdr;
+	struct ubi_work *ubi_wrk;
 	int ret, i, j, free_peb_count, used_peb_count, vol_count;
-	int scrub_peb_count;
+	int scrub_peb_count, erase_peb_count;
 
 	fm_raw = vzalloc(new_fm->size);
 	if (!fm_raw) {
@@ -1064,6 +1096,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
 	free_peb_count = 0;
 	used_peb_count = 0;
 	scrub_peb_count = 0;
+	erase_peb_count = 0;
 	vol_count = 0;
 
 	fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
@@ -1121,6 +1154,24 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
 	}
 	fmh->scrub_peb_count = cpu_to_be32(scrub_peb_count);
 
+
+	list_for_each_entry(ubi_wrk, &ubi->works, list) {
+		if (ubi_is_erase_work(ubi_wrk)) {
+			wl_e = ubi_wrk->e;
+			ubi_assert(wl_e);
+
+			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);
+
+			erase_peb_count++;
+			fm_pos += sizeof(*fec);
+			ubi_assert(fm_pos <= new_fm->size);
+		}
+	}
+	fmh->erase_peb_count = cpu_to_be32(erase_peb_count);
+
 	for (i = 0; i < UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT; i++) {
 		vol = ubi->volumes[i];
 
@@ -1366,15 +1417,10 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 	}
 
 	kfree(old_fm);
-	/* Ensure that the PEBs of the old fastmap got erased and added to the
-	 * free list before we write the fastmap. Otherwise fastmp does not
-	 * see these PEBs and we leak them.
-	 * We need the flush also to ensure that no to be scrubbed PEBs are in
-	 * flight.
-	 */
-	ubi_wl_flush(ubi);
 
+	down_write(&ubi->work_sem);
 	ret = ubi_write_fastmap(ubi, new_fm);
+	up_write(&ubi->work_sem);
 out_unlock:
 	mutex_unlock(&ubi->fm_mutex);
 
diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h
index bea8c95..a0648c1 100644
--- a/drivers/mtd/ubi/ubi-media.h
+++ b/drivers/mtd/ubi/ubi-media.h
@@ -433,17 +433,19 @@ struct ubi_fm_sb {
  * @magic: fastmap header magic number (%UBI_FM_HDR_MAGIC)
  * @free_peb_count: number of free PEBs known by this fastmap
  * @free_peb_count: number of used PEBs known by this fastmap
- * @vol_count: number of UBI volumes known by this fastmap
  * @bad_peb_count: number of bad PEBs known by this fastmap
+ * @erase_peb_count: number of bad PEBs which have to be erased
+ * @vol_count: number of UBI volumes known by this fastmap
  */
 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[8];
+	__be32 erase_peb_count;
+	__be32 vol_count;
+	__u8 padding[4];
 } __packed;
 
 /* struct ubi_fm_hdr is followed by struct ubi_fm_scan_pool */
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index dcbc420..8588f9c 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -653,6 +653,26 @@ struct ubi_attach_info {
 	struct kmem_cache *aeb_slab_cache;
 };
 
+/**
+ * struct ubi_work - UBI work description data structure.
+ * @list: a link in the list of pending works
+ * @func: worker function
+ * @e: physical eraseblock to erase
+ * @torture: if the physical eraseblock has to be tortured
+ *
+ * The @func pointer points to the worker function. If the @cancel argument is
+ * not zero, the worker has to free the resources and exit immediately. The
+ * worker has to return zero in case of success and a negative error code in
+ * case of failure.
+ */
+struct ubi_work {
+	struct list_head list;
+	int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel);
+	/* The below fields are only relevant to erasure works */
+	struct ubi_wl_entry *e;
+	int torture;
+};
+
 #include "debug.h"
 
 extern struct kmem_cache *ubi_wl_entry_slab;
@@ -734,6 +754,7 @@ void ubi_wl_close(struct ubi_device *ubi);
 int ubi_thread(void *u);
 struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int max_pnum);
 int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *used_e, int torture);
+int ubi_is_erase_work(struct ubi_work *wrk);
 
 /* io.c */
 int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 58d74e4..25d2e0b 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -135,32 +135,11 @@
  */
 #define WL_MAX_FAILURES 32
 
-/**
- * struct ubi_work - UBI work description data structure.
- * @list: a link in the list of pending works
- * @func: worker function
- * @e: physical eraseblock to erase
- * @torture: if the physical eraseblock has to be tortured
- *
- * The @func pointer points to the worker function. If the @cancel argument is
- * not zero, the worker has to free the resources and exit immediately. The
- * worker has to return zero in case of success and a negative error code in
- * case of failure.
- */
-struct ubi_work {
-	struct list_head list;
-	int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel);
-	/* The below fields are only relevant to erasure works */
-	struct ubi_wl_entry *e;
-	int torture;
-};
-
 static int self_check_ec(struct ubi_device *ubi, int pnum, int ec);
 static int self_check_in_wl_tree(const struct ubi_device *ubi,
 				 struct ubi_wl_entry *e, struct rb_root *root);
 static int self_check_in_pq(const struct ubi_device *ubi,
 			    struct ubi_wl_entry *e);
-
 /**
  *  ubi_ubi_is_fm_block - returns 1 if a PEB is currently used in a fastmap.
  *  @ubi: UBI device description object
@@ -760,6 +739,7 @@ repeat:
  */
 static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk)
 {
+	down_read(&ubi->work_sem);
 	spin_lock(&ubi->wl_lock);
 	list_add_tail(&wrk->list, &ubi->works);
 	ubi_assert(ubi->works_count >= 0);
@@ -767,12 +747,22 @@ static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk)
 	if (ubi->thread_enabled && !ubi_dbg_is_bgt_disabled(ubi))
 		wake_up_process(ubi->bgt_thread);
 	spin_unlock(&ubi->wl_lock);
+	up_read(&ubi->work_sem);
 }
 
 static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
 			int cancel);
 
 /**
+ * ubi_is_erase_work - checks whether a work is erase work
+ * @wrk: The work object to be checked
+ */
+int ubi_is_erase_work(struct ubi_work *wrk)
+{
+	return wrk->func == erase_worker;
+}
+
+/**
  * schedule_erase - schedule an erase work.
  * @ubi: UBI device description object
  * @e: the WL entry of the physical eraseblock to erase
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 12/22] UBI: Fastmap: Locking fixes
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (10 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 11/22] UBI: Fastmap: Get rid of ubi_wl_flush() in ubi_update_fastmap() Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 13/22] UBI: Fastmap: Fix EC values Richard Weinberger
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Add a new rw semaphore to block EBA table changes
while creating the fastmap.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/eba.c     |   12 ++++++++++++
 drivers/mtd/ubi/fastmap.c |    2 ++
 drivers/mtd/ubi/ubi.h     |    2 ++
 3 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index d112b10..2bee8be 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -340,7 +340,9 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
 
 	dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum);
 
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED;
+	up_read(&ubi->fm_sem);
 	err = ubi_wl_put_peb(ubi, pnum, 0);
 
 out_unlock:
@@ -549,7 +551,9 @@ retry:
 	mutex_unlock(&ubi->buf_mutex);
 	ubi_free_vid_hdr(ubi, vid_hdr);
 
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = new_pnum;
+	up_read(&ubi->fm_sem);
 	ubi_wl_put_peb(ubi, pnum, 1);
 
 	ubi_msg("data was successfully recovered");
@@ -667,7 +671,9 @@ retry:
 		}
 	}
 
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = pnum;
+	up_read(&ubi->fm_sem);
 
 	leb_write_unlock(ubi, vol_id, lnum);
 	ubi_free_vid_hdr(ubi, vid_hdr);
@@ -785,7 +791,9 @@ retry:
 	}
 
 	ubi_assert(vol->eba_tbl[lnum] < 0);
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = pnum;
+	up_read(&ubi->fm_sem);
 
 	leb_write_unlock(ubi, vol_id, lnum);
 	ubi_free_vid_hdr(ubi, vid_hdr);
@@ -906,7 +914,9 @@ retry:
 			goto out_leb_unlock;
 	}
 
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = pnum;
+	up_read(&ubi->fm_sem);
 
 out_leb_unlock:
 	leb_write_unlock(ubi, vol_id, lnum);
@@ -1154,7 +1164,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
 	}
 
 	ubi_assert(vol->eba_tbl[lnum] == from);
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = to;
+	up_read(&ubi->fm_sem);
 
 out_unlock_buf:
 	mutex_unlock(&ubi->buf_mutex);
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index ff09fd4..33a14cf 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -1418,9 +1418,11 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 
 	kfree(old_fm);
 
+	down_write(&ubi->fm_sem);
 	down_write(&ubi->work_sem);
 	ret = ubi_write_fastmap(ubi, new_fm);
 	up_write(&ubi->work_sem);
+	up_write(&ubi->fm_sem);
 out_unlock:
 	mutex_unlock(&ubi->fm_mutex);
 
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 8588f9c..8abbcd5 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -384,6 +384,7 @@ struct ubi_wl_entry;
  * @fm_pool: in-memory data structure of the fastmap pool
  * @fm_pool_mutex: serializes ubi_wl_get_peb()
  * @fm_mutex: serializes ubi_update_fastmap()
+ * @fm_sem: allows ubi_update_fastmap() to block EBA table changes
  * @attached_by_scanning: this UBI device was attached by the old scanning
  *			  methold. All fastmap volumes have to be deleted.
  *
@@ -482,6 +483,7 @@ struct ubi_device {
 	struct ubi_fastmap_layout *fm;
 	struct ubi_fm_pool fm_pool;
 	struct ubi_fm_pool fm_wl_pool;
+	struct rw_semaphore fm_sem;
 	struct mutex fm_mutex;
 	struct mutex fm_pool_mutex;
 	int attached_by_scanning;
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 13/22] UBI: Fastmap: Fix EC values
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (11 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 12/22] UBI: Fastmap: Locking fixes Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 14/22] UBI: Fastmap: Fix copy&paste error Richard Weinberger
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Return the correct EC values back to the WL sub-system.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c |    2 ++
 drivers/mtd/ubi/wl.c      |    4 +++-
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 33a14cf..b4f7fce 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -721,6 +721,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
 		list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
 			if (aeb->pnum == tmp_aeb->pnum) {
 				aeb->scrub = tmp_aeb->scrub;
+				aeb->ec = tmp_aeb->ec;
 				list_del(&tmp_aeb->u.list);
 				kfree(tmp_aeb);
 				continue;
@@ -1345,6 +1346,7 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 
 			ec = be64_to_cpu(ec_hdr->ec);
 			ec += ret;
+			old_fm->e[0]->ec = ec;
 			if (ec > UBI_MAX_ERASECOUNTER) {
 				ubi_err("erase counter overflow!");
 				kfree(ec_hdr);
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 25d2e0b..eec3940 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -839,8 +839,10 @@ int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *fm_e,
 		e = fm_e;
 		ubi_assert(e->ec);
 		ubi->lookuptbl[pnum] = e;
-	} else
+	} else {
+		e->ec = fm_e->ec;
 		kfree(fm_e);
+	}
 
 	spin_unlock(&ubi->wl_lock);
 
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 14/22] UBI: Fastmap: Fix copy&paste error
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (12 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 13/22] UBI: Fastmap: Fix EC values Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 15/22] UBI: Fastmap: Kill old fastmap in case of a failure Richard Weinberger
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index b4f7fce..f9e5dbb 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -1403,7 +1403,7 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 		tmp_e = ubi_wl_get_fm_peb(ubi, -1);
 		spin_unlock(&ubi->wl_lock);
 
-		if (!new_fm->e[i]) {
+		if (!tmp_e) {
 			ubi_err("could not get any free erase block");
 
 			while (i--) {
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 15/22] UBI: Fastmap: Kill old fastmap in case of a failure
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (13 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 14/22] UBI: Fastmap: Fix copy&paste error Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:18 ` [PATCH 16/22] UBI: Fastmap: Fix loglevel Richard Weinberger
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

We have to make sure that the old (and from this point on
invalid) fastmap is killed if we fail to create a new one.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c |  177 +++++++++++++++++++++++++--------------------
 1 files changed, 100 insertions(+), 77 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index f9e5dbb..7d36034 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -1266,6 +1266,59 @@ out:
 	return ret;
 }
 
+static int erase_block(struct ubi_device *ubi, int pnum)
+{
+	int ret;
+	struct ubi_ec_hdr *ec_hdr;
+	long long ec;
+
+	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+	if (!ec_hdr)
+		return -ENOMEM;
+
+	ret = ubi_io_read_ec_hdr(ubi, pnum, ec_hdr, 0);
+	if (ret < 0)
+		goto out;
+	else if (ret && ret != UBI_IO_BITFLIPS) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = ubi_io_sync_erase(ubi, pnum, 0);
+	if (ret < 0)
+		goto out;
+
+	ec = be64_to_cpu(ec_hdr->ec);
+	ec += ret;
+	if (ec > UBI_MAX_ERASECOUNTER) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ec_hdr->ec = cpu_to_be64(ec);
+	ret = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr);
+	if (ret < 0)
+		goto out;
+
+	ret = ec;
+out:
+	kfree(ec_hdr);
+	return ret;
+}
+
+static int invalidate_fastmap(struct ubi_device *ubi,
+			      struct ubi_fastmap_layout *fm)
+{
+	int ret, i;
+
+	ret = erase_block(ubi, fm->e[0]->pnum);
+
+	for (i = 0; i < fm->used_blocks; i++)
+		ubi_wl_put_fm_peb(ubi, fm->e[i], fm->to_be_tortured[i]);
+
+	return ret;
+}
+
 /**
  * ubi_update_fastmap - will be called by UBI if a volume changes or
  * a fastmap pool becomes full.
@@ -1307,10 +1360,35 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 	}
 
 	mutex_lock(&ubi->fm_mutex);
-
 	old_fm = ubi->fm;
 	ubi->fm = NULL;
 
+	if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) {
+		ubi_err("fastmap too large");
+		ret = -ENOSPC;
+		goto err;
+	}
+
+	for (i = 1; i < new_fm->used_blocks; i++) {
+		spin_lock(&ubi->wl_lock);
+		tmp_e = ubi_wl_get_fm_peb(ubi, -1);
+		spin_unlock(&ubi->wl_lock);
+
+		if (!tmp_e) {
+			int j;
+			ubi_err("could not get any free erase block");
+
+			for (j = 1; j < i; j++)
+				ubi_wl_put_fm_peb(ubi, new_fm->e[j], 0);
+
+			ret = -ENOSPC;
+			goto err;
+		}
+
+		new_fm->e[i]->pnum = tmp_e->pnum;
+		new_fm->e[i]->ec = tmp_e->ec;
+	}
+
 	spin_lock(&ubi->wl_lock);
 	tmp_e = ubi_wl_get_fm_peb(ubi, UBI_FM_MAX_START);
 	spin_unlock(&ubi->wl_lock);
@@ -1318,53 +1396,14 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 	if (old_fm) {
 		/* no fresh early PEB was found, reuse the old one */
 		if (!tmp_e) {
-			struct ubi_ec_hdr *ec_hdr;
-			long long ec;
-
-			ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
-			if (!ec_hdr) {
-				ret = -ENOMEM;
-				goto err;
-			}
-
-			/* we have to erase the block by hand */
-			ret = ubi_io_read_ec_hdr(ubi, old_fm->e[0]->pnum,
-						 ec_hdr, 0);
-			if (ret && ret != UBI_IO_BITFLIPS) {
-				ubi_err("unable to read EC header");
-				kfree(ec_hdr);
-				goto err;
-			}
-
-			ret = ubi_io_sync_erase(ubi, old_fm->e[0]->pnum,
-						0);
+			ret = erase_block(ubi, old_fm->e[0]->pnum);
 			if (ret < 0) {
-				ubi_err("unable to erase old SB");
-				kfree(ec_hdr);
-				goto err;
-			}
-
-			ec = be64_to_cpu(ec_hdr->ec);
-			ec += ret;
-			old_fm->e[0]->ec = ec;
-			if (ec > UBI_MAX_ERASECOUNTER) {
-				ubi_err("erase counter overflow!");
-				kfree(ec_hdr);
-				ret = -EINVAL;
-				goto err;
-			}
-
-			ec_hdr->ec = cpu_to_be64(ec);
-			ret = ubi_io_write_ec_hdr(ubi, old_fm->e[0]->pnum,
-						  ec_hdr);
-			kfree(ec_hdr);
-			if (ret) {
-				ubi_err("unable to write new EC header");
+				ubi_err("could not erase old early PEB");
 				goto err;
 			}
 
 			new_fm->e[0]->pnum = old_fm->e[0]->pnum;
-			new_fm->e[0]->ec = old_fm->e[0]->ec;
+			new_fm->e[0]->ec = ret;
 		} else {
 			/* we've got a new early PEB, return the old one */
 			ubi_wl_put_fm_peb(ubi, old_fm->e[0],
@@ -1389,48 +1428,32 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 		new_fm->e[0]->ec = tmp_e->ec;
 	}
 
-	if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) {
-		ubi_err("fastmap too large");
-		ret = -ENOSPC;
-		goto err;
-	}
-
-	/* give the wl subsystem a chance to produce some free blocks */
-	cond_resched();
-
-	for (i = 1; i < new_fm->used_blocks; i++) {
-		spin_lock(&ubi->wl_lock);
-		tmp_e = ubi_wl_get_fm_peb(ubi, -1);
-		spin_unlock(&ubi->wl_lock);
-
-		if (!tmp_e) {
-			ubi_err("could not get any free erase block");
-
-			while (i--) {
-				ubi_wl_put_fm_peb(ubi, new_fm->e[i], 0);
-				kfree(new_fm->e[i]);
-			}
-			ret = -ENOSPC;
-			goto err;
-		}
-
-		new_fm->e[i]->pnum = tmp_e->pnum;
-		new_fm->e[i]->ec = tmp_e->ec;
-	}
-
-	kfree(old_fm);
-
-	down_write(&ubi->fm_sem);
 	down_write(&ubi->work_sem);
+	down_write(&ubi->fm_sem);
 	ret = ubi_write_fastmap(ubi, new_fm);
-	up_write(&ubi->work_sem);
 	up_write(&ubi->fm_sem);
+	up_write(&ubi->work_sem);
+
+	if (ret)
+		goto err;
+
 out_unlock:
 	mutex_unlock(&ubi->fm_mutex);
-
+	kfree(old_fm);
 	return ret;
 
 err:
 	kfree(new_fm);
+
+	ubi_warn("Unable to write new fastmap, err=%i", ret);
+
+	ret = 0;
+	if (old_fm) {
+		ret = invalidate_fastmap(ubi, old_fm);
+		if (ret < 0)
+			ubi_err("Unable to invalidiate current fastmap!");
+		else if (ret)
+			ret = 0;
+	}
 	goto out_unlock;
 }
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 16/22] UBI: Fastmap: Fix loglevel
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (14 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 15/22] UBI: Fastmap: Kill old fastmap in case of a failure Richard Weinberger
@ 2012-06-18 16:18 ` Richard Weinberger
  2012-06-18 16:19 ` [PATCH 17/22] UBI: Fastmap: Add comments to new functions Richard Weinberger
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:18 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/wl.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index eec3940..be847d4 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -799,7 +799,7 @@ static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
 {
 	struct ubi_work *wl_wrk;
 
-	ubi_msg("sync erase of PEB %i", e->pnum);
+	dbg_wl("sync erase of PEB %i", e->pnum);
 
 	wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
 	if (!wl_wrk)
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 17/22] UBI: Fastmap: Add comments to new functions
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (15 preceding siblings ...)
  2012-06-18 16:18 ` [PATCH 16/22] UBI: Fastmap: Fix loglevel Richard Weinberger
@ 2012-06-18 16:19 ` Richard Weinberger
  2012-06-18 16:19 ` [PATCH 18/22] UBI: Fastmap: Rename "early PEB" to "anchor PEB" Richard Weinberger
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:19 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 7d36034..65fd7ee 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -1266,6 +1266,11 @@ out:
 	return ret;
 }
 
+/**
+ * erase_block - Manually erase a PEB
+ * @ubi: UBI device object
+ * @pnum: PEB to be erased
+ */
 static int erase_block(struct ubi_device *ubi, int pnum)
 {
 	int ret;
@@ -1306,6 +1311,11 @@ out:
 	return ret;
 }
 
+/**
+ * invalidate_fastmap - destroys a fastmap
+ * @ubi: UBI device object
+ * @fm: the fastmap to be destroyed
+ */
 static int invalidate_fastmap(struct ubi_device *ubi,
 			      struct ubi_fastmap_layout *fm)
 {
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 18/22] UBI: Fastmap: Rename "early PEB" to "anchor PEB".
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (16 preceding siblings ...)
  2012-06-18 16:19 ` [PATCH 17/22] UBI: Fastmap: Add comments to new functions Richard Weinberger
@ 2012-06-18 16:19 ` Richard Weinberger
  2012-06-18 16:19 ` [PATCH 19/22] UBI: Fastmap: Init fm_sem Richard Weinberger
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:19 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

"early PEB" is a very bad name.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c |    8 ++++----
 drivers/mtd/ubi/wl.c      |    8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 65fd7ee..bea9446 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -1404,18 +1404,18 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 	spin_unlock(&ubi->wl_lock);
 
 	if (old_fm) {
-		/* no fresh early PEB was found, reuse the old one */
+		/* no fresh anchor PEB was found, reuse the old one */
 		if (!tmp_e) {
 			ret = erase_block(ubi, old_fm->e[0]->pnum);
 			if (ret < 0) {
-				ubi_err("could not erase old early PEB");
+				ubi_err("could not erase old anchor PEB");
 				goto err;
 			}
 
 			new_fm->e[0]->pnum = old_fm->e[0]->pnum;
 			new_fm->e[0]->ec = ret;
 		} else {
-			/* we've got a new early PEB, return the old one */
+			/* we've got a new anchor PEB, return the old one */
 			ubi_wl_put_fm_peb(ubi, old_fm->e[0],
 					  old_fm->to_be_tortured[0]);
 
@@ -1429,7 +1429,7 @@ int ubi_update_fastmap(struct ubi_device *ubi)
 					  old_fm->to_be_tortured[i]);
 	} else {
 		if (!tmp_e) {
-			ubi_err("could not find an early PEB");
+			ubi_err("could not find an anchor PEB");
 			ret = -ENOSPC;
 			goto err;
 		}
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index be847d4..e5ab683 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -388,12 +388,12 @@ static struct ubi_wl_entry *find_mean_wl_entry(struct rb_root *root)
 }
 
 /**
- * find_early_wl_entry - find wear-leveling entry with the lowest pnum.
+ * find_anchor_wl_entry - find wear-leveling entry to used as anchor PEB.
  * @root: the RB-tree where to look for
  * @max_pnum: highest possible pnum
  */
-static struct ubi_wl_entry *find_early_wl_entry(struct rb_root *root,
-						int max_pnum)
+static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root,
+						 int max_pnum)
 {
 	struct rb_node *p;
 	struct ubi_wl_entry *e, *victim = NULL;
@@ -433,7 +433,7 @@ struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int max_pnum)
 	if (max_pnum < 0)
 		e = find_mean_wl_entry(&ubi->free);
 	else
-		e = find_early_wl_entry(&ubi->free, max_pnum);
+		e = find_anchor_wl_entry(&ubi->free, max_pnum);
 
 	if (!e)
 		goto out;
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 19/22] UBI: Fastmap: Init fm_sem
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (17 preceding siblings ...)
  2012-06-18 16:19 ` [PATCH 18/22] UBI: Fastmap: Rename "early PEB" to "anchor PEB" Richard Weinberger
@ 2012-06-18 16:19 ` Richard Weinberger
  2012-06-18 16:19 ` [PATCH 20/22] UBI: Fastmap: Use good_peb_count in assert Richard Weinberger
  2012-06-18 16:19 ` [PATCH 21/22] UBI: Fastmap: Fix and explain duplicated PEBs Richard Weinberger
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:19 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

...forgot to stage this change.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/build.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 0ad6789..1ad128d 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -908,6 +908,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
 	mutex_init(&ubi->device_mutex);
 	mutex_init(&ubi->fm_pool_mutex);
 	mutex_init(&ubi->fm_mutex);
+	init_rwsem(&ubi->fm_sem);
 	spin_lock_init(&ubi->volumes_lock);
 
 	ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num);
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 20/22] UBI: Fastmap: Use good_peb_count in assert
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (18 preceding siblings ...)
  2012-06-18 16:19 ` [PATCH 19/22] UBI: Fastmap: Init fm_sem Richard Weinberger
@ 2012-06-18 16:19 ` Richard Weinberger
  2012-06-18 16:19 ` [PATCH 21/22] UBI: Fastmap: Fix and explain duplicated PEBs Richard Weinberger
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:19 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/wl.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index e5ab683..f4d2c79 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1720,10 +1720,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
 	dbg_wl("found %i PEBs", found_pebs);
 
 	if (ubi->fm)
-		ubi_assert(ubi->peb_count - ubi->bad_peb_count == \
+		ubi_assert(ubi->good_peb_count == \
 			   found_pebs + ubi->fm->used_blocks);
 	else
-		ubi_assert(ubi->peb_count - ubi->bad_peb_count == found_pebs);
+		ubi_assert(ubi->good_peb_count == found_pebs);
 
 	if (ubi->avail_pebs < WL_RESERVED_PEBS) {
 		ubi_err("no enough physical eraseblocks (%d, need %d)",
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 21/22] UBI: Fastmap: Fix and explain duplicated PEBs
  2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
                   ` (19 preceding siblings ...)
  2012-06-18 16:19 ` [PATCH 20/22] UBI: Fastmap: Use good_peb_count in assert Richard Weinberger
@ 2012-06-18 16:19 ` Richard Weinberger
  20 siblings, 0 replies; 22+ messages in thread
From: Richard Weinberger @ 2012-06-18 16:19 UTC (permalink / raw)
  To: linux-mtd
  Cc: linux-kernel, adrian.hunter, Heinz.Egger, thomas.wucher,
	shmulik.ladkani, tglx, tim.bird, Marius.Mazarel, artem.bityutskiy,
	Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 drivers/mtd/ubi/fastmap.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index bea9446..45f70db 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -714,6 +714,15 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
 		kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
 	}
 
+	/*
+	 * Sort out dups. We are allowed to have duplicates here because
+	 * the fastmap can be written without refilling all pools.
+	 * E.g. If PEB X is in a pool fastmap may detect it as empty and
+	 * puts it into the free list. But ff PEB X is in the pool, get's
+	 * used and returned (e.g. by schedule_erase()) it remains in
+	 * the erase or free list too.
+	 * We could also sort out these dups while creating the fastmap.
+	 */
 	if (list_empty(&free))
 		goto out;
 
@@ -729,6 +738,18 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
 		}
 	}
 
+	list_for_each_entry(aeb, &ai->erase, u.list) {
+		list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
+			if (aeb->pnum == tmp_aeb->pnum) {
+				aeb->scrub = tmp_aeb->scrub;
+				aeb->ec = tmp_aeb->ec;
+				list_del(&tmp_aeb->u.list);
+				kfree(tmp_aeb);
+				continue;
+			}
+		}
+	}
+
 	list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
 		list_del(&tmp_aeb->u.list);
 		list_add_tail(&tmp_aeb->u.list, &ai->free);
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2012-06-18 16:24 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-18 16:18 UBI Fastmap updates Richard Weinberger
2012-06-18 16:18 ` [PATCH 01/22] UBI: Fastmap: Add EBA selfcheck Richard Weinberger
2012-06-18 16:18 ` [PATCH 02/22] UBI: Fastmap: Fix NULL pointer bug Richard Weinberger
2012-06-18 16:18 ` [PATCH 03/22] UBI: Fastmap: Keep fastmap after attaching Richard Weinberger
2012-06-18 16:18 ` [PATCH 04/22] UBI: Fastmap: Store scrub list in fastmap Richard Weinberger
2012-06-18 16:18 ` [PATCH 05/22] UBI: Fastmap: Rework ubi_wl_put_fm_peb() Richard Weinberger
2012-06-18 16:18 ` [PATCH 06/22] UBI: Fastmap: Make EBA table self check depend on chk_gen Richard Weinberger
2012-06-18 16:18 ` [PATCH 07/22] UBI: Fastmap: Fix build (a left over from the ai->fm removal) Richard Weinberger
2012-06-18 16:18 ` [PATCH 08/22] Revert "UBI: Fastmap: Check for duplicated PEBs in add_aeb()" Richard Weinberger
2012-06-18 16:18 ` [PATCH 09/22] UBI: Fastmap: Fix PEB count assert Richard Weinberger
2012-06-18 16:18 ` [PATCH 10/22] UBI: Fastmap: Remove more useless new lines Richard Weinberger
2012-06-18 16:18 ` [PATCH 11/22] UBI: Fastmap: Get rid of ubi_wl_flush() in ubi_update_fastmap() Richard Weinberger
2012-06-18 16:18 ` [PATCH 12/22] UBI: Fastmap: Locking fixes Richard Weinberger
2012-06-18 16:18 ` [PATCH 13/22] UBI: Fastmap: Fix EC values Richard Weinberger
2012-06-18 16:18 ` [PATCH 14/22] UBI: Fastmap: Fix copy&paste error Richard Weinberger
2012-06-18 16:18 ` [PATCH 15/22] UBI: Fastmap: Kill old fastmap in case of a failure Richard Weinberger
2012-06-18 16:18 ` [PATCH 16/22] UBI: Fastmap: Fix loglevel Richard Weinberger
2012-06-18 16:19 ` [PATCH 17/22] UBI: Fastmap: Add comments to new functions Richard Weinberger
2012-06-18 16:19 ` [PATCH 18/22] UBI: Fastmap: Rename "early PEB" to "anchor PEB" Richard Weinberger
2012-06-18 16:19 ` [PATCH 19/22] UBI: Fastmap: Init fm_sem Richard Weinberger
2012-06-18 16:19 ` [PATCH 20/22] UBI: Fastmap: Use good_peb_count in assert Richard Weinberger
2012-06-18 16:19 ` [PATCH 21/22] UBI: Fastmap: Fix and explain duplicated PEBs Richard Weinberger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).