diff options
Diffstat (limited to 'ubifs-utils')
| -rw-r--r-- | ubifs-utils/fsck.ubifs/check_files.c | 25 | ||||
| -rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.c | 7 | ||||
| -rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.h | 4 | ||||
| -rw-r--r-- | ubifs-utils/fsck.ubifs/problem.c | 1 | 
4 files changed, 36 insertions, 1 deletions
| diff --git a/ubifs-utils/fsck.ubifs/check_files.c b/ubifs-utils/fsck.ubifs/check_files.c index 2be9619..b9f31a7 100644 --- a/ubifs-utils/fsck.ubifs/check_files.c +++ b/ubifs-utils/fsck.ubifs/check_files.c @@ -499,3 +499,28 @@ int handle_dentry_tree(struct ubifs_info *c)  	return 0;  } + +/** + * tnc_is_empty - Check whether the TNC is empty. + * @c: UBIFS file-system description object + * + * Returns %true if the TNC is empty, otherwise %false is returned. + */ +bool tnc_is_empty(struct ubifs_info *c) +{ +	/* +	 * Check whether the TNC is empty, turn to rebuild_fs if it is empty. +	 * Can we recreate a new root dir to avoid empty TNC? The answer is no, +	 * lpt fixing should be done before creating new entry, but lpt fixing +	 * needs a committing before new dirty data generated to ensure that +	 * bud data won't be overwritten(bud LEB could become freeable after +	 * replaying journal, corrected lpt may treat it as a free one to hold +	 * new data, see details in space checking & correcting step). Then we +	 * have to create the new root dir after fixing lpt and a committing, +	 * znode without children(empty TNC) maybe written on disk at the +	 * moment of committing, which corrupts the UBIFS image. So we choose +	 * to rebuild the filesystem if the TNC is empty, this case is +	 * equivalent to corrupted TNC. +	 */ +	return c->zroot.znode->child_cnt == 0; +} diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.c b/ubifs-utils/fsck.ubifs/fsck.ubifs.c index 3f61668..cd498f5 100644 --- a/ubifs-utils/fsck.ubifs/fsck.ubifs.c +++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.c @@ -467,6 +467,12 @@ static int do_fsck(void)  		goto free_disconnected_files;  	} +	log_out(c, "Check whether the TNC is empty"); +	if (tnc_is_empty(c) && fix_problem(c, EMPTY_TNC, NULL)) { +		err = -EINVAL; +		FSCK(c)->try_rebuild = true; +	} +  free_disconnected_files:  	destroy_file_list(c, &FSCK(c)->disconnected_files);  free_used_lebs: @@ -512,6 +518,7 @@ int main(int argc, char *argv[])  	 * Step 8: Check and handle invalid files  	 * Step 9: Check and handle unreachable files  	 * Step 10: Check and correct files +	 * Step 11: Check whether the TNC is empty  	 */  	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 32a991d..3c0f2af 100644 --- a/ubifs-utils/fsck.ubifs/fsck.ubifs.h +++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.h @@ -43,7 +43,8 @@ enum { SB_CORRUPTED = 0, MST_CORRUPTED, LOG_CORRUPTED, BUD_CORRUPTED,         FILE_HAS_0_NLINK_INODE, FILE_HAS_INCONSIST_TYPE, FILE_HAS_TOO_MANY_DENT,         FILE_SHOULDNT_HAVE_DATA, FILE_HAS_NO_DENT, XATTR_HAS_NO_HOST,         XATTR_HAS_WRONG_HOST, FILE_HAS_NO_ENCRYPT, FILE_IS_DISCONNECTED, -       FILE_ROOT_HAS_DENT, DENTRY_IS_UNREACHABLE, FILE_IS_INCONSISTENT }; +       FILE_ROOT_HAS_DENT, DENTRY_IS_UNREACHABLE, FILE_IS_INCONSISTENT, +       EMPTY_TNC };  enum { HAS_DATA_CORRUPTED = 1, HAS_TNC_CORRUPTED = 2 }; @@ -318,5 +319,6 @@ int traverse_tnc_and_construct_files(struct ubifs_info *c);  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);  #endif diff --git a/ubifs-utils/fsck.ubifs/problem.c b/ubifs-utils/fsck.ubifs/problem.c index e8f0860..795f05f 100644 --- a/ubifs-utils/fsck.ubifs/problem.c +++ b/ubifs-utils/fsck.ubifs/problem.c @@ -60,6 +60,7 @@ static const struct fsck_problem problem_table[] = {  	{PROBLEM_FIXABLE | PROBLEM_MUST_FIX | PROBLEM_DROP_DATA, "Root dir should not have a dentry"},	// FILE_ROOT_HAS_DENT  	{PROBLEM_FIXABLE | PROBLEM_MUST_FIX | PROBLEM_DROP_DATA, "Dentry is unreachable"},	// DENTRY_IS_UNREACHABLE  	{PROBLEM_FIXABLE | PROBLEM_MUST_FIX, "File is inconsistent"},	// FILE_IS_INCONSISTENT +	{PROBLEM_FIXABLE | PROBLEM_MUST_FIX | PROBLEM_DROP_DATA | PROBLEM_NEED_REBUILD, "TNC is empty"},	// EMPTY_TNC  };  static const char *get_question(const struct fsck_problem *problem, | 
