From patchwork Mon May 14 11:24:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 912870 X-Patchwork-Delegate: richard@nod.at Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nod.at Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="QXQbwjDa"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40kz5j5XY3z9s0W for ; Mon, 14 May 2018 21:30:33 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=UaIcrNz8L8GPJUb3mX7rtGxsHrjh3x5rHuWKU7kMZV0=; b=QXQbwjDaQql8DilLGWbvYU78qn J7Bp4/+gdQkOmbi6HRxx8cMwr6oEcCZrKbscbOFPZE4hceoFl4G06z6da1KXjZ8yA9FclX2PC7a7S mDWvTrs13LziYHVRWml+KFkMRQF8108r3p4Wlkql8gYbn8c6/zl/ELn/AKB3ILtEHh2RTbTS5xfsq 9LoW3909Nd0rPp79jTBhO7UYIFcIVIcRf/SlZrrYGv8/6V38cCKEc+0++qhTuMUyKizzzjXe6EOa/ lhW/INJgPECaM7L51Wv+YgODgDD3j/uk2+JjIG0NWFx2O5lHcA1zuJP3THNhYlgzMdaXaeqGXJB1t KBfOFFcw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fIBgL-0007uY-6h; Mon, 14 May 2018 11:30:21 +0000 Received: from lilium.sigma-star.at ([109.75.188.150]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fIBbC-0003cY-QV for linux-mtd@lists.infradead.org; Mon, 14 May 2018 11:25:10 +0000 Received: from localhost (localhost [127.0.0.1]) by lilium.sigma-star.at (Postfix) with ESMTP id 40BA2181A2F16; Mon, 14 May 2018 13:24:36 +0200 (CEST) From: Richard Weinberger To: linux-mtd@lists.infradead.org Subject: [PATCH 6/8] ubi: fastmap: Scan empty space if fastmap is preseeded Date: Mon, 14 May 2018 13:24:20 +0200 Message-Id: <20180514112422.23988-7-richard@nod.at> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180514112422.23988-1-richard@nod.at> References: <20180514112422.23988-1-richard@nod.at> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180514_042503_250079_EC8CEED6 X-CRM114-Status: GOOD ( 20.62 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 T_SPF_PERMERROR SPF: test of record failed (permerror) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Weinberger , linux-kernel@vger.kernel.org MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The creation tool does not know the real size of the MTD, therefore the preseeded fastmap references only used PEBs. Free PEBs need to be discovered during the initial attach of the preseeded fastmap. Signed-off-by: Richard Weinberger --- drivers/mtd/ubi/fastmap.c | 109 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 0d1274b69274..5ec14fd70c13 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -400,6 +400,94 @@ static void unmap_peb(struct ubi_attach_info *ai, int pnum) } } } +/** + * scan_empty_space - scan empty space. + * + * @ubi: UBI device object + * @ai: attach info object + * @start: PEB number where empty space is expected to start + * + * Is is the fastmap preseeded, it references only used PEBs, the creation + * does not know the real MTD size. Therefore many PEBs are 0xff and unknown + * to the fastmap. Scan for this PEBs during attach and make them known. + * These PEBs are only allowed to be 0xff or have a valid EC header. + * EC headers are allowed because the initial scan+erase operation could be + * interrupted by a power cycle. + */ +static int scan_empty_space(struct ubi_device *ubi, struct ubi_attach_info *ai, + int start) +{ + int pnum, err, scrub, empty, image_seq; + unsigned long long ec; + struct ubi_ec_hdr *ech = NULL; + struct ubi_vid_io_buf *vb = NULL; + struct ubi_vid_hdr *vh; + + err = -ENOMEM; + + ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ech) + goto out; + + vb = ubi_alloc_vid_buf(ubi, GFP_KERNEL); + if (!vb) + goto out; + + vh = ubi_get_vid_hdr(vb); + + for (pnum = start; pnum < ubi->peb_count; pnum++) { + if (ubi_io_is_bad(ubi, pnum)) + continue; + + scrub = empty = ec = 0; + err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); + switch (err) { + case UBI_IO_FF_BITFLIPS: + scrub = 1; + /* fall through */ + case UBI_IO_FF: + empty = 1; + break; + case UBI_IO_BITFLIPS: + scrub = 1; + /* fall through */ + case 0: + ec = be64_to_cpu(ech->ec); + image_seq = be32_to_cpu(ech->image_seq); + + if (image_seq && (image_seq != ubi->image_seq)) { + ubi_err(ubi, "bad image seq: 0x%x, expected: 0x%x", + image_seq, ubi->image_seq); + err = UBI_BAD_FASTMAP; + goto out; + } + break; + default: + ubi_err(ubi, "Unable to read EC header in empty space: %i", + err); + err = UBI_BAD_FASTMAP; + goto out; + } + + err = ubi_io_read_vid_hdr(ubi, pnum, vb, 0); + if (err != UBI_IO_FF && err != UBI_IO_FF_BITFLIPS) { + ubi_err(ubi, "Unexpected data in empty space: %i", err); + err = UBI_BAD_FASTMAP; + goto out; + } + + if (empty) + add_aeb(ai, &ai->erase, pnum, ec, scrub); + else + add_aeb(ai, &ai->free, pnum, ec, scrub); + } + + err = 0; +out: + kfree(ech); + ubi_free_vid_buf(vb); + return err; +} /** * scan_pool - scans a pool for changed (no longer empty PEBs). @@ -784,13 +872,22 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, } } - ret = scan_pool(ubi, ai, fmpl->pebs, pool_size, &max_sqnum, &free); - if (ret) - goto fail; + if (!(fm->flags & UBI_FM_SB_PRESEEDED_FLG)) { + ret = scan_pool(ubi, ai, fmpl->pebs, pool_size, &max_sqnum, &free); + if (ret) + goto fail; - ret = scan_pool(ubi, ai, fmpl_wl->pebs, wl_pool_size, &max_sqnum, &free); - if (ret) - goto fail; + ret = scan_pool(ubi, ai, fmpl_wl->pebs, wl_pool_size, &max_sqnum, &free); + if (ret) + goto fail; + } + + if (fm->flags & UBI_FM_SB_PRESEEDED_FLG) { + int empty_start = fix_pnum(ai, be32_to_cpu(fmhdr->used_peb_count) + fm->used_blocks); + ret = scan_empty_space(ubi, ai, empty_start); + if (ret) + goto fail; + } if (max_sqnum > ai->max_sqnum) ai->max_sqnum = max_sqnum;