[metadata_counter] Count under populated nodes if the option is provided

This commit is contained in:
Ming-Hung Tsai 2020-08-22 04:17:50 +08:00
parent 1fe8a0dbde
commit 61f07573e1
4 changed files with 32 additions and 17 deletions

View File

@ -14,12 +14,14 @@ namespace persistent_data {
public: public:
typedef btree<Levels, ValueTraits> tree; 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), : bc_(bc),
vc_(vc), vc_(vc),
error_outcome_(bc.stop_on_error() ? error_outcome_(bc.stop_on_error() ?
tree::visitor::RETHROW_EXCEPTION : tree::visitor::RETHROW_EXCEPTION :
tree::visitor::EXCEPTION_HANDLED) { tree::visitor::EXCEPTION_HANDLED),
ignore_non_fatal_(ignore_non_fatal) {
} }
virtual bool visit_internal(node_location const &l, virtual bool visit_internal(node_location const &l,
@ -66,7 +68,7 @@ namespace persistent_data {
if (!checker_.check_block_nr(n) || if (!checker_.check_block_nr(n) ||
!checker_.check_value_size(n) || !checker_.check_value_size(n) ||
!checker_.check_max_entries(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_ordered_keys(n) ||
!checker_.check_parent_key(n, l.is_sub_root() ? boost::optional<uint64_t>() : l.key)) !checker_.check_parent_key(n, l.is_sub_root() ? boost::optional<uint64_t>() : l.key))
return false; return false;
@ -83,7 +85,7 @@ namespace persistent_data {
if (!checker_.check_block_nr(n) || if (!checker_.check_block_nr(n) ||
!checker_.check_value_size(n) || !checker_.check_value_size(n) ||
!checker_.check_max_entries(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_ordered_keys(n) ||
!checker_.check_parent_key(n, l.is_sub_root() ? boost::optional<uint64_t>() : l.key) || !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()])) !checker_.check_leaf_key(n, last_leaf_key_[l.level()]))
@ -109,11 +111,18 @@ namespace persistent_data {
return !seen; 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_; block_counter &bc_;
ValueCounter &vc_; ValueCounter &vc_;
btree_node_checker checker_; btree_node_checker checker_;
boost::optional<uint64_t> last_leaf_key_[Levels]; boost::optional<uint64_t> last_leaf_key_[Levels];
error_outcome error_outcome_; error_outcome error_outcome_;
bool ignore_non_fatal_;
}; };
} }
@ -141,8 +150,9 @@ namespace persistent_data {
// walked. This walk should only be done once you're sure the tree // walked. This walk should only be done once you're sure the tree
// is not corrupt. // is not corrupt.
template <unsigned Levels, typename ValueTraits, typename ValueCounter> template <unsigned Levels, typename ValueTraits, typename ValueCounter>
void count_btree_blocks(btree<Levels, ValueTraits> const &tree, block_counter &bc, ValueCounter &vc) { 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); bool ignore_non_fatal = false) {
btree_count_detail::counting_visitor<Levels, ValueTraits, ValueCounter> v(bc, vc, ignore_non_fatal);
tree.visit_depth_first(v); tree.visit_depth_first(v);
} }
} }

View File

@ -303,11 +303,12 @@ namespace {
error_state check_metadata_space_map_counts(transaction_manager::ptr tm, error_state check_metadata_space_map_counts(transaction_manager::ptr tm,
superblock_detail::superblock const &sb, superblock_detail::superblock const &sb,
block_counter &bc, block_counter &bc,
nested_output &out) { nested_output &out,
bool ignore_non_fatal) {
out << "checking space map counts" << end_message(); out << "checking space map counts" << end_message();
nested_output::nest _ = out.push(); nested_output::nest _ = out.push();
if (!count_metadata(tm, sb, bc)) if (!count_metadata(tm, sb, bc, false, ignore_non_fatal))
return FATAL; return FATAL;
// Finally we need to check the metadata space map agrees // Finally we need to check the metadata space map agrees
@ -428,7 +429,7 @@ namespace {
// if we're checking everything, and there were no errors, // if we're checking everything, and there were no errors,
// then we should check the space maps too. // then we should check the space maps too.
err_ << examine_metadata_space_map(tm, sb, options_.sm_opts_, out_, expected_rc_); err_ << examine_metadata_space_map(tm, sb, options_.sm_opts_, options_.ignore_non_fatal_, out_, expected_rc_);
// verify ref-counts of data blocks // verify ref-counts of data blocks
if (err_ != FATAL && core_sm) if (err_ != FATAL && core_sm)
@ -541,13 +542,14 @@ namespace {
examine_metadata_space_map(transaction_manager::ptr tm, examine_metadata_space_map(transaction_manager::ptr tm,
superblock_detail::superblock const &sb, superblock_detail::superblock const &sb,
check_options::space_map_options option, check_options::space_map_options option,
bool ignore_non_fatal,
nested_output &out, nested_output &out,
block_counter &bc) { block_counter &bc) {
error_state err = NO_ERROR; error_state err = NO_ERROR;
switch (option) { switch (option) {
case check_options::SPACE_MAP_FULL: case check_options::SPACE_MAP_FULL:
err << check_metadata_space_map_counts(tm, sb, bc, out); err << check_metadata_space_map_counts(tm, sb, bc, out, ignore_non_fatal);
break; break;
default: default:
break; // do nothing break; // do nothing

View File

@ -10,14 +10,15 @@ using namespace thin_provisioning;
namespace { namespace {
bool count_trees(transaction_manager::ptr tm, bool count_trees(transaction_manager::ptr tm,
superblock_detail::superblock const &sb, superblock_detail::superblock const &sb,
block_counter &bc) { block_counter &bc,
bool ignore_non_fatal) {
// Count the device tree // Count the device tree
{ {
noop_value_counter<device_tree_detail::device_details> vc; noop_value_counter<device_tree_detail::device_details> vc;
device_tree dtree(*tm, sb.device_details_root_, device_tree dtree(*tm, sb.device_details_root_,
device_tree_detail::device_details_traits::ref_counter()); 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 // Count the mapping tree
@ -25,7 +26,7 @@ namespace {
noop_value_counter<mapping_tree_detail::block_time> vc; noop_value_counter<mapping_tree_detail::block_time> vc;
mapping_tree mtree(*tm, sb.data_mapping_root_, mapping_tree mtree(*tm, sb.data_mapping_root_,
mapping_tree_detail::block_traits::ref_counter(space_map::ptr())); 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);
} }
return true; return true;
@ -65,19 +66,20 @@ namespace {
bool thin_provisioning::count_metadata(transaction_manager::ptr tm, bool thin_provisioning::count_metadata(transaction_manager::ptr tm,
superblock_detail::superblock const &sb, superblock_detail::superblock const &sb,
block_counter &bc, block_counter &bc,
bool skip_metadata_snap) { bool skip_metadata_snap,
bool ignore_non_fatal) {
bool ret = true; bool ret = true;
// Count the superblock // Count the superblock
bc.inc(superblock_detail::SUPERBLOCK_LOCATION); bc.inc(superblock_detail::SUPERBLOCK_LOCATION);
ret &= count_trees(tm, sb, bc); ret &= count_trees(tm, sb, bc, ignore_non_fatal);
// Count the metadata snap, if present // Count the metadata snap, if present
if (!skip_metadata_snap && sb.metadata_snap_ != superblock_detail::SUPERBLOCK_LOCATION) { if (!skip_metadata_snap && sb.metadata_snap_ != superblock_detail::SUPERBLOCK_LOCATION) {
bc.inc(sb.metadata_snap_); bc.inc(sb.metadata_snap_);
superblock_detail::superblock snap = read_superblock(tm->get_bm(), sb.metadata_snap_); superblock_detail::superblock snap = read_superblock(tm->get_bm(), sb.metadata_snap_);
ret &= count_trees(tm, snap, bc); ret &= count_trees(tm, snap, bc, ignore_non_fatal);
} }
ret &= count_space_maps(tm, sb, bc); ret &= count_space_maps(tm, sb, bc);

View File

@ -10,7 +10,8 @@ namespace thin_provisioning {
bool count_metadata(transaction_manager::ptr tm, bool count_metadata(transaction_manager::ptr tm,
superblock_detail::superblock const &sb, superblock_detail::superblock const &sb,
block_counter &bc, block_counter &bc,
bool skip_metadata_snap = false); bool skip_metadata_snap = false,
bool ignore_non_fatal = false);
} }
//---------------------------------------------------------------- //----------------------------------------------------------------