persistent-data/data-structures/btree_counter.h | 22 ++++++++++++++++------
thin-provisioning/metadata_counter.cc | 14 ++++++++------
thin-provisioning/metadata_counter.h | 3 ++-
thin-provisioning/thin_check.cc | 2 +-
4 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/persistent-data/data-structures/btree_counter.h b/persistent-data/data-structures/btree_counter.h
index 6ccf03a..e639c40 100644
--- a/persistent-data/data-structures/btree_counter.h
+++ b/persistent-data/data-structures/btree_counter.h
@@ -14,9 +14,11 @@ namespace persistent_data {
public:
typedef btree<Levels, ValueTraits> tree;
- counting_visitor(block_counter &bc, ValueCounter &vc)
+ counting_visitor(block_counter &bc, ValueCounter &vc,
+ bool ignore_non_fatal = false)
: bc_(bc),
- vc_(vc) {
+ vc_(vc),
+ ignore_non_fatal_(ignore_non_fatal) {
}
virtual bool visit_internal(node_location const &l,
@@ -63,7 +65,7 @@ namespace persistent_data {
if (!checker_.check_block_nr(n) ||
!checker_.check_value_size(n) ||
!checker_.check_max_entries(n) ||
- !checker_.check_nr_entries(n, l.is_sub_root()) ||
+ !check_nr_entries(l, n) ||
!checker_.check_ordered_keys(n) ||
!checker_.check_parent_key(n, l.is_sub_root() ? boost::optional<uint64_t>() : l.key))
return false;
@@ -80,7 +82,7 @@ namespace persistent_data {
if (!checker_.check_block_nr(n) ||
!checker_.check_value_size(n) ||
!checker_.check_max_entries(n) ||
- !checker_.check_nr_entries(n, l.is_sub_root()) ||
+ !check_nr_entries(l, n) ||
!checker_.check_ordered_keys(n) ||
!checker_.check_parent_key(n, l.is_sub_root() ? boost::optional<uint64_t>() : l.key) ||
!checker_.check_leaf_key(n, last_leaf_key_[l.level()]))
@@ -106,10 +108,17 @@ namespace persistent_data {
return !seen;
}
+ template <typename ValueTraits2>
+ bool check_nr_entries(node_location const &loc,
+ btree_detail::node_ref<ValueTraits2> const &n) {
+ return ignore_non_fatal_ || checker_.check_nr_entries(n, loc.is_sub_root());
+ }
+
block_counter &bc_;
ValueCounter &vc_;
btree_node_checker checker_;
boost::optional<uint64_t> last_leaf_key_[Levels];
+ bool ignore_non_fatal_;
};
}
@@ -137,8 +146,9 @@ namespace persistent_data {
// walked. This walk should only be done once you're sure the tree
// is not corrupt.
template <unsigned Levels, typename ValueTraits, typename ValueCounter>
- void count_btree_blocks(btree<Levels, ValueTraits> const &tree, block_counter &bc, ValueCounter &vc) {
- btree_count_detail::counting_visitor<Levels, ValueTraits, ValueCounter> v(bc, vc);
+ void count_btree_blocks(btree<Levels, ValueTraits> const &tree, block_counter &bc, ValueCounter &vc,
+ bool ignore_non_fatal = false) {
+ btree_count_detail::counting_visitor<Levels, ValueTraits, ValueCounter> v(bc, vc, ignore_non_fatal);
tree.visit_depth_first(v);
}
}
diff --git a/thin-provisioning/metadata_counter.cc b/thin-provisioning/metadata_counter.cc
index 95487d2..6f0d109 100644
--- a/thin-provisioning/metadata_counter.cc
+++ b/thin-provisioning/metadata_counter.cc
@@ -10,14 +10,15 @@ using namespace thin_provisioning;
namespace {
void count_trees(transaction_manager::ptr tm,
superblock_detail::superblock const &sb,
- block_counter &bc) {
+ block_counter &bc,
+ bool ignore_non_fatal) {
// Count the device tree
{
noop_value_counter<device_tree_detail::device_details> vc;
device_tree dtree(*tm, sb.device_details_root_,
device_tree_detail::device_details_traits::ref_counter());
- count_btree_blocks(dtree, bc, vc);
+ count_btree_blocks(dtree, bc, vc, ignore_non_fatal);
}
// Count the mapping tree
@@ -25,7 +26,7 @@ namespace {
noop_value_counter<mapping_tree_detail::block_time> vc;
mapping_tree mtree(*tm, sb.data_mapping_root_,
mapping_tree_detail::block_traits::ref_counter(space_map::ptr()));
- count_btree_blocks(mtree, bc, vc);
+ count_btree_blocks(mtree, bc, vc, ignore_non_fatal);
}
}
@@ -55,17 +56,18 @@ namespace {
void thin_provisioning::count_metadata(transaction_manager::ptr tm,
superblock_detail::superblock const &sb,
block_counter &bc,
- bool skip_metadata_snap) {
+ bool skip_metadata_snap,
+ bool ignore_non_fatal) {
// Count the superblock
bc.inc(superblock_detail::SUPERBLOCK_LOCATION);
- count_trees(tm, sb, bc);
+ count_trees(tm, sb, bc, ignore_non_fatal);
// Count the metadata snap, if present
if (!skip_metadata_snap && sb.metadata_snap_ != superblock_detail::SUPERBLOCK_LOCATION) {
bc.inc(sb.metadata_snap_);
superblock_detail::superblock snap = read_superblock(tm->get_bm(), sb.metadata_snap_);
- count_trees(tm, snap, bc);
+ count_trees(tm, snap, bc, ignore_non_fatal);
}
count_space_maps(tm, sb, bc);
diff --git a/thin-provisioning/metadata_counter.h b/thin-provisioning/metadata_counter.h
index bc65ab9..ea9813d 100644
--- a/thin-provisioning/metadata_counter.h
+++ b/thin-provisioning/metadata_counter.h
@@ -10,7 +10,8 @@ namespace thin_provisioning {
void count_metadata(transaction_manager::ptr tm,
superblock_detail::superblock const &sb,
block_counter &bc,
- bool skip_metadata_snap = false);
+ bool skip_metadata_snap = false,
+ bool ignore_non_fatal = false);
}
//----------------------------------------------------------------
diff --git a/thin-provisioning/thin_check.cc b/thin-provisioning/thin_check.cc
index c2612b5..5900902 100644
--- a/thin-provisioning/thin_check.cc
+++ b/thin-provisioning/thin_check.cc
@@ -165,7 +165,7 @@ namespace {
transaction_manager::ptr tm) {
block_counter bc;
- count_metadata(tm, sb, bc);
+ count_metadata(tm, sb, bc, false, fs.ignore_non_fatal_errors);
// Finally we need to check the metadata space map agrees
// with the counts we've just calculated.