Blame SOURCES/dmpd-0_9_0-thin_check-dump-Under-populated-nodes-are-now-non-fatal.patch

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