diff --git a/caching/cache_check.cc b/caching/cache_check.cc index 419169f..8f6ab7d 100644 --- a/caching/cache_check.cc +++ b/caching/cache_check.cc @@ -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) { diff --git a/persistent-data/data-structures/array.h b/persistent-data/data-structures/array.h index 654902d..6c76bf2 100644 --- a/persistent-data/data-structures/array.h +++ b/persistent-data/data-structures/array.h @@ -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 void visit_values(ValueVisitor &value_visitor, DamageVisitor &damage_visitor) const { - block_counter counter; block_value_visitor bvisitor(*this, value_visitor); block_damage_visitor 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 { diff --git a/persistent-data/data-structures/btree_damage_visitor.h b/persistent-data/data-structures/btree_damage_visitor.h index 67addaa..c8eee3b 100644 --- a/persistent-data/data-structures/btree_damage_visitor.h +++ b/persistent-data/data-structures/btree_damage_visitor.h @@ -136,11 +136,9 @@ namespace persistent_data { typedef run run64; typedef boost::optional 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 void btree_visit_values(btree const &tree, - block_counter &counter, ValueVisitor &value_visitor, DamageVisitor &damage_visitor) { btree_detail::btree_damage_visitor - v(counter, value_visitor, damage_visitor); + v(value_visitor, damage_visitor); tree.visit_depth_first(v); } } diff --git a/persistent-data/space-maps/careful_alloc.cc b/persistent-data/space-maps/careful_alloc.cc index a0fb180..a25653c 100644 --- a/persistent-data/space-maps/careful_alloc.cc +++ b/persistent-data/space-maps/careful_alloc.cc @@ -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 { diff --git a/persistent-data/space-maps/disk.cc b/persistent-data/space-maps/disk.cc index 36937ec..df3ed43 100644 --- a/persistent-data/space-maps/disk.cc +++ b/persistent-data/space-maps/disk.cc @@ -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 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 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(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 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 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::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 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: diff --git a/persistent-data/space-maps/recursive.cc b/persistent-data/space-maps/recursive.cc index f7939e9..6533c20 100644 --- a/persistent-data/space-maps/recursive.cc +++ b/persistent-data/space-maps/recursive.cc @@ -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 { diff --git a/persistent-data/space_map.h b/persistent-data/space_map.h index 8f37b0b..5395c90 100644 --- a/persistent-data/space_map.h +++ b/persistent-data/space_map.h @@ -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 #include @@ -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 &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 ptr; @@ -126,8 +149,8 @@ namespace persistent_data { public: typedef boost::shared_ptr 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? diff --git a/thin-provisioning/device_tree.cc b/thin-provisioning/device_tree.cc index ef5d097..223d816 100644 --- a/thin-provisioning/device_tree.cc +++ b/thin-provisioning/device_tree.cc @@ -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 diff --git a/thin-provisioning/mapping_tree.cc b/thin-provisioning/mapping_tree.cc index 007d1dd..ea3292f 100644 --- a/thin-provisioning/mapping_tree.cc +++ b/thin-provisioning/mapping_tree.cc @@ -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 diff --git a/thin-provisioning/thin_pool.cc b/thin-provisioning/thin_pool.cc index cb2655e..23725d4 100644 --- a/thin-provisioning/thin_pool.cc +++ b/thin-provisioning/thin_pool.cc @@ -18,8 +18,6 @@ #include "thin-provisioning/thin_pool.h" -#include "persistent-data/data-structures/btree_checker.h" - #include #include #include diff --git a/thin-provisioning/thin_rmap.cc b/thin-provisioning/thin_rmap.cc index bfbd67f..9211459 100644 --- a/thin-provisioning/thin_rmap.cc +++ b/thin-provisioning/thin_rmap.cc @@ -63,7 +63,6 @@ namespace { } int rmap(string const &path, vector const ®ions) { - 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()); diff --git a/unit-tests/btree_damage_visitor_t.cc b/unit-tests/btree_damage_visitor_t.cc index 175f0a7..d6eb9c4 100644 --- a/unit-tests/btree_damage_visitor_t.cc +++ b/unit-tests/btree_damage_visitor_t.cc @@ -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_); } }; }