]> www.infradead.org Git - mtd-utils.git/commitdiff
fsck.ubifs: Check and create the root dir
authorZhihao Cheng <chengzhihao1@huawei.com>
Mon, 11 Nov 2024 09:08:13 +0000 (17:08 +0800)
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>
Mon, 11 Nov 2024 09:32:46 +0000 (10:32 +0100)
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>
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
ubifs-utils/fsck.ubifs/check_files.c
ubifs-utils/fsck.ubifs/fsck.ubifs.c
ubifs-utils/fsck.ubifs/fsck.ubifs.h
ubifs-utils/fsck.ubifs/problem.c

index b9f31a7aefc7c3e94211769e32e89427885f9878..1e1a77b4fd366a8846003fc3247d4e487e973f86 100644 (file)
@@ -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);
+}
index 80205aac5e5848a0bda05702d5d7a95d75c8d665..b97c8e3bc15520fe6f1b34f5a8d7915537344f23 100644 (file)
@@ -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) {
index ab498ad13a0e3002e0835618d844c8c93a1d6493..fb7ccca01f5d2243befd29ceba6bcf482f2278eb 100644 (file)
@@ -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);
index 32182c91e75474442e14a0cfe6386f485e803e23..8e7e1e158757919b9cff62f79c3af3949c659986 100644 (file)
@@ -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?";