This commit is contained in:
Joe Thornber 2013-12-11 17:28:14 +00:00
parent 927f611aad
commit 8049d369a9
12 changed files with 123 additions and 90 deletions

View File

@ -17,6 +17,7 @@
#include "caching/metadata.h" #include "caching/metadata.h"
#include "persistent-data/block.h" #include "persistent-data/block.h"
#include "persistent-data/file_utils.h" #include "persistent-data/file_utils.h"
#include "persistent-data/space_map.h"
#include "persistent-data/space-maps/core.h" #include "persistent-data/space-maps/core.h"
#include "version.h" #include "version.h"
@ -158,6 +159,15 @@ namespace {
using reporter_base::get_error; using reporter_base::get_error;
}; };
class space_map_reporter : public space_map_detail::visitor, reporter_base {
public:
space_map_reporter(nested_output &o)
: reporter_base(o) {
}
using reporter_base::get_error;
};
//-------------------------------- //--------------------------------
transaction_manager::ptr open_tm(block_manager<>::ptr bm) { transaction_manager::ptr open_tm(block_manager<>::ptr bm) {

View File

@ -21,6 +21,7 @@
#include "persistent-data/math_utils.h" #include "persistent-data/math_utils.h"
#include "persistent-data/data-structures/btree.h" #include "persistent-data/data-structures/btree.h"
#include "persistent-data/data-structures/btree_counter.h"
#include "persistent-data/data-structures/btree_damage_visitor.h" #include "persistent-data/data-structures/btree_damage_visitor.h"
#include "persistent-data/data-structures/array_block.h" #include "persistent-data/data-structures/array_block.h"
@ -275,10 +276,9 @@ namespace persistent_data {
template <typename ValueVisitor, typename DamageVisitor> template <typename ValueVisitor, typename DamageVisitor>
void visit_values(ValueVisitor &value_visitor, void visit_values(ValueVisitor &value_visitor,
DamageVisitor &damage_visitor) const { DamageVisitor &damage_visitor) const {
block_counter counter;
block_value_visitor<ValueVisitor> bvisitor(*this, value_visitor); block_value_visitor<ValueVisitor> bvisitor(*this, value_visitor);
block_damage_visitor<DamageVisitor> dvisitor(damage_visitor, entries_per_block_); block_damage_visitor<DamageVisitor> dvisitor(damage_visitor, entries_per_block_);
btree_visit_values(block_tree_, counter, bvisitor, dvisitor); btree_visit_values(block_tree_, bvisitor, dvisitor);
// check that all blocks were seen // check that all blocks were seen
unsigned h = bvisitor.get_highest_seen(); unsigned h = bvisitor.get_highest_seen();
@ -288,6 +288,26 @@ namespace persistent_data {
} }
} }
//--------------------------------
struct ablock_counter {
ablock_counter(block_counter &bc)
: bc_(bc) {
}
void visit(btree_detail::node_location const &loc, block_address b) {
bc_.inc(b);
}
private:
block_counter &bc_;
};
void count_metadata_blocks(block_counter &bc) const {
ablock_counter vc(bc);
count_btree_blocks(block_tree_, bc, vc);
}
private: private:
struct resizer { struct resizer {

View File

@ -136,11 +136,9 @@ namespace persistent_data {
typedef run<block_address> run64; typedef run<block_address> run64;
typedef boost::optional<run64> maybe_run64; typedef boost::optional<run64> maybe_run64;
btree_damage_visitor(block_counter &counter, btree_damage_visitor(ValueVisitor &value_visitor,
ValueVisitor &value_visitor,
DamageVisitor &damage_visitor) DamageVisitor &damage_visitor)
: counter_(counter), : avoid_repeated_visits_(true),
avoid_repeated_visits_(true),
value_visitor_(value_visitor), value_visitor_(value_visitor),
damage_visitor_(damage_visitor) { damage_visitor_(damage_visitor) {
} }
@ -243,8 +241,6 @@ namespace persistent_data {
bool already_visited(node const &n) { bool already_visited(node const &n) {
block_address b = n.get_location(); block_address b = n.get_location();
counter_.inc(b);
if (avoid_repeated_visits_) { if (avoid_repeated_visits_) {
if (seen_.count(b) > 0) if (seen_.count(b) > 0)
return true; return true;
@ -441,7 +437,6 @@ namespace persistent_data {
//-------------------------------- //--------------------------------
block_counter &counter_;
bool avoid_repeated_visits_; bool avoid_repeated_visits_;
ValueVisitor &value_visitor_; ValueVisitor &value_visitor_;
@ -458,11 +453,10 @@ namespace persistent_data {
template <unsigned Levels, typename ValueTraits, typename ValueVisitor, typename DamageVisitor> template <unsigned Levels, typename ValueTraits, typename ValueVisitor, typename DamageVisitor>
void btree_visit_values(btree<Levels, ValueTraits> const &tree, void btree_visit_values(btree<Levels, ValueTraits> const &tree,
block_counter &counter,
ValueVisitor &value_visitor, ValueVisitor &value_visitor,
DamageVisitor &damage_visitor) { DamageVisitor &damage_visitor) {
btree_detail::btree_damage_visitor<ValueVisitor, DamageVisitor, Levels, ValueTraits> btree_detail::btree_damage_visitor<ValueVisitor, DamageVisitor, Levels, ValueTraits>
v(counter, value_visitor, damage_visitor); v(value_visitor, damage_visitor);
tree.visit_depth_first(v); tree.visit_depth_first(v);
} }
} }

View File

@ -97,8 +97,8 @@ namespace {
return sm_->copy_root(dest, len); return sm_->copy_root(dest, len);
} }
virtual void check(block_counter &counter) const { virtual void visit(space_map_detail::visitor &v) const {
return sm_->check(counter); return sm_->visit(v);
} }
virtual checked_space_map::ptr clone() const { virtual checked_space_map::ptr clone() const {

View File

@ -21,7 +21,7 @@
#include "persistent-data/space-maps/recursive.h" #include "persistent-data/space-maps/recursive.h"
#include "persistent-data/space-maps/careful_alloc.h" #include "persistent-data/space-maps/careful_alloc.h"
#include "persistent-data/data-structures/btree_checker.h" #include "persistent-data/data-structures/btree_damage_visitor.h"
#include "persistent-data/checksum.h" #include "persistent-data/checksum.h"
#include "persistent-data/endian_utils.h" #include "persistent-data/endian_utils.h"
#include "persistent-data/math_utils.h" #include "persistent-data/math_utils.h"
@ -200,6 +200,7 @@ namespace {
} }
}; };
#if 0
class ref_count_checker : public btree_checker<1, ref_count_traits> { class ref_count_checker : public btree_checker<1, ref_count_traits> {
public: public:
typedef boost::shared_ptr<ref_count_checker> ptr; typedef boost::shared_ptr<ref_count_checker> ptr;
@ -208,6 +209,14 @@ namespace {
: btree_checker<1, ref_count_traits>(counter) { : btree_checker<1, ref_count_traits>(counter) {
} }
}; };
#endif
class index_entry_visitor {
public:
virtual ~index_entry_visitor() {}
virtual void visit(index_entry const &ie) = 0;
virtual void visit(run<block_address> const &missing) = 0;
};
class index_store { class index_store {
public: public:
@ -219,7 +228,7 @@ namespace {
virtual void commit_ies() = 0; virtual void commit_ies() = 0;
virtual ptr clone() const = 0; virtual ptr clone() const = 0;
virtual block_address get_root() const = 0; virtual block_address get_root() const = 0;
virtual void check(block_counter &counter, block_address nr_index_entries) const = 0; virtual void visit(index_entry_visitor &v, block_address nr_index_entries) const = 0;
}; };
unsigned const ENTRIES_PER_BLOCK = (MD_BLOCK_SIZE - sizeof(bitmap_header)) * 4; unsigned const ENTRIES_PER_BLOCK = (MD_BLOCK_SIZE - sizeof(bitmap_header)) * 4;
@ -358,12 +367,14 @@ namespace {
nr_blocks_ = nr_blocks; nr_blocks_ = nr_blocks;
} }
virtual void check(block_counter &counter) const { virtual void visit(space_map_detail::visitor &v) const {
ref_count_checker v(counter); #if 0
ref_counts_.visit_depth_first(v); ref_count_checker rcv(v);
ref_counts_.visit_depth_first(rcv);
block_address nr_entries = div_up<block_address>(get_nr_blocks(), ENTRIES_PER_BLOCK); block_address nr_entries = div_up<block_address>(get_nr_blocks(), ENTRIES_PER_BLOCK);
indexes_->check(counter, nr_entries); indexes_->visit(v, nr_entries);
#endif
} }
struct look_aside_iterator : public iterator { struct look_aside_iterator : public iterator {
@ -498,56 +509,34 @@ namespace {
btree<1, ref_count_traits> ref_counts_; btree<1, ref_count_traits> ref_counts_;
}; };
class bitmap_tree_validator : public btree_checker<1, index_entry_traits> { //--------------------------------
class ie_value_visitor {
public: public:
typedef btree_detail::node_location node_location; ie_value_visitor(index_entry_visitor &v)
typedef boost::shared_ptr<bitmap_tree_validator> ptr; : v_(v) {
bitmap_tree_validator(block_counter &counter)
: btree_checker<1, index_entry_traits>(counter) {
} }
bool visit_leaf(node_location const &loc, virtual void visit(btree_path const &path, sm_disk_detail::index_entry const &ie) {
btree_detail::node_ref<index_entry_traits> const &n) { // FIXME: finish
bool r = btree_checker<1, index_entry_traits>::visit_leaf(loc, n);
if (!r)
return r;
for (unsigned i = 0; i < n.get_nr_entries(); i++) {
if (seen_indexes_.count(n.key_at(i)) > 0) {
ostringstream out;
out << "index entry " << i << " is present twice";
throw runtime_error(out.str());
}
seen_indexes_.insert(n.key_at(i));
btree_checker<1, index_entry_traits>::get_counter().inc(n.value_at(i).blocknr_);
}
return true;
}
void check_all_index_entries_present(block_address nr_entries) {
for (block_address i = 0; i < nr_entries; i++) {
if (seen_indexes_.count(i) == 0) {
ostringstream out;
out << "missing index entry " << i;
throw runtime_error(out.str());
}
}
set<block_address>::const_iterator it;
for (it = seen_indexes_.begin(); it != seen_indexes_.end(); ++it) {
if (*it >= nr_entries) {
ostringstream out;
out << "unexpected index entry " << *it;
throw runtime_error(out.str());
}
}
} }
private: private:
set<block_address> seen_indexes_; index_entry_visitor &v_;
};
class ie_damage_visitor {
public:
ie_damage_visitor(index_entry_visitor &v)
: v_(v) {
}
virtual void visit(btree_path const &path, btree_detail::damage const &d) {
// FIXME: finish
}
private:
index_entry_visitor &v_;
}; };
class btree_index_store : public index_store { class btree_index_store : public index_store {
@ -595,10 +584,10 @@ namespace {
return bitmaps_.get_root(); return bitmaps_.get_root();
} }
virtual void check(block_counter &counter, block_address nr_index_entries) const { virtual void visit(index_entry_visitor &v, block_address nr_index_entries) const {
bitmap_tree_validator v(counter); ie_value_visitor vv(v);
bitmaps_.visit_depth_first(v); ie_damage_visitor dv(v);
v.check_all_index_entries_present(nr_index_entries); btree_visit_values(bitmaps_, vv, dv);
} }
private: private:
@ -654,12 +643,18 @@ namespace {
return bitmap_root_; return bitmap_root_;
} }
virtual void check(block_counter &counter, block_address nr_index_entries) const { virtual void visit(index_entry_visitor &vv, block_address nr_index_entries) const {
for (unsigned i = 0; i < entries_.size(); i++)
if (entries_[i].blocknr_ != 0)
vv.visit(entries_[i]);
#if 0
counter.inc(bitmap_root_); counter.inc(bitmap_root_);
for (unsigned i = 0; i < entries_.size(); i++) for (unsigned i = 0; i < entries_.size(); i++)
// FIXME: this looks like a hack // FIXME: this looks like a hack
if (entries_[i].blocknr_ != 0) // superblock if (entries_[i].blocknr_ != 0) // superblock
counter.inc(entries_[i].blocknr_); counter.inc(entries_[i].blocknr_);
#endif
} }
private: private:

View File

@ -188,10 +188,10 @@ namespace {
return sm_->copy_root(dest, len); return sm_->copy_root(dest, len);
} }
virtual void check(persistent_data::block_counter &counter) const { virtual void visit(space_map_detail::visitor &v) const {
cant_recurse("check"); cant_recurse("check");
recursing_const_lock lock(*this); recursing_const_lock lock(*this);
return sm_->check(counter); return sm_->visit(v);
} }
virtual checked_space_map::ptr clone() const { virtual checked_space_map::ptr clone() const {

View File

@ -19,8 +19,9 @@
#ifndef SPACE_MAP_H #ifndef SPACE_MAP_H
#define SPACE_MAP_H #define SPACE_MAP_H
#include "block.h" #include "persistent-data/block.h"
#include "block_counter.h" #include "persistent-data/block_counter.h"
#include "persistent-data/run.h"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -114,6 +115,28 @@ namespace persistent_data {
} }
}; };
//--------------------------------
namespace space_map_detail {
class damage {
virtual ~damage() {}
};
class missing_counts : public damage {
public:
missing_counts(base::run<block_address> &lost);
};
class visitor {
public:
virtual ~visitor() {}
virtual void visit(missing_counts const &mc) = 0;
virtual void visit(block_address b, uint32_t count) = 0;
};
}
//--------------------------------
class persistent_space_map : public space_map { class persistent_space_map : public space_map {
public: public:
typedef boost::shared_ptr<persistent_space_map> ptr; typedef boost::shared_ptr<persistent_space_map> ptr;
@ -126,8 +149,8 @@ namespace persistent_data {
public: public:
typedef boost::shared_ptr<checked_space_map> ptr; typedef boost::shared_ptr<checked_space_map> ptr;
virtual void check(block_counter &counter) const { virtual void visit(space_map_detail::visitor &v) const {
throw std::runtime_error("'check' not implemented"); throw std::runtime_error("space_map.visit not implemented");
} }
// FIXME: should this be in the base space_map class? // FIXME: should this be in the base space_map class?

View File

@ -84,10 +84,9 @@ thin_provisioning::walk_device_tree(device_tree const &tree,
device_tree_detail::device_visitor &vv, device_tree_detail::device_visitor &vv,
device_tree_detail::damage_visitor &dv) device_tree_detail::damage_visitor &dv)
{ {
block_counter counter;
visitor_adapter av(vv); visitor_adapter av(vv);
ll_damage_visitor ll_dv(dv); ll_damage_visitor ll_dv(dv);
btree_visit_values(tree, counter, av, ll_dv); btree_visit_values(tree, av, ll_dv);
} }
void void

View File

@ -173,9 +173,8 @@ thin_provisioning::walk_mapping_tree(dev_tree const &tree,
mapping_tree_detail::device_visitor &dev_v, mapping_tree_detail::device_visitor &dev_v,
mapping_tree_detail::damage_visitor &dv) mapping_tree_detail::damage_visitor &dv)
{ {
block_counter counter;
ll_damage_visitor ll_dv(dv); ll_damage_visitor ll_dv(dv);
btree_visit_values(tree, counter, dev_v, ll_dv); btree_visit_values(tree, dev_v, ll_dv);
} }
void void
@ -191,9 +190,8 @@ thin_provisioning::walk_mapping_tree(mapping_tree const &tree,
mapping_tree_detail::mapping_visitor &mv, mapping_tree_detail::mapping_visitor &mv,
mapping_tree_detail::damage_visitor &dv) mapping_tree_detail::damage_visitor &dv)
{ {
block_counter counter;
ll_damage_visitor ll_dv(dv); ll_damage_visitor ll_dv(dv);
btree_visit_values(tree, counter, mv, ll_dv); btree_visit_values(tree, mv, ll_dv);
} }
void void
@ -209,9 +207,8 @@ thin_provisioning::walk_mapping_tree(single_mapping_tree const &tree,
mapping_tree_detail::mapping_visitor &mv, mapping_tree_detail::mapping_visitor &mv,
mapping_tree_detail::damage_visitor &dv) mapping_tree_detail::damage_visitor &dv)
{ {
block_counter counter;
ll_damage_visitor ll_dv(dv); ll_damage_visitor ll_dv(dv);
btree_visit_values(tree, counter, mv, ll_dv); btree_visit_values(tree, mv, ll_dv);
} }
void void

View File

@ -18,8 +18,6 @@
#include "thin-provisioning/thin_pool.h" #include "thin-provisioning/thin_pool.h"
#include "persistent-data/data-structures/btree_checker.h"
#include <stdexcept> #include <stdexcept>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>

View File

@ -63,7 +63,6 @@ namespace {
} }
int rmap(string const &path, vector<region> const &regions) { int rmap(string const &path, vector<region> const &regions) {
block_counter counter; // FIXME: get rid of this counter arg
damage_visitor dv; damage_visitor dv;
rmap_visitor rv; rmap_visitor rv;
@ -79,7 +78,7 @@ namespace {
mapping_tree mtree(tm, sb.data_mapping_root_, mapping_tree mtree(tm, sb.data_mapping_root_,
mapping_tree_detail::block_traits::ref_counter(tm->get_sm())); mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
btree_visit_values(mtree, counter, rv, dv); btree_visit_values(mtree, rv, dv);
rv.complete(); rv.complete();
display_rmap(cout, rv.get_rmap()); display_rmap(cout, rv.get_rmap());

View File

@ -388,8 +388,7 @@ namespace {
} }
virtual void run_() { virtual void run_() {
block_counter counter; btree_visit_values(*tree_, value_visitor_, damage_visitor_);
btree_visit_values(*tree_, counter, value_visitor_, damage_visitor_);
} }
}; };
@ -470,8 +469,7 @@ namespace {
} }
virtual void run_() { virtual void run_() {
block_counter counter; btree_visit_values(*tree_, value_visitor_, damage_visitor_);
btree_visit_values(*tree_, counter, value_visitor_, damage_visitor_);
} }
}; };
} }