From nobody Tue Dec 23 14:14:41 2025 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 C62A510E5 for ; Thu, 28 Dec 2023 01:38:09 +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.44]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4T0rdg1m7jz1FGL4; Thu, 28 Dec 2023 09:34:15 +0800 (CST) Received: from kwepemm000013.china.huawei.com (unknown [7.193.23.81]) by mail.maildlp.com (Postfix) with ESMTPS id 2A137140120; Thu, 28 Dec 2023 09:38:07 +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:06 +0800 From: Zhihao Cheng To: , , , , CC: , Subject: [PATCH RFC 01/17] ubifs: repair: Load filesystem info from volume Date: Thu, 28 Dec 2023 09:40:56 +0800 Message-ID: <20231228014112.2836317-2-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 1/13 step of repairing. Open UBI volume and read UBIFS super block, which is similar to UBIFS mounting process. If read superblock failed, repair is failure. Signed-off-by: Zhihao Cheng --- fs/ubifs/Makefile | 2 +- fs/ubifs/repair.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++ fs/ubifs/super.c | 10 ++--- fs/ubifs/ubifs.h | 5 +++ 4 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 fs/ubifs/repair.c diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile index 314c80b24a76..88a11f85e150 100644 --- a/fs/ubifs/Makefile +++ b/fs/ubifs/Makefile @@ -5,7 +5,7 @@ ubifs-y +=3D shrinker.o journal.o file.o dir.o super.o sb.o= io.o ubifs-y +=3D tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o ubifs-y +=3D budget.o find.o tnc_commit.o compress.o lpt.o lprops.o ubifs-y +=3D recovery.o ioctl.o lpt_commit.o tnc_misc.o debug.o -ubifs-y +=3D misc.o sysfs.o +ubifs-y +=3D misc.o sysfs.o repair.o ubifs-$(CONFIG_FS_ENCRYPTION) +=3D crypto.o ubifs-$(CONFIG_UBIFS_FS_XATTR) +=3D xattr.o ubifs-$(CONFIG_UBIFS_FS_AUTHENTICATION) +=3D auth.o diff --git a/fs/ubifs/repair.c b/fs/ubifs/repair.c new file mode 100644 index 000000000000..b722187de74f --- /dev/null +++ b/fs/ubifs/repair.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This file is part of UBIFS. + * + * Copyright (C) 2023-2024, Huawei Technologies Co, Ltd. + * + * Authors: Zhihao Cheng + */ + +/* + * This file implements ubifs repair. + */ + +#include +#include "ubifs.h" + +int ubifs_repair(const char *dev_name) +{ + int err =3D 0; + struct ubifs_info *c; + struct ubi_volume_desc *ubi; + struct super_block *fake_sb; + + ubi =3D open_ubi(dev_name, UBI_READWRITE); + if (IS_ERR(ubi)) { + err =3D PTR_ERR(ubi); + pr_err("cannot open dev %s, err %d\n", dev_name, err); + return err; + } + + fake_sb =3D kzalloc(sizeof(struct super_block), GFP_KERNEL); + if (!fake_sb) { + err =3D -ENOMEM; + goto close_volume; + } + + c =3D alloc_ubifs_info(ubi); + if (!c) { + err =3D -ENOMEM; + goto free_sb; + } + + c->ubi =3D ubi; + c->vfs_sb =3D fake_sb; + c->max_inode_sz =3D key_max_inode_size(c); + if (c->max_inode_sz > MAX_LFS_FILESIZE) + c->max_inode_sz =3D MAX_LFS_FILESIZE; + + err =3D init_constants_early(c); + if (err) + goto free_ubifs; + + err =3D ubifs_debugging_init(c); + if (err) + goto free_ubifs; + + if (c->ro_media) { + err =3D -EROFS; + goto free_debug; + } + + err =3D check_volume_empty(c); + if (err) + goto free_debug; + + if (c->empty) { + ubifs_err(c, "empty filesystem"); + err =3D -ENODEV; + goto free_debug; + } + + c->sbuf =3D vmalloc(c->leb_size); + if (!c->sbuf) { + err =3D -ENOMEM; + goto free_debug; + } + + /* Step 1: Load filesystem info from volume. */ + ubifs_msg(c, "Step 1: Load filesystem"); + err =3D ubifs_read_superblock(c); + if (err) + goto free_sup; + + /* TODO: Support repairing authenticated image. */ + if (le32_to_cpu(c->sup_node->flags) & UBIFS_FLG_AUTHENTICATION) { + ubifs_err(c, "not support authentication"); + err =3D -EOPNOTSUPP; + goto free_sup; + } + + err =3D init_constants_sb(c); + if (err) + goto free_sup; + + ubifs_msg(c, "Repair success!"); + +free_sup: + kfree(c->sup_node); + vfree(c->sbuf); +free_debug: + ubifs_debugging_exit(c); +free_ubifs: + kfree(c); +free_sb: + kfree(fake_sb); +close_volume: + ubi_close_volume(ubi); + return err; +} diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index eabb0f44ea3e..ad726523d491 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -506,7 +506,7 @@ static int ubifs_sync_fs(struct super_block *sb, int wa= it) * requirements. Returns zero in case of success and a negative error code= in * case of failure. */ -static int init_constants_early(struct ubifs_info *c) +int init_constants_early(struct ubifs_info *c) { if (c->vi.corrupted) { ubifs_warn(c, "UBI volume is corrupted - read-only mode"); @@ -670,7 +670,7 @@ static int bud_wbuf_callback(struct ubifs_info *c, int = lnum, int free, int pad) * makes sure they are all right. Returns zero in case of success and a * negative error code in case of failure. */ -static int init_constants_sb(struct ubifs_info *c) +int init_constants_sb(struct ubifs_info *c) { int tmp, err; long long tmp64; @@ -934,7 +934,7 @@ static void free_buds(struct ubifs_info *c) * Returns zero in case of success and a negative error code in case of * failure. */ -static int check_volume_empty(struct ubifs_info *c) +int check_volume_empty(struct ubifs_info *c) { int lnum, err; =20 @@ -2086,7 +2086,7 @@ const struct super_operations ubifs_super_operations = =3D { * returns UBI volume description object in case of success and a negative * error code in case of failure. */ -static struct ubi_volume_desc *open_ubi(const char *name, int mode) +struct ubi_volume_desc *open_ubi(const char *name, int mode) { struct ubi_volume_desc *ubi; int dev, vol; @@ -2132,7 +2132,7 @@ static struct ubi_volume_desc *open_ubi(const char *n= ame, int mode) return ERR_PTR(-EINVAL); } =20 -static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi) +struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi) { struct ubifs_info *c; =20 diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 3916dc4f30ca..a7ee8010ad66 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -2072,6 +2072,11 @@ static inline int ubifs_init_security(struct inode *= dentry, =20 /* super.c */ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); +int init_constants_early(struct ubifs_info *c); +int init_constants_sb(struct ubifs_info *c); +int check_volume_empty(struct ubifs_info *c); +struct ubi_volume_desc *open_ubi(const char *name, int mode); +struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi); =20 /* recovery.c */ int ubifs_recover_master_node(struct ubifs_info *c); --=20 2.31.1