From patchwork Wed May 16 12:20:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Reardon X-Patchwork-Id: 159613 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 2F5E6B6F86 for ; Wed, 16 May 2012 22:23:09 +1000 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1SUdDy-0000Eu-MO; Wed, 16 May 2012 12:21:02 +0000 Received: from [78.46.68.141] (helo=eristoteles.iwoars.net) by merlin.infradead.org with smtp (Exim 4.76 #1 (Red Hat Linux)) id 1SUdDv-0000Eg-Io for linux-mtd@lists.infradead.org; Wed, 16 May 2012 12:21:00 +0000 Received: (qmail 29334 invoked by uid 5144); 16 May 2012 14:20:56 +0200 Received: from localhost (sendmail-bs@127.0.0.1) by localhost with SMTP; 16 May 2012 14:20:56 +0200 Date: Wed, 16 May 2012 14:20:56 +0200 (CEST) From: Joel Reardon X-X-Sender: joel@eristoteles.iwoars.net To: Artem Bityutskiy Subject: [PATCH] ubi: add volume id and LEB number to struct ubi_scan_leb Message-ID: User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -0.8 (/) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-0.8 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.8 RDNS_NONE Delivered to internal network by a host with no rDNS 0.3 FROM_12LTRDOM From a 12-letter domain 0.0 SUBJ_OBFU_PUNCT_FEW Possible punctuation-obfuscated Subject: header Cc: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org 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: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This patch adds the volume id and LEB number to struct ubi_scan_leb when scanning the LEBs at startup. PEBs now added to the erase queue will know their original LEB number and volume id, if available, and will be -1 otherwise (for instance, if the vid header is unreadable). This was tested by creating an ubi device with 3 volumes and disabiling the ubi_thread's do_work functionality. The different ubi volumes were formatted to ubifs and had files created and erased. The ubi modules was reloaded and the list of LEB's added to the erased list was outputted, confirming the volume ids and LEB numbers were appropriate. Signed-off-by: Joel Reardon --- drivers/mtd/ubi/scan.c | 49 +++++++++++++++++++++++++++++------------------ drivers/mtd/ubi/scan.h | 2 + 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index c26b1ad..3d87446 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -102,20 +102,23 @@ static struct ubi_vid_hdr *vidh; * add_to_list - add physical eraseblock to a list. * @si: scanning information * @pnum: physical eraseblock number to add + * @vol_id: the last used volume id for the PEB + * @lnum: the last used LEB number for the PEB * @ec: erase counter of the physical eraseblock * @to_head: if not zero, add to the head of the list * @list: the list to add to * * This function adds physical eraseblock @pnum to free, erase, or alien lists. - * If @to_head is not zero, PEB will be added to the head of the list, which - * basically means it will be processed first later. E.g., we add corrupted - * PEBs (corrupted due to power cuts) to the head of the erase list to make - * sure we erase them first and get rid of corruptions ASAP. This function - * returns zero in case of success and a negative error code in case of - * failure. + * It stores the @lnum and @vol_id alongside, which can both be -1 if they are + * not available, not readable, or not assigned. If @to_head is not zero, PEB + * will be added to the head of the list, which basically means it will be + * processed first later. E.g., we add corrupted PEBs (corrupted due to power + * cuts) to the head of the erase list to make sure we erase them first and + * get rid of corruptions ASAP. This function returns zero in case of success + * and a negative error code in case of failure. */ -static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head, - struct list_head *list) +static int add_to_list(struct ubi_scan_info *si, int pnum, int vol_id, + int lnum, int ec, int to_head, struct list_head *list) { struct ubi_scan_leb *seb; @@ -134,6 +137,8 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head, return -ENOMEM; seb->pnum = pnum; + seb->vol_id = vol_id; + seb->lnum = lnum; seb->ec = ec; if (to_head) list_add(&seb->u.list, list); @@ -532,13 +537,16 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, if (err) return err; - err = add_to_list(si, seb->pnum, seb->ec, cmp_res & 4, + err = add_to_list(si, seb->pnum, seb->vol_id, + seb->lnum, seb->ec, cmp_res & 4, &si->erase); if (err) return err; seb->ec = ec; seb->pnum = pnum; + seb->vol_id = vol_id; + seb->lnum = lnum; seb->scrub = ((cmp_res & 2) || bitflips); seb->copy_flag = vid_hdr->copy_flag; seb->sqnum = sqnum; @@ -553,8 +561,8 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, * This logical eraseblock is older than the one found * previously. */ - return add_to_list(si, pnum, ec, cmp_res & 4, - &si->erase); + return add_to_list(si, pnum, vol_id, lnum, ec, + cmp_res & 4, &si->erase); } } @@ -573,6 +581,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, seb->ec = ec; seb->pnum = pnum; + seb->vol_id = vol_id; seb->lnum = lnum; seb->scrub = bitflips; seb->copy_flag = vid_hdr->copy_flag; @@ -868,11 +877,11 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, break; case UBI_IO_FF: si->empty_peb_count += 1; - return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, 0, + return add_to_list(si, pnum, -1, -1, UBI_SCAN_UNKNOWN_EC, 0, &si->erase); case UBI_IO_FF_BITFLIPS: si->empty_peb_count += 1; - return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, 1, + return add_to_list(si, pnum, -1, -1, UBI_SCAN_UNKNOWN_EC, 1, &si->erase); case UBI_IO_BAD_HDR_EBADMSG: case UBI_IO_BAD_HDR: @@ -984,7 +993,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, return err; else if (!err) /* This corruption is caused by a power cut */ - err = add_to_list(si, pnum, ec, 1, &si->erase); + err = add_to_list(si, pnum, -1, -1, ec, 1, &si->erase); else /* This is an unexpected corruption */ err = add_corrupted(si, pnum, ec); @@ -992,15 +1001,15 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, return err; goto adjust_mean_ec; case UBI_IO_FF_BITFLIPS: - err = add_to_list(si, pnum, ec, 1, &si->erase); + err = add_to_list(si, pnum, -1, -1, ec, 1, &si->erase); if (err) return err; goto adjust_mean_ec; case UBI_IO_FF: if (ec_err) - err = add_to_list(si, pnum, ec, 1, &si->erase); + err = add_to_list(si, pnum, -1, -1, ec, 1, &si->erase); else - err = add_to_list(si, pnum, ec, 0, &si->free); + err = add_to_list(si, pnum, -1, -1, ec, 0, &si->free); if (err) return err; goto adjust_mean_ec; @@ -1019,7 +1028,8 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, case UBI_COMPAT_DELETE: ubi_msg("\"delete\" compatible internal volume %d:%d" " found, will remove it", vol_id, lnum); - err = add_to_list(si, pnum, ec, 1, &si->erase); + err = add_to_list(si, pnum, vol_id, lnum, + ec, 1, &si->erase); if (err) return err; return 0; @@ -1034,7 +1044,8 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, case UBI_COMPAT_PRESERVE: ubi_msg("\"preserve\" compatible internal volume %d:%d" " found", vol_id, lnum); - err = add_to_list(si, pnum, ec, 0, &si->alien); + err = add_to_list(si, pnum, vol_id, lnum, + ec, 0, &si->alien); if (err) return err; return 0; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index d48aef1..e214647 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -28,6 +28,7 @@ * struct ubi_scan_leb - scanning information about a physical eraseblock. * @ec: erase counter (%UBI_SCAN_UNKNOWN_EC if it is unknown) * @pnum: physical eraseblock number + * @vol_id: the volume identifier of the LEB. * @lnum: logical eraseblock number * @scrub: if this physical eraseblock needs scrubbing * @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB) @@ -42,6 +43,7 @@ struct ubi_scan_leb { int ec; int pnum; + int vol_id; int lnum; unsigned int scrub:1; unsigned int copy_flag:1;