Received: by 2002:ab2:6309:0:b0:1fb:d597:ff75 with SMTP id s9csp811834lqt; Thu, 6 Jun 2024 21:46:19 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWksSM46Eqm5KXvp9jfCPY6qR5PPw07f1SuKT4h0FKY5ndQ85y/FqR7fafUpzpnKtOI0ipF1xb12Pf8WivHC9lpe39zB+uejBnwiosyuw== X-Google-Smtp-Source: AGHT+IG5wuCxYcJ2S+Ma0Xuy7dA81sornZq+C+2YFgVbK9aEnfhhvAxisOUpUaoEy8Fz1yJp4ORE X-Received: by 2002:a17:906:ae9b:b0:a68:c36c:6c75 with SMTP id a640c23a62f3a-a6cd7a84183mr95659366b.35.1717735579193; Thu, 06 Jun 2024 21:46:19 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1717735579; cv=pass; d=google.com; s=arc-20160816; b=FVMTjTJhPDGeGT3tQ+GwnpGG9BvraH05VjkmhbD7MhMS03+1PXD+jeIARjwpz8QlvW zset39ajyskzLQuHc2Nhu4qeBO7s4t/2tjGM3p2pOxyjykhAPnIKFPH2WCFB50z9Q6TA ceRvpKPZjr8ae+XU8o63UBuJBUoU9CFeSV275AkaIe/3pqSB2F9GiWpE1gBZysSE5arL ys2CqoYfba1L0XC+LQt1nzQ7wQKTXNaCmD+tJQqi4SFmA+vzWkAYejUCdFYgJYTP7pav 0DkipQDQpakV4+j5F5J4VsCqMTs2ImfoT3z2CuUJD+9P6ZnfNWE/Untraf8ql0sn3mjy auWg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=K2JMy2ebR90iBouaDgmcUnDT0MDVWeyl4GSJYficoco=; fh=yXYChwFvQA/NaaLzCC0IJdkW11OhjXgO4DHXzVmnGFw=; b=wH3WrQ6Yz/uoTc5sRedCCN+FgCf1QL9M09zzj4xmaoZ9WbSMzYtRqRyMCyu8omUoVz qb957eXRi1dPQ7kOUJbOR/p3YL+TPNowUN0MLXQ34CQHFc8DhAm3tBeWRTg2VdMBkvvm ilFzIn5bZwPu6C+hToNpqcfoXT3+Rk3c7xgnQqaX6dlaANBpNoRQbgjjfP6CPINWRgDT n2OEMIF95Sg8bSDgbojMmg2SjJ9ls+qj8SiS/HwxnFJ5Aet25wJxyhrqAo+h2rh0Y2zz sNWZd6vOuCWLtiDewpGuXhkPhO94jJCwRpEEDvQRc9nL3xeuYSaqmfEdg4Ru3bmlgDKc pOAw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=huawei.com dmarc=pass fromdomain=huawei.com); spf=pass (google.com: domain of linux-kernel+bounces-205361-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-205361-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id a640c23a62f3a-a6c806db609si133523166b.445.2024.06.06.21.46.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jun 2024 21:46:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-205361-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=huawei.com dmarc=pass fromdomain=huawei.com); spf=pass (google.com: domain of linux-kernel+bounces-205361-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-205361-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id BB44F1F260E5 for ; Fri, 7 Jun 2024 04:46:18 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1C2FE167296; Fri, 7 Jun 2024 04:27:51 +0000 (UTC) Received: from szxga03-in.huawei.com (szxga03-in.huawei.com [45.249.212.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC09961FF6 for ; Fri, 7 Jun 2024 04:27:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.189 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717734468; cv=none; b=Mg0RdLFi4VWZd4x+ZHGt2RzivDMWASKOn2jXsxAwuW1HjK677cSt/TTVtROdswHzC+0fCZEtWok/0Gced9nsRf0LTfI9skkpvtQg7HtqzhfnVBlNLoVdggnB/sxF4Hv19cWh+wD/mkASXhQZD7AsSa+8A2kCikQ09qi+jlqiTLI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717734468; c=relaxed/simple; bh=dF8ezjxrT0QcHwI/GBQO1w4zFWfcy18fGOKinTlEdoo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dq3MstWJ6r6uiftsZJLS3LtxhPRIVOZOPX7q/HX9B+LbkzCj3Cvfe50R1uC72+EWkdhoNxNRj7RliCmnhByt7FAgq6H+NOaEJaa7718Afdjj++Vl3+91PNkPDP/HI6R3bAUbJJHnD9qqFZl+Vc5pbmv7v/E1Hk8EQsOIbvD4oJg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com 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> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600013.china.huawei.com (7.193.23.68) 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); } -- 2.13.6