diff options
-rw-r--r-- | ubifs-utils/fsck.ubifs/check_files.c | 29 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.c | 8 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.h | 4 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/problem.c | 3 |
4 files changed, 43 insertions, 1 deletions
diff --git a/ubifs-utils/fsck.ubifs/check_files.c b/ubifs-utils/fsck.ubifs/check_files.c index b9f31a7..1e1a77b 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 80205aa..b97c8e3 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 ab498ad..fb7ccca 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 32182c9..8e7e1e1 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?"; |