From nobody Tue Dec 23 14:14:38 2025 Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) (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 63ACD4695 for ; Thu, 28 Dec 2023 01:38:14 +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.163.17]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4T0rjn326qz1wq13; Thu, 28 Dec 2023 09:37:49 +0800 (CST) Received: from kwepemm000013.china.huawei.com (unknown [7.193.23.81]) by mail.maildlp.com (Postfix) with ESMTPS id 3DD651A0173; Thu, 28 Dec 2023 09:38:12 +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:11 +0800 From: Zhihao Cheng To: , , , , CC: , Subject: [PATCH RFC 09/17] ubifs: repair: Re-write data Date: Thu, 28 Dec 2023 09:41:04 +0800 Message-ID: <20231228014112.2836317-10-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: quoted-printable X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm000013.china.huawei.com (7.193.23.81) Content-Type: text/plain; charset="utf-8" This is the 9/13 step of repairing. Re-write data. Read data from LEB and write back data, make sure that all LEB is ended with empty data(0xFF). It will prevent failed gc scanning in next mounting. Signed-off-by: Zhihao Cheng --- fs/ubifs/repair.c | 117 ++++++++++++++++++++++++++++++++++++---------- fs/ubifs/repair.h | 11 +++++ 2 files changed, 104 insertions(+), 24 deletions(-) diff --git a/fs/ubifs/repair.c b/fs/ubifs/repair.c index 7d97de6219fa..59b79481974a 100644 --- a/fs/ubifs/repair.c +++ b/fs/ubifs/repair.c @@ -32,6 +32,8 @@ struct scanned_info { =20 static int init_repair_info(struct ubifs_info *c) { + int err; + c->repair =3D kzalloc(sizeof(struct ubifs_repair_info), GFP_KERNEL); if (!c->repair) return -ENOMEM; @@ -39,15 +41,28 @@ static int init_repair_info(struct ubifs_info *c) c->repair->scanned_files =3D RB_ROOT; c->repair->used_lebs =3D bitmap_zalloc(c->main_lebs, GFP_KERNEL); if (!c->repair->used_lebs) { - kfree(c->repair); - return -ENOMEM; + err =3D -ENOMEM; + goto free_repair; + } + c->repair->lpts =3D kzalloc(sizeof(struct lprops) * c->main_lebs, + GFP_KERNEL); + if (!c->repair->lpts) { + err =3D -ENOMEM; + goto free_used_lebs; } =20 return 0; + +free_used_lebs: + bitmap_free(c->repair->used_lebs); +free_repair: + kfree(c->repair); + return err; } =20 static void destroy_repair_info(struct ubifs_info *c) { + kfree(c->repair->lpts); bitmap_free(c->repair->used_lebs); kfree(c->repair); } @@ -1026,9 +1041,13 @@ static void remove_del_nodes(struct ubifs_info *c, s= truct scanned_info *si) =20 valid_ino_node =3D lookup_valid_ino_node(c, si, del_ino_node); if (valid_ino_node) { - int lnum =3D del_ino_node->header.lnum; + int lnum =3D del_ino_node->header.lnum - c->main_first; + int pos =3D del_ino_node->header.offs + + ALIGN(del_ino_node->header.len, 8); =20 - set_bit(lnum - c->main_first, c->repair->used_lebs); + set_bit(lnum, c->repair->used_lebs); + c->repair->lpts[lnum].end =3D + max(c->repair->lpts[lnum].end, pos); rb_erase(&valid_ino_node->rb, &si->valid_inos); kfree(valid_ino_node); } @@ -1045,9 +1064,13 @@ static void remove_del_nodes(struct ubifs_info *c, s= truct scanned_info *si) =20 valid_dent_node =3D lookup_valid_dent_node(c, si, del_dent_node); if (valid_dent_node) { - int lnum =3D del_dent_node->header.lnum; + int lnum =3D del_dent_node->header.lnum - c->main_first; + int pos =3D del_dent_node->header.offs + + ALIGN(del_dent_node->header.len, 8); =20 - set_bit(lnum - c->main_first, c->repair->used_lebs); + set_bit(lnum, c->repair->used_lebs); + c->repair->lpts[lnum].end =3D + max(c->repair->lpts[lnum].end, pos); rb_erase(&valid_dent_node->rb, &si->valid_dents); kfree(valid_dent_node); } @@ -1746,21 +1769,37 @@ static char *get_file_name(struct ubifs_info *c, st= ruct scanned_file *file) return name; } =20 +static void parse_node_location(struct ubifs_info *c, struct scanned_node = *sn) +{ + int lnum, pos; + + lnum =3D sn->lnum - c->main_first; + pos =3D sn->offs + ALIGN(sn->len, 8); + + set_bit(lnum, c->repair->used_lebs); + c->repair->lpts[lnum].end =3D max(c->repair->lpts[lnum].end, pos); +} + /** - * record_used_lebs - record used LEBs. + * traverse_files_and_nodes - traverse all nodes from valid files. * @c: UBIFS file-system description object * - * This function records all used LEBs which may hold useful nodes, then l= eft - * unused LEBs could be taken for storing new index tree. + * This function traverses all nodes from valid files and does following + * things: + * 1. Record all used LEBs which may hold useful nodes, then left unused + * LEBs could be taken for storing new index tree. + * 2. Re-write data to prevent failed gc scanning in the subsequent mounti= ng + * process caused by corrupted data. */ -static void record_used_lebs(struct ubifs_info *c) +static int traverse_files_and_nodes(struct ubifs_info *c) { - int lnum; + int i, err =3D 0; struct rb_node *node, *n; struct scanned_file *file; struct scanned_dent_node *dent_node; struct scanned_data_node *data_node; =20 + ubifs_msg(c, "Step 8: Record used LEBs"); for (node =3D rb_first(&c->repair->scanned_files); node; node =3D rb_next(node)) { cond_resched(); @@ -1772,30 +1811,58 @@ static void record_used_lebs(struct ubifs_info *c) ubifs_get_type_name(ubifs_get_dent_type(file->ino.mode)), c->vi.ubi_num, c->vi.vol_id); =20 - lnum =3D file->ino.header.lnum; - set_bit(lnum - c->main_first, c->repair->used_lebs); + parse_node_location(c, &file->ino.header); =20 - if (file->trun.header.exist) { - lnum =3D file->trun.header.lnum; - set_bit(lnum - c->main_first, c->repair->used_lebs); - } + if (file->trun.header.exist) + parse_node_location(c, &file->trun.header); =20 for (n =3D rb_first(&file->data_nodes); n; n =3D rb_next(n)) { cond_resched(); data_node =3D rb_entry(n, struct scanned_data_node, rb); =20 - lnum =3D data_node->header.lnum; - set_bit(lnum - c->main_first, c->repair->used_lebs); + parse_node_location(c, &data_node->header); } =20 for (n =3D rb_first(&file->dent_nodes); n; n =3D rb_next(n)) { cond_resched(); dent_node =3D rb_entry(n, struct scanned_dent_node, rb); =20 - lnum =3D dent_node->header.lnum; - set_bit(lnum - c->main_first, c->repair->used_lebs); + parse_node_location(c, &dent_node->header); } } + + /* Re-write data. */ + ubifs_msg(c, "Step 9: Re-write data"); + for (i =3D 0; i < c->main_lebs; ++i) { + int lnum, len, end; + + if (fatal_signal_pending(current)) + return -EINTR; + cond_resched(); + + if (!test_bit(i, c->repair->used_lebs)) + continue; + + lnum =3D i + c->main_first; + dbg_repair("re-write LEB %d, in ubi%d_%d", + lnum, c->vi.ubi_num, c->vi.vol_id); + + end =3D c->repair->lpts[i].end; + len =3D ALIGN(end, c->min_io_size); + + err =3D ubifs_leb_read(c, lnum, c->sbuf, 0, len, 0); + if (err && err !=3D -EBADMSG) + return err; + + if (len > end) + ubifs_pad(c, c->sbuf + end, len - end); + + err =3D ubifs_leb_change(c, lnum, c->sbuf, len); + if (err) + return err; + } + + return err; } =20 static int do_repair(struct ubifs_info *c) @@ -1835,9 +1902,11 @@ static int do_repair(struct ubifs_info *c) if (err) goto out; =20 - /* Step 8: Record used LEBs. */ - ubifs_msg(c, "Step 8: Record used LEBs"); - record_used_lebs(c); + /* + * Step 8: Record used LEBs. + * Step 9: Re-write data to clean corrupted data. + */ + err =3D traverse_files_and_nodes(c); =20 out: destroy_scanned_info(c, &si); diff --git a/fs/ubifs/repair.h b/fs/ubifs/repair.h index fecf437ff0f7..2ab885fefee0 100644 --- a/fs/ubifs/repair.h +++ b/fs/ubifs/repair.h @@ -151,13 +151,24 @@ struct scanned_file { struct rb_root data_nodes; }; =20 + +/** + * lprops - logical eraseblock properties. + * @end: the end postition of LEB calculated by the last node + */ +struct lprops { + int end; +}; + /** * ubifs_repair_info - per-FS repairing information. * @usen_lebs: a bitmap used for recording used lebs + * @lpts: lprops table * @scanned_files: tree of all scanned files */ struct ubifs_repair_info { unsigned long *used_lebs; + struct lprops *lpts; struct rb_root scanned_files; }; =20 --=20 2.31.1