From patchwork Fri Jun 7 04:25:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhihao Cheng X-Patchwork-Id: 1944925 X-Patchwork-Delegate: david.oberhollenzer@sigma-star.at Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=XNXlRsfZ; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=infradead.org header.i=@infradead.org header.a=rsa-sha256 header.s=casper.20170209 header.b=KJJcLkjC; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VwVH65VX2z20KL for ; Fri, 7 Jun 2024 15:33:38 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=FjnkMAMB+P4SFnEw2mc14VDYWFnqFKdE01C+jwWrdOc=; b=XNXlRsfZMuWWHU u1gpN1RV959LVWXY3veWuN3S6SacHxU/4J4N2xX5MpxE8BwpF7dFlcgC+WBRjtNFGv/dmbqzxObqU XLjX68QNYnZwmi/rKX77dIGQJb96UdOHKwkEkT4Poz4b8/BiWTTwoV6XcCzZRkdtEFtP+wiWRAjLH qhYOMK97ETKxFXyRZ3soRbjDZH9wdCuGnkDVd2D8mZBS7OYD1RwR7OEn9Wip2etYtnX7DToPzbGJC N8wKygXs9A729+VsbMx/+vzYfOIaApfuTA8Ixc9LFr+Gay+rDOPIzHV8PbgVCVX++lu6D00s/A1Lv FWiXjcxQIb+SuEWD/Tnw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sFSEF-0000000CVdp-3vZM; Fri, 07 Jun 2024 05:33:31 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sFRCl-0000000CH4T-21OG for linux-mtd@bombadil.infradead.org; Fri, 07 Jun 2024 04:27:55 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Type:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From:Sender :Reply-To:Content-ID:Content-Description; bh=K2JMy2ebR90iBouaDgmcUnDT0MDVWeyl4GSJYficoco=; b=KJJcLkjCLMnwe79sHWfyNGuCzC c3bwb9LqW9qAiig+4XA8Nt7xefHWgFB+s75gxKxjwOJFYCMS7LCAt7WF93FmIU0GF915hG388R67K 3SqurSoCsVXDwD3mRvr7SfA8VWpBe1cREo5EK1tt3VzpNijxhu0PhwjflZmwct3nMe+cnGNDmggMU oKzTprkY1mYbt26seeuX3mUrCzC0Oj+85WTaT06j0XKxDM6nvB9hXtVIC1T3Y+rzJYVBcvfvZdyzh apOvrEVSXEsNvcwpNj3EEZtCDusyOf6Kntoh0aHNV1MHqIFh7dWmI1E2R2xaeyEndJQuT6iD83ZMz Ge9ja0yA==; Received: from szxga03-in.huawei.com ([45.249.212.189]) by casper.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sFRCg-00000004U2U-1AOI for linux-mtd@lists.infradead.org; Fri, 07 Jun 2024 04:27:54 +0000 Received: from mail.maildlp.com (unknown [172.19.163.252]) by szxga03-in.huawei.com (SkyGuard) with ESMTP id 4VwSl93ZSXzPpnL; Fri, 7 Jun 2024 12:24:21 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id C49D2180AA6; Fri, 7 Jun 2024 12:27:40 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Fri, 7 Jun 2024 12:27:25 +0800 From: Zhihao Cheng To: , , , , , CC: , Subject: [RFC PATCH mtd-utils 080/110] fsck.ubifs: Recover isize Date: Fri, 7 Jun 2024 12:25:45 +0800 Message-ID: <20240607042615.2069840-81-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240607042615.2069840-1-chengzhihao1@huawei.com> References: <20240607042615.2069840-1-chengzhihao1@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.67] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600013.china.huawei.com (7.193.23.68) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240607_052750_945412_805AA343 X-CRM114-Status: GOOD ( 18.01 ) X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 4.0.0 on casper.infradead.org summary: Content analysis details: (-4.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_MSPIKE_H4 RBL: Very Good reputation (+4) [45.249.212.189 listed in wl.mailspike.net] -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.189 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 T_SCC_BODY_TEXT_LINE No description available. X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This is the 5/18 step of fsck. Recover isize. There could be following steps and possible errors: Step 1. Traverse size tree, lookup corresponding inode from TNC a. corrupted node searched from TNC: skip node for danger mode and normal mode with 'yes' answer, other modes will exit. b. corrupted index node read from TNC: danger mode with rebuild_fs and normal mode with 'yes' answer will turn to rebuild filesystem, other modes will exit. Step 2. update isize for inode. Keep in size tree for check mode, update inode node in place for other modes. Signed-off-by: Zhihao Cheng --- ubifs-utils/fsck.ubifs/fsck.ubifs.c | 1 + ubifs-utils/fsck.ubifs/load_fs.c | 79 +++++++++++++++++++++---------------- ubifs-utils/libubifs/recovery.c | 34 +++++++++++++--- 3 files changed, 75 insertions(+), 39 deletions(-) diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.c b/ubifs-utils/fsck.ubifs/fsck.ubifs.c index 9d69a4fd..77013851 100644 --- a/ubifs-utils/fsck.ubifs/fsck.ubifs.c +++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.c @@ -434,6 +434,7 @@ int main(int argc, char *argv[]) * Step 2: Replay journal * Step 3: Handle orphan nodes * Step 4: Consolidate log + * Step 5: Recover isize */ err = ubifs_load_filesystem(c); if (err) { diff --git a/ubifs-utils/fsck.ubifs/load_fs.c b/ubifs-utils/fsck.ubifs/load_fs.c index 42b1afaa..58540543 100644 --- a/ubifs-utils/fsck.ubifs/load_fs.c +++ b/ubifs-utils/fsck.ubifs/load_fs.c @@ -17,6 +17,33 @@ #include "misc.h" #include "fsck.ubifs.h" +enum { HAS_DATA_CORRUPTED = 1, HAS_TNC_CORRUPTED = 2 }; + +static void handle_error(const struct ubifs_info *c, int reason_set) +{ + bool handled = false; + unsigned int reason = get_failure_reason_callback(c); + + clear_failure_reason_callback(c); + if ((reason_set & HAS_DATA_CORRUPTED) && (reason & FR_DATA_CORRUPTED)) { + handled = true; + reason &= ~FR_DATA_CORRUPTED; + if (fix_problem(c, LOG_CORRUPTED, NULL)) + FSCK(c)->try_rebuild = true; + } + if ((reason_set & HAS_TNC_CORRUPTED) && (reason & FR_TNC_CORRUPTED)) { + ubifs_assert(c, !handled); + handled = true; + reason &= ~FR_TNC_CORRUPTED; + if (fix_problem(c, TNC_CORRUPTED, NULL)) + FSCK(c)->try_rebuild = true; + } + + ubifs_assert(c, reason == 0); + if (!handled) + exit_code |= FSCK_ERROR; +} + int ubifs_load_filesystem(struct ubifs_info *c) { int err; @@ -164,19 +191,7 @@ int ubifs_load_filesystem(struct ubifs_info *c) log_out(c, "Replay journal"); err = ubifs_replay_journal(c); if (err) { - unsigned int reason = get_failure_reason_callback(c); - - clear_failure_reason_callback(c); - if (reason & FR_DATA_CORRUPTED) { - if (fix_problem(c, LOG_CORRUPTED, NULL)) - FSCK(c)->try_rebuild = true; - } else if (reason & FR_TNC_CORRUPTED) { - if (fix_problem(c, TNC_CORRUPTED, NULL)) - FSCK(c)->try_rebuild = true; - } else { - ubifs_assert(c, reason == 0); - exit_code |= FSCK_ERROR; - } + handle_error(c, HAS_DATA_CORRUPTED | HAS_TNC_CORRUPTED); goto out_journal; } @@ -186,16 +201,7 @@ int ubifs_load_filesystem(struct ubifs_info *c) log_out(c, "Handle orphan nodes"); err = ubifs_mount_orphans(c, c->need_recovery, c->ro_mount); if (err) { - unsigned int reason = get_failure_reason_callback(c); - - clear_failure_reason_callback(c); - if (reason & FR_TNC_CORRUPTED) { - if (fix_problem(c, TNC_CORRUPTED, NULL)) - FSCK(c)->try_rebuild = true; - } else { - ubifs_assert(c, reason == 0); - exit_code |= FSCK_ERROR; - } + handle_error(c, HAS_TNC_CORRUPTED); goto out_orphans; } @@ -210,19 +216,26 @@ int ubifs_load_filesystem(struct ubifs_info *c) log_out(c, "Consolidate log"); err = ubifs_consolidate_log(c); if (err) { - unsigned int reason = get_failure_reason_callback(c); - - clear_failure_reason_callback(c); - if (reason & FR_DATA_CORRUPTED) { - if (fix_problem(c, LOG_CORRUPTED, NULL)) - FSCK(c)->try_rebuild = true; - } else { - ubifs_assert(c, reason == 0); - exit_code |= FSCK_ERROR; - } + handle_error(c, HAS_DATA_CORRUPTED); + goto out_orphans; + } + } + + if (c->need_recovery) { + log_out(c, "Recover isize"); + err = ubifs_recover_size(c, true); + if (err) { + handle_error(c, HAS_TNC_CORRUPTED); goto out_orphans; } } + } else if (c->need_recovery) { + log_out(c, "Recover isize"); + err = ubifs_recover_size(c, false); + if (err) { + handle_error(c, HAS_TNC_CORRUPTED); + goto out_orphans; + } } c->mounting = 0; diff --git a/ubifs-utils/libubifs/recovery.c b/ubifs-utils/libubifs/recovery.c index 9115b17a..a5133a0f 100644 --- a/ubifs-utils/libubifs/recovery.c +++ b/ubifs-utils/libubifs/recovery.c @@ -1272,8 +1272,18 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e) /* Locate the inode node LEB number and offset */ ino_key_init(c, &key, e->inum); err = ubifs_tnc_locate(c, &key, ino, &lnum, &offs); - if (err) + if (err) { + unsigned int reason = get_failure_reason_callback(c); + + if (reason & FR_DATA_CORRUPTED) { + test_and_clear_failure_reason_callback(c, FR_DATA_CORRUPTED); + if (handle_failure_callback(c, FR_H_TNC_DATA_CORRUPTED, NULL)) { + /* Leave the inode to be deleted by subsequent steps */ + return 0; + } + } goto out; + } /* * If the size recorded on the inode node is greater than the size that * was calculated from nodes in the journal then don't change the inode. @@ -1320,10 +1330,10 @@ out: */ static int inode_fix_size(struct ubifs_info *c, __unused struct size_entry *e) { - ubifs_assert(c, 0); - - // To be implemented - return -EINVAL; + /* Don't remove entry, keep it in the size tree. */ + /* Remove this assertion after supporting authentication. */ + ubifs_assert(c, c->ro_mount); + return 0; } /** @@ -1353,8 +1363,19 @@ int ubifs_recover_size(struct ubifs_info *c, bool in_place) ino_key_init(c, &key, e->inum); err = ubifs_tnc_lookup(c, &key, c->sbuf); - if (err && err != -ENOENT) + if (err && err != -ENOENT) { + unsigned int reason; + + reason = get_failure_reason_callback(c); + if (reason & FR_DATA_CORRUPTED) { + test_and_clear_failure_reason_callback(c, FR_DATA_CORRUPTED); + if (handle_failure_callback(c, FR_H_TNC_DATA_CORRUPTED, NULL)) { + /* Leave the inode to be deleted by subsequent steps */ + goto delete_entry; + } + } return err; + } if (err == -ENOENT) { /* Remove data nodes that have no inode */ dbg_rcvry("removing ino %lu", @@ -1390,6 +1411,7 @@ int ubifs_recover_size(struct ubifs_info *c, bool in_place) } } +delete_entry: rb_erase(&e->rb, &c->size_tree); kfree(e); }