From patchwork Mon Jun 18 16:18:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 165503 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 046D6B7019 for ; Tue, 19 Jun 2012 02:21:35 +1000 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Sgefx-0000do-3a; Mon, 18 Jun 2012 16:19:37 +0000 Received: from a.ns.miles-group.at ([95.130.255.143] helo=radon.swed.at) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Sgefn-0000ci-39 for linux-mtd@lists.infradead.org; Mon, 18 Jun 2012 16:19:29 +0000 Received: (qmail 14142 invoked by uid 89); 18 Jun 2012 16:19:21 -0000 Received: by simscan 1.3.1 ppid: 14119, pid: 14139, t: 0.1305s scanners: attach: 1.3.1 clamav: 0.96.5/m:53 Received: from unknown (HELO localhost.localdomain) (richard@nod.at@212.62.202.73) by radon.swed.at with ESMTPA; 18 Jun 2012 16:19:21 -0000 From: Richard Weinberger To: linux-mtd@lists.infradead.org Subject: [PATCH 01/22] UBI: Fastmap: Add EBA selfcheck Date: Mon, 18 Jun 2012 18:18:44 +0200 Message-Id: <1340036345-96726-2-git-send-email-richard@nod.at> X-Mailer: git-send-email 1.7.6.5 In-Reply-To: <1340036345-96726-1-git-send-email-richard@nod.at> References: <1340036345-96726-1-git-send-email-richard@nod.at> X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: artem.bityutskiy@linux.intel.com, linux-kernel@vger.kernel.org, adrian.hunter@intel.com, Heinz.Egger@linutronix.de, thomas.wucher@linutronix.de, shmulik.ladkani@gmail.com, Richard Weinberger , tglx@linutronix.de, Marius.Mazarel@ugal.ro, tim.bird@am.sony.com X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Using this self-check it's possible to proof Fastmap's correctness. Signed-off-by: Richard Weinberger --- 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);