@@ -9030,6 +9030,8 @@ int cmd_check(int argc, char **argv)
int init_csum_tree = 0;
int qgroup_report = 0;
enum btrfs_open_ctree_flags ctree_flags = OPEN_CTREE_EXCLUSIVE;
+ u16 root_corrupted = 0;
+ int in_recheck = 0;
while(1) {
int c;
@@ -9075,12 +9077,14 @@ int cmd_check(int argc, char **argv)
printf("Creating a new CRC tree\n");
init_csum_tree = 1;
repair = 1;
+ in_recheck = 1;
ctree_flags |= OPEN_CTREE_WRITES;
} else if (option_index == 3) {
init_extent_tree = 1;
ctree_flags |= (OPEN_CTREE_WRITES |
OPEN_CTREE_NO_BLOCK_GROUPS);
repair = 1;
+ in_recheck = 1;
} else if (option_index == 4) {
check_data_csum = 1;
}
@@ -9106,6 +9110,7 @@ int cmd_check(int argc, char **argv)
if (repair)
ctree_flags |= OPEN_CTREE_PARTIAL;
+again:
info = open_ctree_fs_info(argv[optind], bytenr, tree_root_bytenr,
ctree_flags);
if (!info) {
@@ -9218,7 +9223,21 @@ int cmd_check(int argc, char **argv)
* chunk and extent tree check has iterates all the extents,
* so know we have a brief view on which trees are damaged.
*/
- report_root_corrupted(info, "\t");
+ root_corrupted = report_root_corrupted(info, "\t");
+ if (repair && !in_recheck && (root_corrupted == CORRUPTED_CSUM ||
+ root_corrupted == CORRUPTED_EXTENT)) {
+ in_recheck = 1;
+ if (root_corrupted == CORRUPTED_CSUM) {
+ init_csum_tree = 1;
+ printf("Only csum tree is corrupted, rebuild it\n");
+ }
+ if (root_corrupted == CORRUPTED_EXTENT) {
+ init_extent_tree = 1;
+ printf("Only extent tree is corrupted, rebuild it\n");
+ }
+ close_ctree(root);
+ goto again;
+ }
ret = repair_root_items(info);
if (ret < 0)
goto close_out;
If we find other tree has no corrupted/missing extent, we should be safely to rebuild csum/extent tree. This patch will automatically do it using the report_root_corrtuped() result. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> --- cmds-check.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)