diff --git a/caching/cache_check.cc b/caching/cache_check.cc index ba750d5..005159e 100644 --- a/caching/cache_check.cc +++ b/caching/cache_check.cc @@ -187,7 +187,8 @@ namespace { check_hints_(true), check_discards_(true), ignore_non_fatal_errors_(false), - quiet_(false) { + quiet_(false), + clear_needs_check_on_success_(false) { } bool check_mappings_; @@ -195,6 +196,7 @@ namespace { bool check_discards_; bool ignore_non_fatal_errors_; bool quiet_; + bool clear_needs_check_on_success_; }; struct stat guarded_stat(string const &path) { @@ -210,6 +212,14 @@ namespace { return info; } + void clear_needs_check(string const &path) { + block_manager<>::ptr bm = open_bm(path, block_manager<>::READ_WRITE); + + superblock sb = read_superblock(bm); + sb.flags.clear_flag(superblock_flags::NEEDS_CHECK); + write_superblock(bm, sb); + } + error_state metadata_check(block_manager<>::ptr bm, flags const &fs) { nested_output out(cerr, 2); if (fs.quiet_) @@ -288,6 +298,16 @@ namespace { block_manager<>::ptr bm = open_bm(path, block_manager<>::READ_ONLY); err = metadata_check(bm, fs); + bool success = false; + + if (fs.ignore_non_fatal_errors_) + success = (err == FATAL) ? false : true; + else + success = (err == NO_ERROR) ? true : false; + + if (success && fs.clear_needs_check_on_success_) + clear_needs_check(path); + return err == NO_ERROR ? 0 : 1; } @@ -312,6 +332,7 @@ namespace { << " {-q|--quiet}" << endl << " {-h|--help}" << endl << " {-V|--version}" << endl + << " {--clear-needs-check-flag}" << endl << " {--super-block-only}" << endl << " {--skip-mappings}" << endl << " {--skip-hints}" << endl @@ -332,6 +353,7 @@ int cache_check_main(int argc, char **argv) { "skip-mappings", no_argument, NULL, 2 }, { "skip-hints", no_argument, NULL, 3 }, { "skip-discards", no_argument, NULL, 4 }, + { "clear-needs-check-flag", no_argument, NULL, 5 }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { NULL, no_argument, NULL, 0 } @@ -356,6 +378,10 @@ int cache_check_main(int argc, char **argv) fs.check_discards_ = false; break; + case 5: + fs.clear_needs_check_on_success_ = true; + break; + case 'h': usage(cout, basename(argv[0])); return 0; diff --git a/caching/superblock.cc b/caching/superblock.cc index 4089eee..2edd6c1 100644 --- a/caching/superblock.cc +++ b/caching/superblock.cc @@ -74,6 +74,11 @@ superblock_flags::superblock_flags(uint32_t bits) bits &= ~(1 << CLEAN_SHUTDOWN_BIT); } + if (bits & (1u << NEEDS_CHECK_BIT)) { + flags_.insert(NEEDS_CHECK); + bits &= ~(1u << NEEDS_CHECK_BIT); + } + unhandled_flags_ = bits; } @@ -103,6 +108,9 @@ superblock_flags::encode() const if (get_flag(CLEAN_SHUTDOWN)) r = r | (1 << CLEAN_SHUTDOWN_BIT); + if (get_flag(NEEDS_CHECK)) + r = r | (1u << NEEDS_CHECK_BIT); + return r; } diff --git a/caching/superblock.h b/caching/superblock.h index b59365a..fdac263 100644 --- a/caching/superblock.h +++ b/caching/superblock.h @@ -19,11 +19,13 @@ namespace caching { class superblock_flags { public: enum flag { - CLEAN_SHUTDOWN + CLEAN_SHUTDOWN, + NEEDS_CHECK }; enum flag_bits { - CLEAN_SHUTDOWN_BIT = 0 + CLEAN_SHUTDOWN_BIT = 0, + NEEDS_CHECK_BIT = 1, }; superblock_flags(); diff --git a/features/cache_check.feature b/features/cache_check.feature index a47274c..7efbd40 100644 --- a/features/cache_check.feature +++ b/features/cache_check.feature @@ -93,3 +93,8 @@ Feature: cache_check And I run cache_restore with -i metadata.xml -o input --debug-override-metadata-version 12345 When I run `cache_check input` Then it should fail + + Scenario: Accepts --clear-needs-check-flag + Given valid cache metadata + When I run `cache_check --clear-needs-check-flag metadata.bin` + Then it should pass \ No newline at end of file diff --git a/features/step_definitions/cache_steps.rb b/features/step_definitions/cache_steps.rb index ffc8150..7949cd0 100644 --- a/features/step_definitions/cache_steps.rb +++ b/features/step_definitions/cache_steps.rb @@ -40,6 +40,7 @@ Options: {-q|--quiet} {-h|--help} {-V|--version} + {--clear-needs-check-flag} {--super-block-only} {--skip-mappings} {--skip-hints}