diff options
Diffstat (limited to 'ubifs-utils/fsck.ubifs')
-rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.c | 2 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.h | 2 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/load_fs.c | 19 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/problem.c | 20 |
4 files changed, 40 insertions, 3 deletions
diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.c b/ubifs-utils/fsck.ubifs/fsck.ubifs.c index 85175cf..31c2aa6 100644 --- a/ubifs-utils/fsck.ubifs/fsck.ubifs.c +++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.c @@ -328,6 +328,7 @@ static bool fsck_can_ignore_failure(const struct ubifs_info *c, static const unsigned int reason_mapping_table[] = { BUD_CORRUPTED, /* FR_H_BUD_CORRUPTED */ TNC_DATA_CORRUPTED, /* FR_H_TNC_DATA_CORRUPTED */ + ORPHAN_CORRUPTED, /* FR_H_ORPHAN_CORRUPTED */ }; static bool fsck_handle_failure(const struct ubifs_info *c, unsigned int reason, @@ -431,6 +432,7 @@ int main(int argc, char *argv[]) * Init: Read superblock * Step 1: Read master & init lpt * Step 2: Replay journal + * Step 3: Handle orphan nodes */ err = ubifs_load_filesystem(c); if (err) { diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.h b/ubifs-utils/fsck.ubifs/fsck.ubifs.h index f1da974..a1c64e3 100644 --- a/ubifs-utils/fsck.ubifs/fsck.ubifs.h +++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.h @@ -38,7 +38,7 @@ enum { NORMAL_MODE = 0, SAFE_MODE, DANGER_MODE0, /* Types of inconsistent problems */ enum { SB_CORRUPTED = 0, MST_CORRUPTED, LOG_CORRUPTED, BUD_CORRUPTED, - TNC_CORRUPTED, TNC_DATA_CORRUPTED }; + TNC_CORRUPTED, TNC_DATA_CORRUPTED, ORPHAN_CORRUPTED }; struct scanned_file; diff --git a/ubifs-utils/fsck.ubifs/load_fs.c b/ubifs-utils/fsck.ubifs/load_fs.c index f45c411..f376383 100644 --- a/ubifs-utils/fsck.ubifs/load_fs.c +++ b/ubifs-utils/fsck.ubifs/load_fs.c @@ -183,10 +183,28 @@ int ubifs_load_filesystem(struct ubifs_info *c) /* Calculate 'min_idx_lebs' after journal replay */ c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c); + log_out(c, "Handle orphan nodes"); + err = ubifs_mount_orphans(c, c->need_recovery, c->ro_mount); + if (err) { + unsigned int reason = get_failure_reason_callback(c); + + clear_failure_reason_callback(c); + if (reason & FR_TNC_CORRUPTED) { + if (fix_problem(c, TNC_CORRUPTED, NULL)) + FSCK(c)->try_rebuild = true; + } else { + ubifs_assert(c, reason == 0); + exit_code |= FSCK_ERROR; + } + goto out_orphans; + } + c->mounting = 0; return 0; +out_orphans: + free_orphans(c); out_journal: destroy_journal(c); out_lpt: @@ -214,6 +232,7 @@ void ubifs_destroy_filesystem(struct ubifs_info *c) { destroy_journal(c); free_wbufs(c); + free_orphans(c); ubifs_lpt_free(c, 0); c->max_sqnum = 0; diff --git a/ubifs-utils/fsck.ubifs/problem.c b/ubifs-utils/fsck.ubifs/problem.c index 9df2c2a..9c8730a 100644 --- a/ubifs-utils/fsck.ubifs/problem.c +++ b/ubifs-utils/fsck.ubifs/problem.c @@ -41,6 +41,7 @@ static const struct fsck_problem problem_table[] = { {PROBLEM_FIXABLE | PROBLEM_MUST_FIX | PROBLEM_DROP_DATA, "Corrupted bud LEB"}, // BUD_CORRUPTED {PROBLEM_FIXABLE | PROBLEM_MUST_FIX | PROBLEM_DROP_DATA | PROBLEM_NEED_REBUILD, "Corrupted index node"}, // TNC_CORRUPTED {PROBLEM_FIXABLE | PROBLEM_MUST_FIX | PROBLEM_DROP_DATA, "Corrupted data searched from TNC"}, // TNC_DATA_CORRUPTED + {PROBLEM_FIXABLE | PROBLEM_MUST_FIX | PROBLEM_DROP_DATA, "Corrupted orphan LEB"}, // ORPHAN_CORRUPTED }; static const char *get_question(const struct fsck_problem *problem, @@ -54,6 +55,8 @@ static const char *get_question(const struct fsck_problem *problem, return "Drop bud?"; case TNC_DATA_CORRUPTED: return "Drop it?"; + case ORPHAN_CORRUPTED: + return "Drop orphans on the LEB?"; } return "Fix it?"; @@ -63,13 +66,26 @@ static void print_problem(const struct ubifs_info *c, const struct fsck_problem *problem, int problem_type, const void *priv) { - if (problem_type == BUD_CORRUPTED) { + switch (problem_type) { + case BUD_CORRUPTED: + { const struct ubifs_bud *bud = (const struct ubifs_bud *)priv; log_out(c, "problem: %s %d:%d %s", problem->desc, bud->lnum, bud->start, dbg_jhead(bud->jhead)); - } else + break; + } + case ORPHAN_CORRUPTED: + { + const int *lnum = (const int *)priv; + + log_out(c, "problem: %s %d", problem->desc, *lnum); + break; + } + default: log_out(c, "problem: %s", problem->desc); + break; + } } static void fatal_error(const struct ubifs_info *c, |