[thin_check] Support fixing leaked metadata blocks

- The leaked blocks are defined as allocated but not used ones,
  i.e., expected ref-count == 0 and actual ref-count <= 2.
- Blocks with expected ref-count > 0, or actual ref-count > 2,
  are treated as unrepairable leaks.
- The fixing processing won't be executed if there's any
  unrepairable leak or errors.
- The fixing process implicitly clearing the superblock
  needs_check flag if there's no error.
This commit is contained in:
Ming-Hung Tsai
2020-07-14 17:57:29 +08:00
parent 7be6b91420
commit 49efa06ffa
3 changed files with 232 additions and 61 deletions

View File

@@ -76,10 +76,8 @@ namespace {
return 1;
}
block_manager::ptr bm = open_bm(path, block_manager::READ_ONLY,
!fs.check_opts.use_metadata_snap_);
output_options output_opts = !fs.quiet ? OUTPUT_NORMAL : OUTPUT_QUIET;
error_state err = check_metadata(bm, fs.check_opts, output_opts);
error_state err = check_metadata(path, fs.check_opts, output_opts);
if (fs.ignore_non_fatal_errors)
success = (err == FATAL) ? false : true;
@@ -116,6 +114,7 @@ thin_check_cmd::usage(std::ostream &out) const
<< " {-h|--help}\n"
<< " {-V|--version}\n"
<< " {-m|--metadata-snap}\n"
<< " {--fix-metadata-leaks}\n"
<< " {--override-mapping-root}\n"
<< " {--clear-needs-check-flag}\n"
<< " {--ignore-non-fatal-errors}\n"
@@ -140,6 +139,7 @@ thin_check_cmd::run(int argc, char **argv)
{ "ignore-non-fatal-errors", no_argument, NULL, 3},
{ "clear-needs-check-flag", no_argument, NULL, 4 },
{ "override-mapping-root", required_argument, NULL, 5},
{ "fix-metadata-leaks", no_argument, NULL, 6},
{ NULL, no_argument, NULL, 0 }
};
@@ -187,6 +187,11 @@ thin_check_cmd::run(int argc, char **argv)
fs.check_opts.set_override_mapping_root(boost::lexical_cast<uint64_t>(optarg));
break;
case 6:
// fix-metadata-leaks
fs.check_opts.set_fix_metadata_leaks();
break;
default:
usage(cerr);
return 1;
@@ -194,7 +199,12 @@ thin_check_cmd::run(int argc, char **argv)
}
if (fs.clear_needs_check_flag_on_success && fs.check_opts.use_metadata_snap_) {
cerr << "--metadata-snap cannot be combined with --clear-needs-check-flag.";
cerr << "--metadata-snap cannot be combined with --clear-needs-check-flag." << endl;
usage(cerr);
exit(1);
}
if (!fs.check_opts.check_conformance()) {
usage(cerr);
exit(1);
}