diff mbox series

[mtd-utils,v2,RESEND,085/102] fsck.ubifs: Check and create the root dir

Message ID 20241111090832.2093596-16-chengzhihao1@huawei.com
State Accepted
Delegated to: David Oberhollenzer
Headers show
Series Add fsck.ubifs support | expand

Commit Message

Zhihao Cheng Nov. 11, 2024, 9:08 a.m. UTC
This is the 15/18 step of fsck. Check whether the root dir is existed,
create a new one if it is not found. This step makes sure that filesystem
can be mounted successful.

Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
---
 ubifs-utils/fsck.ubifs/check_files.c | 29 +++++++++++++++++++++++++++++
 ubifs-utils/fsck.ubifs/fsck.ubifs.c  |  8 ++++++++
 ubifs-utils/fsck.ubifs/fsck.ubifs.h  |  4 +++-
 ubifs-utils/fsck.ubifs/problem.c     |  3 +++
 4 files changed, 43 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/ubifs-utils/fsck.ubifs/check_files.c b/ubifs-utils/fsck.ubifs/check_files.c
index b9f31a7a..1e1a77b4 100644
--- a/ubifs-utils/fsck.ubifs/check_files.c
+++ b/ubifs-utils/fsck.ubifs/check_files.c
@@ -524,3 +524,32 @@  bool tnc_is_empty(struct ubifs_info *c)
 	 */
 	return c->zroot.znode->child_cnt == 0;
 }
+
+/**
+ * check_and_create_root - Check and create root dir.
+ * @c: UBIFS file-system description object
+ *
+ * This function checks whether the root dir is existed, create a new root
+ * dir if it doesn't exist. Returns zero in case of success, a negative error
+ * code in case of failure.
+ */
+int check_and_create_root(struct ubifs_info *c)
+{
+	int err;
+	struct ubifs_inode *ui = ubifs_lookup_by_inum(c, UBIFS_ROOT_INO);
+
+	if (!IS_ERR(ui)) {
+		/* The root dir is found. */
+		dbg_fsck("root dir is found, in %s", c->dev_name);
+		kfree(ui);
+		return 0;
+	}
+
+	err = PTR_ERR(ui);
+	if (err != -ENOENT)
+		return err;
+
+	fix_problem(c, ROOT_DIR_NOT_FOUND, NULL);
+	dbg_fsck("root dir is lost, create a new one, in %s", c->dev_name);
+	return ubifs_create_root(c);
+}
diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.c b/ubifs-utils/fsck.ubifs/fsck.ubifs.c
index 80205aac..b97c8e3b 100644
--- a/ubifs-utils/fsck.ubifs/fsck.ubifs.c
+++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.c
@@ -519,6 +519,13 @@  static int do_fsck(void)
 
 	log_out(c, "Check and correct the index size");
 	err = check_and_correct_index_size(c);
+	if (err) {
+		exit_code |= FSCK_ERROR;
+		goto free_disconnected_files_2;
+	}
+
+	log_out(c, "Check and create root dir");
+	err = check_and_create_root(c);
 	if (err)
 		exit_code |= FSCK_ERROR;
 
@@ -575,6 +582,7 @@  int main(int argc, char *argv[])
 	 * Step 12: Check and correct the space statistics
 	 * Step 13: Commit problem fixing modifications
 	 * Step 14: Check and correct the index size
+	 * Step 15: Check and create root dir
 	 */
 	err = do_fsck();
 	if (err && FSCK(c)->try_rebuild) {
diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.h b/ubifs-utils/fsck.ubifs/fsck.ubifs.h
index ab498ad1..fb7ccca0 100644
--- a/ubifs-utils/fsck.ubifs/fsck.ubifs.h
+++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.h
@@ -45,7 +45,8 @@  enum { SB_CORRUPTED = 0, MST_CORRUPTED, LOG_CORRUPTED, BUD_CORRUPTED,
        XATTR_HAS_WRONG_HOST, FILE_HAS_NO_ENCRYPT, FILE_IS_DISCONNECTED,
        FILE_ROOT_HAS_DENT, DENTRY_IS_UNREACHABLE, FILE_IS_INCONSISTENT,
        EMPTY_TNC, LPT_CORRUPTED, NNODE_INCORRECT, PNODE_INCORRECT,
-       LP_INCORRECT, SPACE_STAT_INCORRECT, LTAB_INCORRECT, INCORRECT_IDX_SZ };
+       LP_INCORRECT, SPACE_STAT_INCORRECT, LTAB_INCORRECT, INCORRECT_IDX_SZ,
+       ROOT_DIR_NOT_FOUND };
 
 enum { HAS_DATA_CORRUPTED = 1, HAS_TNC_CORRUPTED = 2 };
 
@@ -373,6 +374,7 @@  void update_files_size(struct ubifs_info *c);
 int handle_invalid_files(struct ubifs_info *c);
 int handle_dentry_tree(struct ubifs_info *c);
 bool tnc_is_empty(struct ubifs_info *c);
+int check_and_create_root(struct ubifs_info *c);
 
 /* check_space.c */
 int get_free_leb(struct ubifs_info *c);
diff --git a/ubifs-utils/fsck.ubifs/problem.c b/ubifs-utils/fsck.ubifs/problem.c
index 32182c91..8e7e1e15 100644
--- a/ubifs-utils/fsck.ubifs/problem.c
+++ b/ubifs-utils/fsck.ubifs/problem.c
@@ -68,6 +68,7 @@  static const struct fsck_problem problem_table[] = {
 	{PROBLEM_FIXABLE | PROBLEM_MUST_FIX, "Incorrect space statistics"},	// SPACE_STAT_INCORRECT
 	{PROBLEM_FIXABLE | PROBLEM_MUST_FIX, "Inconsistent properties for lprops table"},	// LTAB_INCORRECT
 	{PROBLEM_FIXABLE | PROBLEM_MUST_FIX, "Incorrect index size"},	// INCORRECT_IDX_SZ
+	{PROBLEM_FIXABLE | PROBLEM_MUST_FIX, "Root dir is lost"},	// ROOT_DIR_NOT_FOUND
 };
 
 static const char *get_question(const struct fsck_problem *problem,
@@ -105,6 +106,8 @@  static const char *get_question(const struct fsck_problem *problem,
 		return "Put it into disconnected list?";
 	case LPT_CORRUPTED:
 		return "Rebuild LPT?";
+	case ROOT_DIR_NOT_FOUND:
+		return "Create a new one?";
 	}
 
 	return "Fix it?";