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 "persistent-data/block.h"
#include "persistent-data/file_utils.h"
#include "persistent-data/space_map.h"
#include "persistent-data/space-maps/core.h"
#include "version.h"
@ -158,6 +159,15 @@ namespace {
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) {

View File

@ -21,6 +21,7 @@
#include "persistent-data/math_utils.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/array_block.h"
@ -275,10 +276,9 @@ namespace persistent_data {
template <typename ValueVisitor, typename DamageVisitor>
void visit_values(ValueVisitor &value_visitor,
DamageVisitor &damage_visitor) const {
block_counter counter;
block_value_visitor<ValueVisitor> bvisitor(*this, value_visitor);
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
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:
struct resizer {

View File

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

View File

@ -97,8 +97,8 @@ namespace {
return sm_->copy_root(dest, len);
}
virtual void check(block_counter &counter) const {
return sm_->check(counter);
virtual void visit(space_map_detail::visitor &v) const {
return sm_->visit(v);
}
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/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/endian_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> {
public:
typedef boost::shared_ptr<ref_count_checker> ptr;
@ -208,6 +209,14 @@ namespace {
: 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 {
public:
@ -219,7 +228,7 @@ namespace {
virtual void commit_ies() = 0;
virtual ptr clone() 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;
@ -358,12 +367,14 @@ namespace {
nr_blocks_ = nr_blocks;
}
virtual void check(block_counter &counter) const {
ref_count_checker v(counter);
ref_counts_.visit_depth_first(v);
virtual void visit(space_map_detail::visitor &v) const {
#if 0
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);
indexes_->check(counter, nr_entries);
indexes_->visit(v, nr_entries);
#endif
}
struct look_aside_iterator : public iterator {
@ -498,56 +509,34 @@ namespace {
btree<1, ref_count_traits> ref_counts_;
};
class bitmap_tree_validator : public btree_checker<1, index_entry_traits> {
//--------------------------------
class ie_value_visitor {
public:
typedef btree_detail::node_location node_location;
typedef boost::shared_ptr<bitmap_tree_validator> ptr;
bitmap_tree_validator(block_counter &counter)
: btree_checker<1, index_entry_traits>(counter) {
ie_value_visitor(index_entry_visitor &v)
: v_(v) {
}
bool visit_leaf(node_location const &loc,
btree_detail::node_ref<index_entry_traits> const &n) {
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());
}
}
virtual void visit(btree_path const &path, sm_disk_detail::index_entry const &ie) {
// FIXME: finish
}
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 {
@ -595,10 +584,10 @@ namespace {
return bitmaps_.get_root();
}
virtual void check(block_counter &counter, block_address nr_index_entries) const {
bitmap_tree_validator v(counter);
bitmaps_.visit_depth_first(v);
v.check_all_index_entries_present(nr_index_entries);
virtual void visit(index_entry_visitor &v, block_address nr_index_entries) const {
ie_value_visitor vv(v);
ie_damage_visitor dv(v);
btree_visit_values(bitmaps_, vv, dv);
}
private:
@ -654,12 +643,18 @@ namespace {
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_);
for (unsigned i = 0; i < entries_.size(); i++)
// FIXME: this looks like a hack
if (entries_[i].blocknr_ != 0) // superblock
counter.inc(entries_[i].blocknr_);
#endif
}
private:

View File

@ -188,10 +188,10 @@ namespace {
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");
recursing_const_lock lock(*this);
return sm_->check(counter);
return sm_->visit(v);
}
virtual checked_space_map::ptr clone() const {

View File

@ -19,8 +19,9 @@
#ifndef SPACE_MAP_H
#define SPACE_MAP_H
#include "block.h"
#include "block_counter.h"
#include "persistent-data/block.h"
#include "persistent-data/block_counter.h"
#include "persistent-data/run.h"
#include <boost/shared_ptr.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 {
public:
typedef boost::shared_ptr<persistent_space_map> ptr;
@ -126,8 +149,8 @@ namespace persistent_data {
public:
typedef boost::shared_ptr<checked_space_map> ptr;
virtual void check(block_counter &counter) const {
throw std::runtime_error("'check' not implemented");
virtual void visit(space_map_detail::visitor &v) const {
throw std::runtime_error("space_map.visit not implemented");
}
// 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::damage_visitor &dv)
{
block_counter counter;
visitor_adapter av(vv);
ll_damage_visitor ll_dv(dv);
btree_visit_values(tree, counter, av, ll_dv);
btree_visit_values(tree, av, ll_dv);
}
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::damage_visitor &dv)
{
block_counter counter;
ll_damage_visitor ll_dv(dv);
btree_visit_values(tree, counter, dev_v, ll_dv);
btree_visit_values(tree, dev_v, ll_dv);
}
void
@ -191,9 +190,8 @@ thin_provisioning::walk_mapping_tree(mapping_tree const &tree,
mapping_tree_detail::mapping_visitor &mv,
mapping_tree_detail::damage_visitor &dv)
{
block_counter counter;
ll_damage_visitor ll_dv(dv);
btree_visit_values(tree, counter, mv, ll_dv);
btree_visit_values(tree, mv, ll_dv);
}
void
@ -209,9 +207,8 @@ thin_provisioning::walk_mapping_tree(single_mapping_tree const &tree,
mapping_tree_detail::mapping_visitor &mv,
mapping_tree_detail::damage_visitor &dv)
{
block_counter counter;
ll_damage_visitor ll_dv(dv);
btree_visit_values(tree, counter, mv, ll_dv);
btree_visit_values(tree, mv, ll_dv);
}
void

View File

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

View File

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

View File

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