diff --git a/thin-provisioning/thin_rmap.cc b/thin-provisioning/thin_rmap.cc index 53ccc25..5416d65 100644 --- a/thin-provisioning/thin_rmap.cc +++ b/thin-provisioning/thin_rmap.cc @@ -6,7 +6,10 @@ #include "version.h" +#include "persistent-data/data-structures/btree_damage_visitor.h" #include "persistent-data/range.h" +#include "persistent-data/space-maps/core.h" +#include "thin-provisioning/file_utils.h" #include "thin-provisioning/superblock.h" #include "thin-provisioning/mapping_tree.h" @@ -16,10 +19,85 @@ using namespace thin_provisioning; //---------------------------------------------------------------- namespace { + block_manager<>::ptr + open_bm(string const &path) { + block_address nr_blocks = get_nr_blocks(path); + typename block_io<>::mode m = block_io<>::READ_ONLY; + return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m)); + } + + transaction_manager::ptr + open_tm(block_manager<>::ptr bm) { + space_map::ptr sm(new core_map(bm->get_nr_blocks())); + sm->inc(superblock_detail::SUPERBLOCK_LOCATION); + transaction_manager::ptr tm(new transaction_manager(bm, sm)); + return tm; + } + + //-------------------------------- + typedef range region; + using namespace mapping_tree_detail; + + class region_visitor { + public: + region_visitor(vector const ®ions) + : regions_(regions) { + } + + virtual void visit(btree_path const &path, block_time const &bt) { + if (in_regions(bt.block_)) { + uint32_t thin_dev = path[0]; + block_address thin_block = path[1]; + + cout << "[" << thin_dev + << ", " << thin_block + << "] -> " << bt.block_ + << endl; + } + } + + private: + // Slow, but I suspect we wont run with many regions. + bool in_regions(block_address b) const { + for (region const &r : regions_) + if (r.contains(b)) + return true; + + return false; + } + + vector const ®ions_; + }; + + class damage_visitor { + public: + virtual void visit(btree_path const &path, btree_detail::damage const &d) { + throw std::runtime_error("damage in mapping tree, please run thin_check"); + } + }; + int rmap(string const &path, vector const ®ions) { - cerr << "Not implemented" << endl; + block_counter counter; // FIXME: get rid of this counter arg + region_visitor rv(regions); + damage_visitor dv; + + try { + block_manager<>::ptr bm = open_bm(path); + transaction_manager::ptr tm = open_tm(bm); + + superblock_detail::superblock sb = read_superblock(bm); + 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); + + } catch (std::exception const &e) { + cerr << e.what(); + return 1; + } + return 0; }