Received: by 2002:a05:7412:b995:b0:f9:9502:5bb8 with SMTP id it21csp3701051rdb; Wed, 27 Dec 2023 17:41:30 -0800 (PST) X-Google-Smtp-Source: AGHT+IHu7mhAF8CGAAkiCv6XNv5JQS+XDPe0seh5XwvVQ5EFYGUMaKpVS+cq8cSKxNJht0tbn7jV X-Received: by 2002:a05:622a:296:b0:427:f2a5:709b with SMTP id z22-20020a05622a029600b00427f2a5709bmr1331429qtw.95.1703727690530; Wed, 27 Dec 2023 17:41:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1703727690; cv=none; d=google.com; s=arc-20160816; b=0ad8EHUD6ShjdyAExkSX4DOSwwdqYD4cBT5hJYGLHVSYb1uv/s4/DDhH50SDDyHyg9 2+vPZANalMW1IBGYzizX7GOnDx7oIc8ymNvRXzaBMHqpdvhQHBELrlnEoyBqDZLL8sQr xU5xlVKgwI8rx2dO1b++ErBRVv6x++GGF30EaoMgGuAf6Yn8+MtKiy0aJLIEfG5uX9C3 XklqfoFcycCTyx+W9ohVTp1Y4MuGIP2QmTmeM8y8C5JewZzu/BiMBSeEybM0PSfG2NHE k5trCd555bMtNDpMMjr63Lgyun9LYfZNPI/vzSmp6UW46Ga5Rg9drNIrqzPWs9qFRANC F83A== ARC-Message-Signature: i=1; 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=MuD3w0hhFvysu5VCOAdLKHpf1w9LztkZs9aulBFSgCc=; fh=3kaVOPShTC55oj708yh1yJALapWuogKx6Yvc3sQq9zY=; b=K2TZzqvc/bi0xAT8y53Xk+/IQn/9MrWogGcYrP8ZwcpQskb0utEk+9YpMiSnwwUjEl lJS/8bySDHvUvw5X/zhW9SAnkwIDYFouUzjQ0lKnQbVJkG7aSkvSEJeJqfbG6+dQtsSv 7R5qmJeM+Vry0TcVNLnXIIkNUprHXIssyz4nGoggoqann1qRXWKtsdHYX0TFRw50DqWx 8efkaR081GCgA0d9xjRVGRpWxxXfpmHna36GcZwElasE2N+mm/oaQ9V3tAZuR12B4x6g paCwYM+0dS2mxsii/kqjlaESiAStra8mZUl1OZZRhC36hQXesGLgt6DRDMKspssLJMrp 8xVw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-12362-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-12362-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id v6-20020a05622a014600b004260b6e6a51si15815268qtw.699.2023.12.27.17.41.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Dec 2023 17:41:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-12362-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-12362-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-12362-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 ny.mirrors.kernel.org (Postfix) with ESMTPS id 3AC151C213D2 for ; Thu, 28 Dec 2023 01:41:30 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 957A6C8DE; Thu, 28 Dec 2023 01:39:02 +0000 (UTC) X-Original-To: linux-kernel@vger.kernel.org Received: from szxga05-in.huawei.com (szxga05-in.huawei.com [45.249.212.191]) (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 43705C2C4 for ; Thu, 28 Dec 2023 01:39:00 +0000 (UTC) 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.88.214]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4T0rff4TmSz1FGNl; Thu, 28 Dec 2023 09:35:06 +0800 (CST) Received: from kwepemm000013.china.huawei.com (unknown [7.193.23.81]) by mail.maildlp.com (Postfix) with ESMTPS id 8D0381A0198; Thu, 28 Dec 2023 09:38:43 +0800 (CST) Received: from huawei.com (10.175.127.227) by kwepemm000013.china.huawei.com (7.193.23.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Thu, 28 Dec 2023 09:38:13 +0800 From: Zhihao Cheng To: , , , , CC: , Subject: [PATCH RFC 13/17] ubifs: repair: Build LPT Date: Thu, 28 Dec 2023 09:41:08 +0800 Message-ID: <20231228014112.2836317-14-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20231228014112.2836317-1-chengzhihao1@huawei.com> References: <20231228014112.2836317-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 kwepemm000013.china.huawei.com (7.193.23.81) This is the 11/13 step of repairing. All LEBs' properties can be calculated in previous steps according to all nodes' position, then construct LPT just like mkfs does, and write TNC on flash. Signed-off-by: Zhihao Cheng --- fs/ubifs/repair.c | 113 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 20 deletions(-) diff --git a/fs/ubifs/repair.c b/fs/ubifs/repair.c index 724f58510599..8d40cff26f7a 100644 --- a/fs/ubifs/repair.c +++ b/fs/ubifs/repair.c @@ -1059,6 +1059,21 @@ lookup_valid_dent_node(struct ubifs_info *c, struct scanned_info *si, return NULL; } +static void update_lpt(struct ubifs_info *c, struct scanned_node *sn, + bool deleted) +{ + int lnum = sn->lnum - c->main_first; + int pos = sn->offs + ALIGN(sn->len, 8); + + set_bit(lnum, c->repair->used_lebs); + c->repair->lpts[lnum].end = max(c->repair->lpts[lnum].end, pos); + + if (deleted) + return; + + c->repair->lpts[lnum].used += ALIGN(sn->len, 8); +} + /** * remove_del_nodes - remove deleted nodes from valid node tree. * @c: UBIFS file-system description object @@ -1083,13 +1098,7 @@ static void remove_del_nodes(struct ubifs_info *c, struct scanned_info *si) valid_ino_node = lookup_valid_ino_node(c, si, del_ino_node); if (valid_ino_node) { - int lnum = del_ino_node->header.lnum - c->main_first; - int pos = del_ino_node->header.offs + - ALIGN(del_ino_node->header.len, 8); - - set_bit(lnum, c->repair->used_lebs); - c->repair->lpts[lnum].end = - max(c->repair->lpts[lnum].end, pos); + update_lpt(c, &del_ino_node->header, true); rb_erase(&valid_ino_node->rb, &si->valid_inos); kfree(valid_ino_node); } @@ -1106,13 +1115,7 @@ static void remove_del_nodes(struct ubifs_info *c, struct scanned_info *si) valid_dent_node = lookup_valid_dent_node(c, si, del_dent_node); if (valid_dent_node) { - int lnum = del_dent_node->header.lnum - c->main_first; - int pos = del_dent_node->header.offs + - ALIGN(del_dent_node->header.len, 8); - - set_bit(lnum, c->repair->used_lebs); - c->repair->lpts[lnum].end = - max(c->repair->lpts[lnum].end, pos); + update_lpt(c, &del_dent_node->header, true); rb_erase(&valid_dent_node->rb, &si->valid_dents); kfree(valid_dent_node); } @@ -1861,6 +1864,14 @@ static int flush_write_buf(struct ubifs_info *c) if (err) return err; + if (c->repair->need_update_lpt) { + int lnum = c->repair->head_lnum - c->main_first; + + c->repair->lpts[lnum].free = c->leb_size - len; + c->repair->lpts[lnum].dirty = pad; + c->repair->lpts[lnum].flags = LPROPS_INDEX; + } + c->repair->head_lnum = -1; return 0; @@ -2001,14 +2012,9 @@ static int parse_node_info(struct ubifs_info *c, struct scanned_node *sn, union ubifs_key *key, char *name, int name_len, struct list_head *idx_list, int *idx_cnt) { - int lnum, pos; struct idx_entry *e; - lnum = sn->lnum - c->main_first; - pos = sn->offs + ALIGN(sn->len, 8); - - set_bit(lnum, c->repair->used_lebs); - c->repair->lpts[lnum].end = max(c->repair->lpts[lnum].end, pos); + update_lpt(c, sn, idx_cnt == NULL); if (idx_cnt == NULL) /* Skip truncation node. */ @@ -2085,6 +2091,7 @@ static int build_tnc(struct ubifs_info *c, struct list_head *lower_idxs, return -ENOMEM; list_sort(c, lower_idxs, cmp_idx); + c->repair->need_update_lpt = true; ubifs_assert(c, lower_cnt != 0); @@ -2156,6 +2163,7 @@ static int build_tnc(struct ubifs_info *c, struct list_head *lower_idxs, /* Flush the last index LEB */ err = flush_write_buf(c); + c->repair->need_update_lpt = false; out: list_for_each_entry_safe(e, tmp_e, lower_idxs, list) { @@ -2300,6 +2308,65 @@ static int traverse_files_and_nodes(struct ubifs_info *c) return err; } +/** + * build_lpt - construct LPT and write it into flash. + * @c: UBIFS file-system description object + * + * This function builds LPT according to @c->repair->lpts and writes LPT + * into flash. + */ +int build_lpt(struct ubifs_info *c) +{ + int i, len, free, dirty, err; + u8 hash_lpt[UBIFS_HASH_ARR_SZ]; + + /* Set gc lnum. */ + err = get_free_leb(c); + if (err) + return err; + c->gc_lnum = c->repair->head_lnum; + /* GC LEB is empty. */ + c->lst.empty_lebs = 1; + + /* Update LPT. */ + for (i = 0; i < c->main_lebs; i++) { + cond_resched(); + + if (!test_bit(i, c->repair->used_lebs)) { + free = c->leb_size; + dirty = 0; + c->lst.empty_lebs++; + } else if (c->repair->lpts[i].flags & LPROPS_INDEX) { + free = c->repair->lpts[i].free; + dirty = c->repair->lpts[i].dirty; + c->lst.idx_lebs += 1; + } else { + len = ALIGN(c->repair->lpts[i].end, c->min_io_size); + free = c->leb_size - len; + dirty = len - c->repair->lpts[i].used; + } + + c->repair->lpts[i].free = free; + c->repair->lpts[i].dirty = dirty; + c->lst.total_free += free; + c->lst.total_dirty += dirty; + + if (!(c->repair->lpts[i].flags & LPROPS_INDEX)) { + int spc; + + spc = free + dirty; + if (spc < c->dead_wm) + c->lst.total_dead += spc; + else + c->lst.total_dark += ubifs_calc_dark(c, spc); + c->lst.total_used += c->leb_size - spc; + } + } + + /* Write LPT. */ + return ubifs_create_lpt(c, c->repair->lpts, c->main_lebs, hash_lpt); +} + static int do_repair(struct ubifs_info *c) { int err = 0; @@ -2343,6 +2410,12 @@ static int do_repair(struct ubifs_info *c) * Step 10: Build TNC. */ err = traverse_files_and_nodes(c); + if (err) + goto out; + + /* Step 11. Build LPT. */ + ubifs_msg(c, "Step 11: Build LPT"); + err = build_lpt(c); out: destroy_scanned_info(c, &si); -- 2.31.1