.../data-structures/btree_damage_visitor.h | 22 +++++++++++----- thin-provisioning/device_tree.cc | 11 +++++--- thin-provisioning/device_tree.h | 6 +++-- thin-provisioning/mapping_tree.cc | 30 +++++++++++++--------- thin-provisioning/mapping_tree.h | 25 ++++++++++++------ thin-provisioning/metadata_dumper.cc | 16 ++++++------ thin-provisioning/thin_check.cc | 6 ++--- 7 files changed, 73 insertions(+), 43 deletions(-) diff --git a/persistent-data/data-structures/btree_damage_visitor.h b/persistent-data/data-structures/btree_damage_visitor.h index 1ff16a8..60e25d9 100644 --- a/persistent-data/data-structures/btree_damage_visitor.h +++ b/persistent-data/data-structures/btree_damage_visitor.h @@ -159,10 +159,12 @@ namespace persistent_data { typedef boost::optional maybe_run64; btree_damage_visitor(ValueVisitor &value_visitor, - DamageVisitor &damage_visitor) + DamageVisitor &damage_visitor, + bool ignore_non_fatal) : avoid_repeated_visits_(true), value_visitor_(value_visitor), - damage_visitor_(damage_visitor) { + damage_visitor_(damage_visitor), + ignore_non_fatal_(ignore_non_fatal) { } bool visit_internal(node_location const &loc, @@ -231,7 +233,7 @@ namespace persistent_data { else if (!checker_.check_block_nr(n) || !checker_.check_value_size(n) || !checker_.check_max_entries(n) || - !checker_.check_nr_entries(n, loc.is_sub_root()) || + !check_nr_entries(loc, n) || !checker_.check_ordered_keys(n) || !checker_.check_parent_key(n, loc.is_sub_root() ? boost::optional() : loc.key)) { report_damage(checker_.get_last_error_string()); @@ -255,7 +257,7 @@ namespace persistent_data { else if (!checker_.check_block_nr(n) || !checker_.check_value_size(n) || !checker_.check_max_entries(n) || - !checker_.check_nr_entries(n, loc.is_sub_root()) || + !check_nr_entries(loc, n) || !checker_.check_ordered_keys(n) || !checker_.check_parent_key(n, loc.is_sub_root() ? boost::optional() : loc.key) || !checker_.check_leaf_key(n, last_leaf_key_[loc.level()])) { @@ -353,6 +355,12 @@ namespace persistent_data { maybe_issue_damage(*old_path); } + template + bool check_nr_entries(node_location const &loc, + btree_detail::node_ref const &n) { + return ignore_non_fatal_ || checker_.check_nr_entries(n, loc.is_sub_root()); + } + //-------------------------------- bool avoid_repeated_visits_; @@ -367,15 +375,17 @@ namespace persistent_data { path_tracker path_tracker_; damage_tracker dt_; std::list damage_reasons_; + bool ignore_non_fatal_; }; } template void btree_visit_values(btree const &tree, ValueVisitor &value_visitor, - DamageVisitor &damage_visitor) { + DamageVisitor &damage_visitor, + bool ignore_non_fatal = false) { btree_detail::btree_damage_visitor - v(value_visitor, damage_visitor); + v(value_visitor, damage_visitor, ignore_non_fatal); tree.visit_depth_first(v); } } diff --git a/thin-provisioning/device_tree.cc b/thin-provisioning/device_tree.cc index 4837cb7..8ae16f7 100644 --- a/thin-provisioning/device_tree.cc +++ b/thin-provisioning/device_tree.cc @@ -89,18 +89,21 @@ namespace thin_provisioning { void thin_provisioning::walk_device_tree(device_tree const &tree, device_tree_detail::device_visitor &vv, - device_tree_detail::damage_visitor &dv) + device_tree_detail::damage_visitor &dv, + bool ignore_non_fatal) { visitor_adapter av(vv); ll_damage_visitor ll_dv(dv); - btree_visit_values(tree, av, ll_dv); + btree_visit_values(tree, av, ll_dv, ignore_non_fatal); } void -thin_provisioning::check_device_tree(device_tree const &tree, damage_visitor &visitor) +thin_provisioning::check_device_tree(device_tree const &tree, + damage_visitor &visitor, + bool ignore_non_fatal) { noop_visitor vv; - walk_device_tree(tree, vv, visitor); + walk_device_tree(tree, vv, visitor, ignore_non_fatal); } //---------------------------------------------------------------- diff --git a/thin-provisioning/device_tree.h b/thin-provisioning/device_tree.h index ec0f9f2..980f1a9 100644 --- a/thin-provisioning/device_tree.h +++ b/thin-provisioning/device_tree.h @@ -74,9 +74,11 @@ namespace thin_provisioning { void walk_device_tree(device_tree const &tree, device_tree_detail::device_visitor &dev_v, - device_tree_detail::damage_visitor &dv); + device_tree_detail::damage_visitor &dv, + bool ignore_non_fatal = false); void check_device_tree(device_tree const &tree, - device_tree_detail::damage_visitor &visitor); + device_tree_detail::damage_visitor &visitor, + bool ignore_non_fatal = false); } //---------------------------------------------------------------- diff --git a/thin-provisioning/mapping_tree.cc b/thin-provisioning/mapping_tree.cc index 5b69fe9..6c82095 100644 --- a/thin-provisioning/mapping_tree.cc +++ b/thin-provisioning/mapping_tree.cc @@ -220,54 +220,60 @@ namespace { void thin_provisioning::walk_mapping_tree(dev_tree const &tree, mapping_tree_detail::device_visitor &dev_v, - mapping_tree_detail::damage_visitor &dv) + mapping_tree_detail::damage_visitor &dv, + bool ignore_non_fatal) { dev_tree_damage_visitor ll_dv(dv); - btree_visit_values(tree, dev_v, ll_dv); + btree_visit_values(tree, dev_v, ll_dv, ignore_non_fatal); } void thin_provisioning::check_mapping_tree(dev_tree const &tree, - mapping_tree_detail::damage_visitor &visitor) + mapping_tree_detail::damage_visitor &visitor, + bool ignore_non_fatal) { noop_block_visitor dev_v; - walk_mapping_tree(tree, dev_v, visitor); + walk_mapping_tree(tree, dev_v, visitor, ignore_non_fatal); } void thin_provisioning::walk_mapping_tree(mapping_tree const &tree, mapping_tree_detail::mapping_visitor &mv, - mapping_tree_detail::damage_visitor &dv) + mapping_tree_detail::damage_visitor &dv, + bool ignore_non_fatal) { mapping_tree_damage_visitor ll_dv(dv); - btree_visit_values(tree, mv, ll_dv); + btree_visit_values(tree, mv, ll_dv, ignore_non_fatal); } void thin_provisioning::check_mapping_tree(mapping_tree const &tree, - mapping_tree_detail::damage_visitor &visitor) + mapping_tree_detail::damage_visitor &visitor, + bool ignore_non_fatal) { noop_block_time_visitor mv; - walk_mapping_tree(tree, mv, visitor); + walk_mapping_tree(tree, mv, visitor, ignore_non_fatal); } void thin_provisioning::walk_mapping_tree(single_mapping_tree const &tree, uint64_t dev_id, mapping_tree_detail::mapping_visitor &mv, - mapping_tree_detail::damage_visitor &dv) + mapping_tree_detail::damage_visitor &dv, + bool ignore_non_fatal) { single_mapping_tree_damage_visitor ll_dv(dv, dev_id); - btree_visit_values(tree, mv, ll_dv); + btree_visit_values(tree, mv, ll_dv, ignore_non_fatal); } void thin_provisioning::check_mapping_tree(single_mapping_tree const &tree, uint64_t dev_id, - mapping_tree_detail::damage_visitor &visitor) + mapping_tree_detail::damage_visitor &visitor, + bool ignore_non_fatal) { noop_block_time_visitor mv; - walk_mapping_tree(tree, dev_id, mv, visitor); + walk_mapping_tree(tree, dev_id, mv, visitor, ignore_non_fatal); } //---------------------------------------------------------------- diff --git a/thin-provisioning/mapping_tree.h b/thin-provisioning/mapping_tree.h index ce88ba2..68b5c4b 100644 --- a/thin-provisioning/mapping_tree.h +++ b/thin-provisioning/mapping_tree.h @@ -128,23 +128,32 @@ namespace thin_provisioning { void walk_mapping_tree(dev_tree const &tree, mapping_tree_detail::device_visitor &dev_v, - mapping_tree_detail::damage_visitor &dv); - void check_mapping_tree(dev_tree const &tree, - mapping_tree_detail::damage_visitor &visitor); + mapping_tree_detail::damage_visitor &dv, + bool ignore_non_fatal = false); void walk_mapping_tree(mapping_tree const &tree, mapping_tree_detail::mapping_visitor &mv, - mapping_tree_detail::damage_visitor &dv); - void check_mapping_tree(mapping_tree const &tree, - mapping_tree_detail::damage_visitor &visitor); + mapping_tree_detail::damage_visitor &dv, + bool ignore_non_fatal = false); void walk_mapping_tree(single_mapping_tree const &tree, uint64_t dev_id, mapping_tree_detail::mapping_visitor &mv, - mapping_tree_detail::damage_visitor &dv); + mapping_tree_detail::damage_visitor &dv, + bool ignore_non_fatal = false); + void check_mapping_tree(single_mapping_tree const &tree, uint64_t dev_id, - mapping_tree_detail::damage_visitor &visitor); + mapping_tree_detail::damage_visitor &visitor, + bool ignore_non_fatal = false); + + void check_mapping_tree(dev_tree const &tree, + mapping_tree_detail::damage_visitor &visitor, + bool ignore_non_fatal = false); + + void check_mapping_tree(mapping_tree const &tree, + mapping_tree_detail::damage_visitor &visitor, + bool ignore_non_fatal = false); } //---------------------------------------------------------------- diff --git a/thin-provisioning/metadata_dumper.cc b/thin-provisioning/metadata_dumper.cc index ce28d2e..9ebc8d8 100644 --- a/thin-provisioning/metadata_dumper.cc +++ b/thin-provisioning/metadata_dumper.cc @@ -131,7 +131,7 @@ namespace { auto tree = device_tree(tm, root, device_tree_detail::device_details_traits::ref_counter()); try { - walk_device_tree(tree, de, dv); + walk_device_tree(tree, de, dv, true); } catch (...) { return optional>(); } @@ -156,7 +156,7 @@ namespace { auto tree = dev_tree(tm, root, mapping_tree_detail::mtree_traits::ref_counter(tm)); try { - walk_mapping_tree(tree, me, mv); + walk_mapping_tree(tree, me, mv, true); } catch (...) { return optional>(); } @@ -722,7 +722,7 @@ namespace { // Since we're not mutating the btrees we don't need a real space map noop_map::ptr sm(new noop_map); single_mapping_tree tree(tm_, subtree_root, mapping_tree_detail::block_time_ref_counter(sm)); - walk_mapping_tree(tree, dev_id, static_cast(me), *damage_policy_); + walk_mapping_tree(tree, dev_id, static_cast(me), *damage_policy_, true); } dump_options const &opts_; @@ -752,7 +752,7 @@ namespace { dump_options opts; details_extractor de(opts); device_tree_detail::damage_visitor::ptr dd_policy(details_damage_policy(true)); - walk_device_tree(*md.details_, de, *dd_policy); + walk_device_tree(*md.details_, de, *dd_policy, true); e->begin_superblock("", sb.time_, sb.trans_id_, @@ -765,7 +765,7 @@ namespace { { mapping_tree_detail::damage_visitor::ptr md_policy(mapping_damage_policy(true)); mapping_tree_emit_visitor mte(opts, *md.tm_, e, de.get_details(), mapping_damage_policy(true)); - walk_mapping_tree(*md.mappings_top_level_, mte, *md_policy); + walk_mapping_tree(*md.mappings_top_level_, mte, *md_policy, true); } e->end_superblock(); @@ -801,7 +801,7 @@ thin_provisioning::metadata_dump(metadata::ptr md, emitter::ptr e, dump_options { details_extractor de(opts); device_tree_detail::damage_visitor::ptr dd_policy(details_damage_policy(false)); - walk_device_tree(*md->details_, de, *dd_policy); + walk_device_tree(*md->details_, de, *dd_policy, true); e->begin_superblock("", md->sb_.time_, md->sb_.trans_id_, @@ -814,7 +814,7 @@ thin_provisioning::metadata_dump(metadata::ptr md, emitter::ptr e, dump_options { mapping_tree_detail::damage_visitor::ptr md_policy(mapping_damage_policy(false)); mapping_tree_emit_visitor mte(opts, *md->tm_, e, de.get_details(), mapping_damage_policy(false)); - walk_mapping_tree(*md->mappings_top_level_, mte, *md_policy); + walk_mapping_tree(*md->mappings_top_level_, mte, *md_policy, true); } e->end_superblock(); @@ -844,7 +844,7 @@ thin_provisioning::metadata_dump_subtree(metadata::ptr md, emitter::ptr e, bool mapping_tree_detail::block_time_ref_counter(md->data_sm_)); // FIXME: pass the current device id instead of zero walk_mapping_tree(tree, 0, static_cast(me), - *mapping_damage_policy(repair)); + *mapping_damage_policy(repair), true); } //---------------------------------------------------------------- diff --git a/thin-provisioning/thin_check.cc b/thin-provisioning/thin_check.cc index 6373603..c2612b5 100644 --- a/thin-provisioning/thin_check.cc +++ b/thin-provisioning/thin_check.cc @@ -244,7 +244,7 @@ namespace { nested_output::nest _ = out.push(); device_tree dtree(*tm, sb.device_details_root_, device_tree_detail::device_details_traits::ref_counter()); - check_device_tree(dtree, dev_rep); + check_device_tree(dtree, dev_rep, fs.ignore_non_fatal_errors); } } @@ -254,7 +254,7 @@ namespace { nested_output::nest _ = out.push(); dev_tree dtree(*tm, mapping_root(sb, fs), mapping_tree_detail::mtree_traits::ref_counter(*tm)); - check_mapping_tree(dtree, mapping_rep); + check_mapping_tree(dtree, mapping_rep, fs.ignore_non_fatal_errors); } } else if (fs.check_mapping_tree_level2) { @@ -263,7 +263,7 @@ namespace { nested_output::nest _ = out.push(); mapping_tree mtree(*tm, mapping_root(sb, fs), mapping_tree_detail::block_traits::ref_counter(tm->get_sm())); - check_mapping_tree(mtree, mapping_rep); + check_mapping_tree(mtree, mapping_rep, fs.ignore_non_fatal_errors); } }