diff --git a/thin-provisioning/metadata_checker.cc b/thin-provisioning/metadata_checker.cc index 95f8179..b3e05c1 100644 --- a/thin-provisioning/metadata_checker.cc +++ b/thin-provisioning/metadata_checker.cc @@ -16,6 +16,7 @@ // with thin-provisioning-tools. If not, see // . +#include "base/error_state.h" #include "base/nested_output.h" #include "persistent-data/file_utils.h" #include "persistent-data/space-maps/core.h" @@ -437,8 +438,30 @@ namespace { return true; } - error_state get_error() const { - return err_; + bool clear_needs_check_flag() { + if (!verify_preconditions_before_fixing()) { + out_ << "metadata has not been fully examined" << end_message(); + return false; + } + + if (err_ != NO_ERROR) + return false; + + block_manager::ptr bm = open_bm(path_, block_manager::READ_WRITE); + superblock_detail::superblock sb = read_superblock(bm); + sb.set_needs_check_flag(false); + write_superblock(bm, sb); + + out_ << "cleared needs_check flag" << end_message(); + + return true; + } + + bool get_status() const { + if (options_.ignore_non_fatal_) + return (err_ == FATAL) ? false : true; + + return (err_ == NO_ERROR) ? true : false; } private: @@ -529,7 +552,8 @@ check_options::check_options() data_mapping_opts_(DATA_MAPPING_LEVEL2), sm_opts_(SPACE_MAP_FULL), ignore_non_fatal_(false), - fix_metadata_leaks_(false) { + fix_metadata_leaks_(false), + clear_needs_check_(false) { } void check_options::set_superblock_only() { @@ -559,8 +583,12 @@ void check_options::set_fix_metadata_leaks() { fix_metadata_leaks_ = true; } +void check_options::set_clear_needs_check() { + clear_needs_check_ = true; +} + bool check_options::check_conformance() { - if (fix_metadata_leaks_) { + if (fix_metadata_leaks_ || clear_needs_check_) { if (ignore_non_fatal_) { cerr << "cannot perform fix by ignoring non-fatal errors" << endl; return false; @@ -588,7 +616,7 @@ bool check_options::check_conformance() { //---------------------------------------------------------------- -base::error_state +bool thin_provisioning::check_metadata(std::string const &path, check_options const &check_opts, output_options output_opts) @@ -598,8 +626,11 @@ thin_provisioning::check_metadata(std::string const &path, checker.check(); if (check_opts.fix_metadata_leaks_) checker.fix_metadata_leaks(); + if (check_opts.fix_metadata_leaks_ || + check_opts.clear_needs_check_) + checker.clear_needs_check_flag(); - return checker.get_error(); + return checker.get_status(); } //---------------------------------------------------------------- diff --git a/thin-provisioning/metadata_checker.h b/thin-provisioning/metadata_checker.h index 001b4f1..2871932 100644 --- a/thin-provisioning/metadata_checker.h +++ b/thin-provisioning/metadata_checker.h @@ -19,7 +19,6 @@ #ifndef METADATA_CHECKER_H #define METADATA_CHECKER_H -#include "base/error_state.h" #include "block-cache/block_cache.h" #include "persistent-data/block.h" @@ -47,6 +46,7 @@ namespace thin_provisioning { void set_metadata_snap(); void set_ignore_non_fatal(); void set_fix_metadata_leaks(); + void set_clear_needs_check(); bool use_metadata_snap_; data_mapping_options data_mapping_opts_; @@ -54,6 +54,7 @@ namespace thin_provisioning { boost::optional override_mapping_root_; bool ignore_non_fatal_; bool fix_metadata_leaks_; + bool clear_needs_check_; }; enum output_options { @@ -61,7 +62,7 @@ namespace thin_provisioning { OUTPUT_QUIET, }; - base::error_state + bool check_metadata(std::string const &path, check_options const &check_opts, output_options output_opts); diff --git a/thin-provisioning/thin_check.cc b/thin-provisioning/thin_check.cc index bd69b11..3a4ef4b 100644 --- a/thin-provisioning/thin_check.cc +++ b/thin-provisioning/thin_check.cc @@ -43,27 +43,13 @@ using namespace thin_provisioning; namespace { struct flags { flags() - : ignore_non_fatal_errors(false), - quiet(false), - clear_needs_check_flag_on_success(false) { + : quiet(false) { } check_options check_opts; - - bool ignore_non_fatal_errors; - bool quiet; - bool clear_needs_check_flag_on_success; }; - void clear_needs_check(string const &path) { - block_manager::ptr bm = open_bm(path, block_manager::READ_WRITE); - - superblock_detail::superblock sb = read_superblock(bm); - sb.set_needs_check_flag(false); - write_superblock(bm, sb); - } - // Returns 0 on success, 1 on failure (this gets returned directly // by main). int check(string const &path, flags fs) { @@ -77,15 +63,7 @@ namespace { } output_options output_opts = !fs.quiet ? OUTPUT_NORMAL : OUTPUT_QUIET; - error_state err = check_metadata(path, fs.check_opts, output_opts); - - if (fs.ignore_non_fatal_errors) - success = (err == FATAL) ? false : true; - else - success = (err == NO_ERROR) ? true : false; - - if (success && fs.clear_needs_check_flag_on_success) - clear_needs_check(path); + success = check_metadata(path, fs.check_opts, output_opts); } catch (std::exception &e) { if (!fs.quiet) @@ -173,13 +151,12 @@ thin_check_cmd::run(int argc, char **argv) case 3: // ignore-non-fatal-errors - fs.ignore_non_fatal_errors = true; fs.check_opts.set_ignore_non_fatal(); break; case 4: // clear needs-check flag - fs.clear_needs_check_flag_on_success = true; + fs.check_opts.set_clear_needs_check(); break; case 5: @@ -198,12 +175,6 @@ 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." << endl; - usage(cerr); - exit(1); - } - if (!fs.check_opts.check_conformance()) { usage(cerr); exit(1);