diff --git a/Makefile.in b/Makefile.in index d56c1ca..1d37887 100644 --- a/Makefile.in +++ b/Makefile.in @@ -51,6 +51,7 @@ SOURCE=\ thin-provisioning/device_tree.cc \ thin-provisioning/file_utils.cc \ thin-provisioning/human_readable_format.cc \ + thin-provisioning/mapping_tree.cc \ thin-provisioning/metadata.cc \ thin-provisioning/metadata_checker.cc \ thin-provisioning/metadata_disk_structures.cc \ diff --git a/thin-provisioning/device_tree.cc b/thin-provisioning/device_tree.cc index 5684ab0..fa32969 100644 --- a/thin-provisioning/device_tree.cc +++ b/thin-provisioning/device_tree.cc @@ -1,10 +1,6 @@ #include "thin-provisioning/device_tree.h" #include "persistent-data/data-structures/btree_damage_visitor.h" -#include "persistent-data/transaction_manager.h" -#include "persistent-data/space-maps/core.h" -#include "thin-provisioning/metadata.h" -#include "thin-provisioning/metadata_disk_structures.h" using namespace persistent_data; using namespace thin_provisioning; @@ -22,12 +18,13 @@ namespace { class ll_damage_visitor { public: + // FIXME: is the namespace needed on here? ll_damage_visitor(device_tree_detail::damage_visitor &v) : v_(v) { } virtual void visit(btree_path const &path, btree_detail::damage const &d) { - v_.visit(path, missing_devices(d.desc_, d.lost_keys_)); + v_.visit(missing_devices(d.desc_, d.lost_keys_)); } private: diff --git a/thin-provisioning/device_tree.h b/thin-provisioning/device_tree.h index c088c3b..1aad86a 100644 --- a/thin-provisioning/device_tree.h +++ b/thin-provisioning/device_tree.h @@ -54,7 +54,7 @@ namespace thin_provisioning { d.visit(*this); } - virtual void visit(btree_path const &path, missing_devices const &d) = 0; + virtual void visit(missing_devices const &d) = 0; }; // FIXME: need to add some more damage types for bad leaf data diff --git a/thin-provisioning/mapping_tree.cc b/thin-provisioning/mapping_tree.cc new file mode 100644 index 0000000..d3b20c4 --- /dev/null +++ b/thin-provisioning/mapping_tree.cc @@ -0,0 +1,177 @@ +#include "thin-provisioning/mapping_tree.h" + +#include "persistent-data/data-structures/btree_damage_visitor.h" +#include "persistent-data/space_map.h" + +using namespace persistent_data; + +//---------------------------------------------------------------- + +namespace thin_provisioning { + namespace mapping_tree_detail { + space_map_ref_counter::space_map_ref_counter(space_map::ptr sm) + : sm_(sm) + { + } + + void + space_map_ref_counter::inc(block_address b) + { + sm_->inc(b); + } + + void + space_map_ref_counter::dec(block_address b) + { + sm_->dec(b); + } + + //-------------------------------- + + block_time_ref_counter::block_time_ref_counter(space_map::ptr sm) + : sm_(sm) + { + } + + void + block_time_ref_counter::inc(block_time bt) + { + sm_->inc(bt.block_); + } + + void + block_time_ref_counter::dec(block_time bt) + { + sm_->dec(bt.block_); + } + + //-------------------------------- + + void + block_traits::unpack(disk_type const &disk, value_type &value) + { + uint64_t v = to_cpu(disk); + value.block_ = v >> 24; + value.time_ = v & ((1 << 24) - 1); + } + + void + block_traits::pack(value_type const &value, disk_type &disk) + { + uint64_t v = (value.block_ << 24) | value.time_; + disk = base::to_disk(v); + } + + //-------------------------------- + + mtree_ref_counter::mtree_ref_counter(transaction_manager::ptr tm) + : tm_(tm) + { + } + + void + mtree_ref_counter::inc(block_address b) + { + } + + void + mtree_ref_counter::dec(block_address b) + { + } + + //-------------------------------- + + void + mtree_traits::unpack(disk_type const &disk, value_type &value) + { + value = base::to_cpu(disk); + } + + void + mtree_traits::pack(value_type const &value, disk_type &disk) + { + disk = base::to_disk(value); + } + + //-------------------------------- + + missing_devices::missing_devices(std::string const &desc, range const &keys) + : desc_(desc), + keys_(keys) + { + } + + void + missing_devices::visit(damage_visitor &v) const + { + v.visit(*this); + } + + //-------------------------------- + + missing_mappings::missing_mappings(std::string const &desc, uint64_t thin_dev, + range const &keys) + : desc_(desc), + thin_dev_(thin_dev), + keys_(keys) + { + } + + void + missing_mappings::visit(damage_visitor &v) const + { + v.visit(*this); + } + } +} + +//---------------------------------------------------------------- + +namespace { + using namespace thin_provisioning; + using namespace mapping_tree_detail; + + struct leaf_visitor { + virtual void visit(btree_path const &, block_time const &) { + } + }; + + class ll_damage_visitor { + public: + ll_damage_visitor(damage_visitor &v) + : v_(v) { + } + + virtual void visit(btree_path const &path, btree_detail::damage const &d) { + switch (path.size()) { + case 0: + v_.visit(missing_devices(d.desc_, d.lost_keys_)); + break; + + case 1: + v_.visit(missing_mappings(d.desc_, path[0], d.lost_keys_)); + break; + + default: + // shouldn't get here. + throw std::runtime_error("ll_damage_visitor: path too long"); + } + } + + private: + damage_visitor &v_; + }; +} + +void +thin_provisioning::check_mapping_tree(mapping_tree const &tree, + mapping_tree_detail::damage_visitor &visitor) +{ + block_counter counter; //FIXME: get rid of this counter arg + leaf_visitor vv; + ll_damage_visitor dv(visitor); + + btree_visit_values(tree, counter, vv, dv); +} + +//---------------------------------------------------------------- diff --git a/thin-provisioning/mapping_tree.h b/thin-provisioning/mapping_tree.h index 0464a53..0b23389 100644 --- a/thin-provisioning/mapping_tree.h +++ b/thin-provisioning/mapping_tree.h @@ -10,17 +10,10 @@ namespace thin_provisioning { namespace mapping_tree_detail { class space_map_ref_counter { public: - space_map_ref_counter(space_map::ptr sm) - : sm_(sm) { - } + space_map_ref_counter(space_map::ptr sm); - void inc(block_address b) { - sm_->inc(b); - } - - void dec(block_address b) { - sm_->dec(b); - } + void inc(block_address b); + void dec(block_address b); private: space_map::ptr sm_; @@ -33,17 +26,9 @@ namespace thin_provisioning { class block_time_ref_counter { public: - block_time_ref_counter(space_map::ptr sm) - : sm_(sm) { - } - - void inc(block_time bt) { - sm_->inc(bt.block_); - } - - void dec(block_time bt) { - sm_->dec(bt.block_); - } + block_time_ref_counter(space_map::ptr sm); + void inc(block_time bt); + void dec(block_time bt); private: space_map::ptr sm_; @@ -54,29 +39,16 @@ namespace thin_provisioning { typedef block_time value_type; typedef block_time_ref_counter ref_counter; - static void unpack(disk_type const &disk, value_type &value) { - uint64_t v = to_cpu(disk); - value.block_ = v >> 24; - value.time_ = v & ((1 << 24) - 1); - } - - static void pack(value_type const &value, disk_type &disk) { - uint64_t v = (value.block_ << 24) | value.time_; - disk = base::to_disk(v); - } + static void unpack(disk_type const &disk, value_type &value); + static void pack(value_type const &value, disk_type &disk); }; class mtree_ref_counter { public: - mtree_ref_counter(transaction_manager::ptr tm) - : tm_(tm) { - } + mtree_ref_counter(transaction_manager::ptr tm); - void inc(block_address b) { - } - - void dec(block_address b) { - } + void inc(block_address b); + void dec(block_address b); private: transaction_manager::ptr tm_; @@ -87,20 +59,58 @@ namespace thin_provisioning { typedef uint64_t value_type; typedef mtree_ref_counter ref_counter; - static void unpack(disk_type const &disk, value_type &value) { - value = base::to_cpu(disk); + static void unpack(disk_type const &disk, value_type &value); + static void pack(value_type const &value, disk_type &disk); + }; + + //-------------------------------- + + class damage_visitor; + + struct damage { + virtual ~damage() {} + virtual void visit(damage_visitor &v) const = 0; + }; + + struct missing_devices : public damage { + missing_devices(std::string const &desc, range const &keys); + virtual void visit(damage_visitor &v) const; + + std::string desc_; + range keys_; + }; + + struct missing_mappings : public damage { + missing_mappings(std::string const &desc, uint64_t thin_dev, + range const &keys); + virtual void visit(damage_visitor &v) const; + + std::string desc_; + uint64_t thin_dev_; + range keys_; + }; + + class damage_visitor { + public: + virtual ~damage_visitor() {} + + void visit(damage const &d) { + d.visit(*this); } - static void pack(value_type const &value, disk_type &disk) { - disk = base::to_disk(value); - } + virtual void visit(missing_devices const &d) = 0; + virtual void visit(missing_mappings const &d) = 0; }; + } typedef persistent_data::btree<2, mapping_tree_detail::block_traits> mapping_tree; typedef persistent_data::btree<1, mapping_tree_detail::mtree_traits> dev_tree; typedef persistent_data::btree<1, mapping_tree_detail::block_traits> single_mapping_tree; -}; + + void check_mapping_tree(mapping_tree const &tree, + mapping_tree_detail::damage_visitor &visitor); +} //----------------------------------------------------------------