From patchwork Thu Oct 15 04:04:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsheng Yang X-Patchwork-Id: 530482 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C839B1402B6 for ; Thu, 15 Oct 2015 15:15:10 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZmZuz-00040V-PR; Thu, 15 Oct 2015 04:13:29 +0000 Received: from [59.151.112.132] (helo=heian.cn.fujitsu.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZmZtw-0002pf-SY for linux-mtd@lists.infradead.org; Thu, 15 Oct 2015 04:12:26 +0000 X-IronPort-AV: E=Sophos;i="5.15,520,1432569600"; d="scan'208";a="101857442" Received: from bogon (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 15 Oct 2015 12:14:21 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (localhost.localdomain [127.0.0.1]) by edo.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id t9F4BS3L010933; Thu, 15 Oct 2015 12:11:28 +0800 Received: from yds-PC.g08.fujitsu.local (10.167.226.66) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Thu, 15 Oct 2015 12:11:55 +0800 From: Dongsheng Yang To: , , , , Subject: [PATCH v2 20/27] ubifs: ubifs_dump: dump log area Date: Thu, 15 Oct 2015 12:04:43 +0800 Message-ID: <1444881890-4012-21-git-send-email-yangds.fnst@cn.fujitsu.com> X-Mailer: git-send-email 1.8.4.2 In-Reply-To: <1444881890-4012-1-git-send-email-yangds.fnst@cn.fujitsu.com> References: <1444881890-4012-1-git-send-email-yangds.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.66] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151014_211225_237748_34CE4F4A X-CRM114-Status: GOOD ( 16.13 ) X-Spam-Score: -1.1 (-) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-1.1 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 X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dongsheng Yang Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org scan the log lebs and dump the log nodes out. Signed-off-by: Dongsheng Yang --- ubifs-utils/ubifs_dump/ubifs_dump.c | 140 ++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/ubifs-utils/ubifs_dump/ubifs_dump.c b/ubifs-utils/ubifs_dump/ubifs_dump.c index 4f67621..d7a2951 100644 --- a/ubifs-utils/ubifs_dump/ubifs_dump.c +++ b/ubifs-utils/ubifs_dump/ubifs_dump.c @@ -581,6 +581,142 @@ static int dump_master(void) return 0; } +static int __dump_log_leb(int leb_num) +{ + int err = 0; + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + const struct ubifs_cs_node *node; + static int cs_sqnum = 0; + int lnum = leb_num; + loff_t offs = 0; + int node_num = 0; + + sleb = ubifs_scan(c, lnum, offs, leb_buf, 0); + if (IS_ERR(sleb)) { + printf("Error in scaning log leb"); + return PTR_ERR(sleb); + } + + if (sleb->nodes_cnt == 0) { + err = 1; + goto out; + } + + node = sleb->buf; + snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list); + if (cs_sqnum == 0) { + /* + * This is the first log LEB we are looking at, make sure that + * the first node is a commit start node. Also record its + * sequence number so that UBIFS can determine where the log + * ends, because all nodes which were have higher sequence + * numbers. + */ + if (snod->type != UBIFS_CS_NODE) { + ubifs_err(c, "first log node at LEB %d:%lu is not CS node", + lnum, offs); + goto out_dump; + } + if (le64_to_cpu(node->cmt_no) != mst.cmt_no) { + ubifs_err(c, "first CS node at LEB %d:%lu has wrong commit number %llu expected %llu", + lnum, offs, + (unsigned long long)le64_to_cpu(node->cmt_no), + mst.cmt_no); + goto out_dump; + } + + cs_sqnum = le64_to_cpu(node->ch.sqnum); + } + + if (snod->sqnum < cs_sqnum) { + /* + * This means that we reached end of log and now + * look to the older log data, which was already + * committed but the eraseblock was not erased (UBIFS + * only un-maps it). So this basically means we have to + * exit with "end of log" code. + */ + err = 1; + goto out; + } + + /* Make sure the first node sits at offset zero of the LEB */ + if (snod->offs != 0) { + ubifs_err(c, "first node is not at zero offset"); + goto out_dump; + } + + printf("\tLOG LEB %d\n", lnum); + list_for_each_entry(snod, &sleb->nodes, list) { + if (snod->sqnum < cs_sqnum) { + ubifs_err(c, "bad sqnum %llu, commit sqnum %d", + snod->sqnum, cs_sqnum); + goto out_dump; + } + + printf("\tNODE %d", node_num++); + switch (snod->type) { + case UBIFS_CS_NODE: + printf(" "); + case UBIFS_REF_NODE: { + printf(":\n"); + dump_node(c, snod->node); + break; + } + default: + ubifs_err(c, "unexpected node in log"); + goto out_dump; + } + } + err = !sleb->endpt; +out: + ubifs_scan_destroy(sleb); + return err; + +out_dump: + ubifs_err(c, "log error detected while replaying the log at LEB %d:%lu", + lnum, offs + snod->offs); + ubifs_scan_destroy(sleb); + return -EINVAL; + +} + +static int dump_log(void) +{ + int err, lnum, ltail_lnum, log_last; + + lnum = ltail_lnum = mst.log_lnum; + log_last = UBIFS_LOG_LNUM + sup.log_lebs - 1; + printf("LOG AREA:\n"); + while (lnum <= log_last) { + err = __dump_log_leb(lnum); + if (err == 1) { + if (lnum != mst.log_lnum) + /* We hit the end of the log */ + break; + + /* + * The head of the log must always start with the + * "commit start" node on a properly formatted UBIFS. + * But we found no nodes at all, which means that + * someting went wrong and we cannot proceed mounting + * the file-system. + */ + ubifs_err(c, "no UBIFS nodes found at the log head LEB %d:%d, possibly corrupted", + lnum, 0); + err = -EINVAL; + } + if (err) + goto out; + lnum++; + } + + err = 0; +out: + return err; +} + static int dump() { int err = 0; @@ -598,6 +734,10 @@ static int dump() err = dump_master(); if (err) goto free; + + err = dump_log(); + if (err) + goto free; free: free(leb_buf); out: