linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Richard Weinberger <richard@nod.at>
To: linux-mtd@lists.infradead.org
Cc: linux-kernel@vger.kernel.org, Richard Weinberger <richard@nod.at>
Subject: [PATCH 05/14] ubi: fastmap: Implement PEB translation
Date: Wed, 13 Jun 2018 23:23:35 +0200	[thread overview]
Message-ID: <20180613212344.11608-6-richard@nod.at> (raw)
In-Reply-To: <20180613212344.11608-1-richard@nod.at>

When a fastmap is preseeded we have to translate PEB numbers because
during the creation of the fastmap the creation tool cannot know
which blocks are bad on the target(s).

Therefore fastmap has to learn all bad blocks during attach and
changes PEB numbers accordingly.
This feature assumes that bad blocks are skipped while the image was
flashed, what nandwrite does by default.

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

diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index 93ceea4f27d5..9a8072cf458c 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -1370,6 +1370,7 @@ static void destroy_ai(struct ubi_attach_info *ai)
 	}
 
 	kmem_cache_destroy(ai->aeb_slab_cache);
+	kfree(ai->bb_trans);
 	kfree(ai);
 }
 
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 1ebb5d15ab1a..279d02874297 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -107,6 +107,9 @@ static bool read_pnum(struct ubi_device *ubi, struct ubi_attach_info *ai,
 	int ret = true;
 	int max_pnum = ubi->peb_count;
 
+	if (ai->bb_trans)
+		max_pnum -= ai->bad_peb_count;
+
 	pnum = be32_to_cpu(pnum);
 	if (pnum == UBI_UNKNOWN) {
 		*out_pnum = pnum;
@@ -117,10 +120,13 @@ static bool read_pnum(struct ubi_device *ubi, struct ubi_attach_info *ai,
 		ubi_err(ubi, "fastmap references PEB out of range: %i", pnum);
 		ret = false;
 		goto out;
-	} else {
-		*out_pnum = pnum;
 	}
 
+	if (!ai->bb_trans)
+		*out_pnum = pnum;
+	else
+		*out_pnum = ai->bb_trans[pnum];
+
 out:
 	return ret;
 }
@@ -880,6 +886,61 @@ static struct ubi_ainf_peb *clone_aeb(struct ubi_attach_info *ai,
 	return new;
 }
 
+/*
+ * build_bb_trans_table - create a translation table to fix PEB numbers.
+ * @ubi: UBI device object
+ * @ai: UBI attach info object
+ *
+ * A preseeded Fastmap has no knowledge of bad blocks. During first attach
+ * UBI has to update PEB numbers to leave out existing bad blocks.
+ */
+static int build_bb_trans_table(struct ubi_device *ubi,
+				struct ubi_attach_info *ai)
+{
+	int pnum, new_pnum, ret;
+	unsigned long *claimed_blocks;
+
+	ret = -ENOMEM;
+	claimed_blocks = kcalloc(BITS_TO_LONGS(ubi->peb_count),
+			       sizeof(unsigned long), GFP_KERNEL);
+	if (!claimed_blocks)
+		goto out;
+
+	/* ai->bb_trans will get free'ed via destroy_ai() */
+	ai->bb_trans = kcalloc(ubi->peb_count, sizeof(int), GFP_KERNEL);
+	if (!ai->bb_trans)
+		goto out;
+
+	/* Find all bad blocks and mark them as claimed */
+	for (pnum = 0; pnum < ubi->peb_count; pnum++) {
+		ret = ubi_io_is_bad(ubi, pnum);
+		if (ret < 0)
+			goto out;
+
+		if (ret == 1) {
+			set_bit(pnum, claimed_blocks);
+			ai->bad_peb_count++;
+		}
+	}
+
+	/*
+	 * Start with PEB 0 and try to place each PEB around all bad blocks
+	 * to create the translation table.
+	 */
+	for (pnum = 0; pnum < ubi->peb_count - ai->bad_peb_count; pnum++) {
+		ubi_assert(!bitmap_full(claimed_blocks, ubi->peb_count));
+
+		new_pnum = find_first_zero_bit(claimed_blocks, ubi->peb_count);
+		ai->bb_trans[pnum] = new_pnum;
+		set_bit(new_pnum, claimed_blocks);
+	}
+
+out:
+	kfree(claimed_blocks);
+
+	return ret;
+}
+
 /**
  * ubi_scan_fastmap - scan the fastmap.
  * @ubi: UBI device object
@@ -987,6 +1048,15 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
 		goto free_fm_sb;
 	}
 
+	if (fm->flags & UBI_FM_SB_PRESEEDED_FLG) {
+		ubi_msg(ubi, "preseeded fastmap found");
+		ret = build_bb_trans_table(ubi, ai);
+		if (ret) {
+			ubi_err(ubi, "failed to construct bb translation table");
+			goto free_fm_sb;
+		}
+	}
+
 	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
 	if (!ech) {
 		ret = -ENOMEM;
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 4fab3790733b..28af5115d180 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -760,6 +760,7 @@ struct ubi_ainf_volume {
  * @aeb_slab_cache: slab cache for &struct ubi_ainf_peb objects
  * @ech: temporary EC header. Only available during scan
  * @vidh: temporary VID buffer. Only available during scan
+ * @bb_trans: bad block translation table, used by fastmap, NULL otherwise
  *
  * 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
@@ -790,6 +791,7 @@ struct ubi_attach_info {
 	struct kmem_cache *aeb_slab_cache;
 	struct ubi_ec_hdr *ech;
 	struct ubi_vid_io_buf *vidb;
+	int *bb_trans;
 };
 
 /**
-- 
2.13.6


  parent reply	other threads:[~2018-06-13 21:24 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-13 21:23 [PATCH 00/14] ubi: Fastmap updates Richard Weinberger
2018-06-13 21:23 ` [PATCH 01/14] ubi: fastmap: Read PEB numbers more carefully Richard Weinberger
2018-06-14  1:04   ` kbuild test robot
2018-06-14  6:23     ` Richard Weinberger
2018-06-20 10:17   ` Boris Brezillon
2018-06-13 21:23 ` [PATCH 02/14] ubi: Fix assert in ubi_wl_init Richard Weinberger
2018-06-20 10:11   ` Boris Brezillon
2018-06-13 21:23 ` [PATCH 03/14] ubi: fastmap: Add support for flags Richard Weinberger
2018-06-24 12:49   ` Boris Brezillon
2018-06-13 21:23 ` [PATCH 04/14] ubi: fastmap: Add UBI_FM_SB_PRESEEDED_FLG flag Richard Weinberger
2018-06-24 12:53   ` Boris Brezillon
2018-06-13 21:23 ` Richard Weinberger [this message]
2018-06-13 21:23 ` [PATCH 06/14] ubi: fastmap: Handle bad block count for preseeded fastmap case Richard Weinberger
2018-06-13 21:23 ` [PATCH 07/14] ubi: fastmap: Fixup pool sizes for preseeded fastmaps Richard Weinberger
2018-06-13 21:23 ` [PATCH 08/14] ubi: fastmap: Scan empty space if fastmap is preseeded Richard Weinberger
2018-06-13 21:23 ` [PATCH 09/14] ubi: fastmap: Relax size check Richard Weinberger
2018-06-24 12:55   ` Boris Brezillon
2018-06-13 21:23 ` [PATCH 10/14] ubi: fastmap: Change a WARN_ON() to ubi_err() Richard Weinberger
2018-06-24 13:04   ` Boris Brezillon
2018-06-13 21:23 ` [PATCH 11/14] ubi: Add module parameter to force a full scan Richard Weinberger
2018-06-24 13:09   ` Boris Brezillon
2018-06-13 21:23 ` [PATCH 12/14] ubi: uapi: Add mode selector to attach request Richard Weinberger
2018-06-24 13:12   ` Boris Brezillon
2018-06-13 21:23 ` [PATCH 13/14] ubi: Wire up attach mode selector Richard Weinberger
2018-06-13 21:23 ` [PATCH 14/14] ubi: Remove experimental stigma from Fastmap Richard Weinberger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180613212344.11608-6-richard@nod.at \
    --to=richard@nod.at \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).