diff --git a/thin-provisioning/mapping_tree.cc b/thin-provisioning/mapping_tree.cc index d3b20c4..d69f30a 100644 --- a/thin-provisioning/mapping_tree.cc +++ b/thin-provisioning/mapping_tree.cc @@ -131,11 +131,16 @@ namespace { using namespace thin_provisioning; using namespace mapping_tree_detail; - struct leaf_visitor { + struct block_time_visitor { virtual void visit(btree_path const &, block_time const &) { } }; + struct block_visitor { + virtual void visit(btree_path const &, uint64_t) { + } + }; + class ll_damage_visitor { public: ll_damage_visitor(damage_visitor &v) @@ -163,12 +168,24 @@ namespace { }; } + +void +thin_provisioning::check_mapping_tree(dev_tree const &tree, + mapping_tree_detail::damage_visitor &visitor) +{ + block_counter counter; // FIXME: get rid of this counter arg + block_visitor vv; + ll_damage_visitor dv(visitor); + + btree_visit_values(tree, counter, vv, dv); +} + void thin_provisioning::check_mapping_tree(mapping_tree const &tree, mapping_tree_detail::damage_visitor &visitor) { block_counter counter; //FIXME: get rid of this counter arg - leaf_visitor vv; + block_time_visitor vv; ll_damage_visitor dv(visitor); btree_visit_values(tree, counter, vv, dv); diff --git a/thin-provisioning/mapping_tree.h b/thin-provisioning/mapping_tree.h index 0b23389..12b3e5c 100644 --- a/thin-provisioning/mapping_tree.h +++ b/thin-provisioning/mapping_tree.h @@ -108,6 +108,8 @@ namespace thin_provisioning { typedef persistent_data::btree<1, mapping_tree_detail::mtree_traits> dev_tree; typedef persistent_data::btree<1, mapping_tree_detail::block_traits> single_mapping_tree; + void check_mapping_tree(dev_tree const &tree, + mapping_tree_detail::damage_visitor &visitor); void check_mapping_tree(mapping_tree const &tree, mapping_tree_detail::damage_visitor &visitor); } diff --git a/thin-provisioning/thin_check.cc b/thin-provisioning/thin_check.cc index 011bff5..1858b7a 100644 --- a/thin-provisioning/thin_check.cc +++ b/thin-provisioning/thin_check.cc @@ -229,7 +229,13 @@ namespace { //-------------------------------- - error_state metadata_check(string const &path) { + struct flags { + bool check_device_tree; + bool check_mapping_tree_level1; + bool check_mapping_tree_level2; + }; + + error_state metadata_check(string const &path, flags fs) { block_manager<>::ptr bm = open_bm(path); nested_output out(cerr, 2); @@ -249,37 +255,47 @@ namespace { superblock_detail::superblock sb = read_superblock(bm); transaction_manager::ptr tm = open_tm(bm); - out << "examining devices tree" << end_message(); - { - auto _ = out.push(); - device_tree dtree(tm, sb.device_details_root_, - device_tree_detail::device_details_traits::ref_counter()); - check_device_tree(dtree, dev_rep); + if (fs.check_device_tree) { + out << "examining devices tree" << end_message(); + { + auto _ = out.push(); + device_tree dtree(tm, sb.device_details_root_, + device_tree_detail::device_details_traits::ref_counter()); + check_device_tree(dtree, dev_rep); + } } - out << "examining mapping tree" << end_message(); - { - auto _ = out.push(); - mapping_tree mtree(tm, sb.data_mapping_root_, - mapping_tree_detail::block_traits::ref_counter(tm->get_sm())); - check_mapping_tree(mtree, mapping_rep); + if (fs.check_mapping_tree_level1 && !fs.check_mapping_tree_level2) { + out << "examining top level of mapping tree" << end_message(); + { + auto _ = out.push(); + dev_tree dtree(tm, sb.data_mapping_root_, + mapping_tree_detail::mtree_traits::ref_counter(tm)); + check_mapping_tree(dtree, mapping_rep); + } + + } else if (fs.check_mapping_tree_level2) { + out << "examining mapping tree" << end_message(); + { + auto _ = out.push(); + mapping_tree mtree(tm, sb.data_mapping_root_, + mapping_tree_detail::block_traits::ref_counter(tm->get_sm())); + check_mapping_tree(mtree, mapping_rep); + } } return combine_errors(sb_rep.get_error(), dev_rep.get_error()); } - int check(string const &path, bool quiet) { + int check(string const &path, flags fs) { error_state err; try { - // FIXME: use quiet flag (pass different reporter) - err = metadata_check(path); + err = metadata_check(path, fs); } catch (std::exception &e) { - - if (!quiet) - cerr << e.what() << endl; + cerr << e.what() << endl; return 1; } @@ -299,13 +315,15 @@ namespace { int main(int argc, char **argv) { int c; - bool quiet = false, superblock_only = false; + flags fs; + bool quiet = false; const char shortopts[] = "qhV"; const struct option longopts[] = { { "quiet", no_argument, NULL, 'q'}, { "help", no_argument, NULL, 'h'}, { "version", no_argument, NULL, 'V'}, { "super-block-only", no_argument, NULL, 1}, + { "skip-mappings", no_argument, NULL, 2}, { NULL, no_argument, NULL, 0 } }; @@ -324,7 +342,17 @@ int main(int argc, char **argv) return 0; case 1: - superblock_only = true; + // super-block-only + fs.check_device_tree = false; + fs.check_mapping_tree_level1 = false; + fs.check_mapping_tree_level2 = false; + break; + + case 2: + // skip-mappings + fs.check_device_tree = true; + fs.check_mapping_tree_level1 = true; + fs.check_mapping_tree_level2 = false; break; default: @@ -340,5 +368,5 @@ int main(int argc, char **argv) } - return check(argv[optind], quiet); + return check(argv[optind], fs); }