Introduce mapping_tree.h

This commit is contained in:
Joe Thornber 2013-05-20 17:37:46 +01:00
parent 35880f3038
commit 8f2ab2d676
7 changed files with 140 additions and 113 deletions

View File

@ -0,0 +1,107 @@
#ifndef MAPPING_TREE_H
#define MAPPING_TREE_H
#include "persistent-data/data-structures/btree.h"
#include "persistent-data/range.h"
//----------------------------------------------------------------
namespace thin_provisioning {
namespace mapping_tree_detail {
class space_map_ref_counter {
public:
space_map_ref_counter(space_map::ptr sm)
: sm_(sm) {
}
void inc(block_address b) {
sm_->inc(b);
}
void dec(block_address b) {
sm_->dec(b);
}
private:
space_map::ptr sm_;
};
struct block_time {
uint64_t block_;
uint32_t time_;
};
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_);
}
private:
space_map::ptr sm_;
};
struct block_traits {
typedef base::le64 disk_type;
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<uint64_t>(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<base::le64>(v);
}
};
class mtree_ref_counter {
public:
mtree_ref_counter(transaction_manager::ptr tm)
: tm_(tm) {
}
void inc(block_address b) {
}
void dec(block_address b) {
}
private:
transaction_manager::ptr tm_;
};
struct mtree_traits {
typedef base::le64 disk_type;
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<uint64_t>(disk);
}
static void pack(value_type const &value, disk_type &disk) {
disk = base::to_disk<base::le64>(value);
}
};
}
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;
};
//----------------------------------------------------------------
#endif

View File

@ -108,8 +108,10 @@ metadata::metadata(std::string const &dev_path, open_type ot,
data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_)); data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_));
details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_, mtree_ref_counter(tm_))); mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_,
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_))); mapping_tree_detail::mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_,
mapping_tree_detail::block_time_ref_counter(data_sm_)));
break; break;
case CREATE: case CREATE:
@ -121,8 +123,10 @@ metadata::metadata(std::string const &dev_path, open_type ot,
data_sm_ = create_disk_sm(tm_, nr_data_blocks); data_sm_ = create_disk_sm(tm_, nr_data_blocks);
details_ = device_tree::ptr(new device_tree(tm_, device_tree_detail::device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, device_tree_detail::device_details_traits::ref_counter()));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, block_time_ref_counter(data_sm_))); mappings_ = mapping_tree::ptr(new mapping_tree(tm_,
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(), mtree_ref_counter(tm_))); mapping_tree_detail::block_time_ref_counter(data_sm_)));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(),
mapping_tree_detail::mtree_ref_counter(tm_)));
::memset(&sb_, 0, sizeof(sb_)); ::memset(&sb_, 0, sizeof(sb_));
sb_.magic_ = SUPERBLOCK_MAGIC; sb_.magic_ = SUPERBLOCK_MAGIC;
@ -147,8 +151,10 @@ metadata::metadata(std::string const &dev_path, block_address metadata_snap)
data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_)); data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_));
details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_, mtree_ref_counter(tm_))); mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_,
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_))); mapping_tree_detail::mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_,
mapping_tree_detail::block_time_ref_counter(data_sm_)));
} }
// FIXME: duplication // FIXME: duplication
@ -169,8 +175,10 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_)); data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_));
details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_, mtree_ref_counter(tm_))); mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_,
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_))); mapping_tree_detail::mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_,
mapping_tree_detail::block_time_ref_counter(data_sm_)));
break; break;
case CREATE: case CREATE:
@ -182,8 +190,10 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
data_sm_ = create_disk_sm(tm_, nr_data_blocks); data_sm_ = create_disk_sm(tm_, nr_data_blocks);
details_ = device_tree::ptr(new device_tree(tm_, device_tree_detail::device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(tm_, device_tree_detail::device_details_traits::ref_counter()));
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, block_time_ref_counter(data_sm_))); mappings_ = mapping_tree::ptr(new mapping_tree(tm_,
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(), mtree_ref_counter(tm_))); mapping_tree_detail::block_time_ref_counter(data_sm_)));
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(),
mapping_tree_detail::mtree_ref_counter(tm_)));
::memset(&sb_, 0, sizeof(sb_)); ::memset(&sb_, 0, sizeof(sb_));
sb_.magic_ = SUPERBLOCK_MAGIC; sb_.magic_ = SUPERBLOCK_MAGIC;

View File

@ -27,6 +27,7 @@
#include "thin-provisioning/metadata_disk_structures.h" #include "thin-provisioning/metadata_disk_structures.h"
#include "thin-provisioning/device_tree.h" #include "thin-provisioning/device_tree.h"
#include "thin-provisioning/mapping_tree.h"
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -40,101 +41,8 @@ namespace thin_provisioning {
//------------------------------------------------ //------------------------------------------------
class space_map_ref_counter {
public:
space_map_ref_counter(space_map::ptr sm)
: sm_(sm) {
}
void inc(block_address b) {
sm_->inc(b);
}
void dec(block_address b) {
sm_->dec(b);
}
private:
space_map::ptr sm_;
};
struct block_time {
uint64_t block_;
uint32_t time_;
};
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_);
}
private:
space_map::ptr sm_;
};
struct block_traits {
typedef base::le64 disk_type;
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<uint64_t>(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<base::le64>(v);
}
};
//------------------------------------------------
class mtree_ref_counter {
public:
mtree_ref_counter(transaction_manager::ptr tm)
: tm_(tm) {
}
void inc(block_address b) {
}
void dec(block_address b) {
}
private:
transaction_manager::ptr tm_;
};
struct mtree_traits {
typedef base::le64 disk_type;
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<uint64_t>(disk);
}
static void pack(value_type const &value, disk_type &disk) {
disk = base::to_disk<base::le64>(value);
}
};
// FIXME: should these be in a sub-namespace? // FIXME: should these be in a sub-namespace?
typedef persistent_data::transaction_manager::ptr tm_ptr; typedef persistent_data::transaction_manager::ptr tm_ptr;
typedef persistent_data::btree<1, mtree_traits> dev_tree;
typedef persistent_data::btree<2, block_traits> mapping_tree;
typedef persistent_data::btree<1, block_traits> single_mapping_tree;
// The tools require different interfaces onto the metadata than // The tools require different interfaces onto the metadata than
// the in kernel driver. This class gives access to the low-level // the in kernel driver. This class gives access to the low-level

View File

@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
#include "metadata_dumper.h" #include "metadata_dumper.h"
#include "thin-provisioning/mapping_tree.h"
using namespace persistent_data; using namespace persistent_data;
using namespace thin_provisioning; using namespace thin_provisioning;
@ -24,11 +25,11 @@ using namespace thin_provisioning;
//---------------------------------------------------------------- //----------------------------------------------------------------
namespace { namespace {
class mappings_extractor : public btree<2, block_traits>::visitor { class mappings_extractor : public mapping_tree::visitor {
public: public:
typedef boost::shared_ptr<mappings_extractor> ptr; typedef boost::shared_ptr<mappings_extractor> ptr;
typedef btree_detail::node_location node_location; typedef btree_detail::node_location node_location;
typedef btree_checker<2, block_traits> checker; typedef btree_checker<2, mapping_tree_detail::block_traits> checker;
mappings_extractor(uint64_t dev_id, emitter::ptr e, mappings_extractor(uint64_t dev_id, emitter::ptr e,
space_map::ptr md_sm, space_map::ptr data_sm) space_map::ptr md_sm, space_map::ptr data_sm)
@ -64,14 +65,14 @@ namespace {
} }
bool visit_leaf(node_location const &loc, bool visit_leaf(node_location const &loc,
btree_detail::node_ref<block_traits> const &n) { btree_detail::node_ref<mapping_tree_detail::block_traits> const &n) {
if (!checker_.visit_leaf(loc, n)) { if (!checker_.visit_leaf(loc, n)) {
found_errors_ = true; found_errors_ = true;
return false; return false;
} }
for (unsigned i = 0; i < n.get_nr_entries(); i++) { for (unsigned i = 0; i < n.get_nr_entries(); i++) {
block_time bt = n.value_at(i); mapping_tree_detail::block_time bt = n.value_at(i);
add_mapping(n.key_at(i), bt.block_, bt.time_); add_mapping(n.key_at(i), bt.block_, bt.time_);
} }

View File

@ -114,7 +114,7 @@ namespace {
throw runtime_error("not in device"); throw runtime_error("not in device");
uint64_t key[1] = {origin_block}; uint64_t key[1] = {origin_block};
block_time bt; mapping_tree_detail::block_time bt;
bt.block_ = data_block; bt.block_ = data_block;
bt.time_ = time; bt.time_ = time;
current_mapping_->insert(key, bt); current_mapping_->insert(key, bt);
@ -125,7 +125,7 @@ namespace {
single_mapping_tree::ptr new_mapping_tree() { single_mapping_tree::ptr new_mapping_tree() {
return single_mapping_tree::ptr( return single_mapping_tree::ptr(
new single_mapping_tree(md_->tm_, new single_mapping_tree(md_->tm_,
block_time_ref_counter(md_->data_sm_))); mapping_tree_detail::block_time_ref_counter(md_->data_sm_)));
} }
bool device_exists(thin_dev_t dev) const { bool device_exists(thin_dev_t dev) const {

View File

@ -56,7 +56,7 @@ void
thin::insert(block_address thin_block, block_address data_block) thin::insert(block_address thin_block, block_address data_block)
{ {
uint64_t key[2] = {dev_, thin_block}; uint64_t key[2] = {dev_, thin_block};
block_time bt; mapping_tree_detail::block_time bt;
bt.block_ = data_block; bt.block_ = data_block;
bt.time_ = 0; // FIXME: use current time. bt.time_ = 0; // FIXME: use current time.
return pool_->md_->mappings_->insert(key, bt); return pool_->md_->mappings_->insert(key, bt);
@ -124,7 +124,8 @@ thin_pool::create_thin(thin_dev_t dev)
if (device_exists(dev)) if (device_exists(dev))
throw std::runtime_error("Device already exists"); throw std::runtime_error("Device already exists");
single_mapping_tree::ptr new_tree(new single_mapping_tree(md_->tm_, block_time_ref_counter(md_->data_sm_))); single_mapping_tree::ptr new_tree(new single_mapping_tree(md_->tm_,
mapping_tree_detail::block_time_ref_counter(md_->data_sm_)));
md_->mappings_top_level_->insert(key, new_tree->get_root()); md_->mappings_top_level_->insert(key, new_tree->get_root());
md_->mappings_->set_root(md_->mappings_top_level_->get_root()); // FIXME: ugly md_->mappings_->set_root(md_->mappings_top_level_->get_root()); // FIXME: ugly
@ -142,7 +143,7 @@ thin_pool::create_snap(thin_dev_t dev, thin_dev_t origin)
throw std::runtime_error("unknown origin"); throw std::runtime_error("unknown origin");
single_mapping_tree otree(md_->tm_, *mtree_root, single_mapping_tree otree(md_->tm_, *mtree_root,
block_time_ref_counter(md_->data_sm_)); mapping_tree_detail::block_time_ref_counter(md_->data_sm_));
single_mapping_tree::ptr clone(otree.clone()); single_mapping_tree::ptr clone(otree.clone());
md_->mappings_top_level_->insert(snap_key, clone->get_root()); md_->mappings_top_level_->insert(snap_key, clone->get_root());

View File

@ -35,7 +35,7 @@ namespace thin_provisioning {
class thin { class thin {
public: public:
typedef boost::shared_ptr<thin> ptr; typedef boost::shared_ptr<thin> ptr;
typedef boost::optional<block_time> maybe_address; typedef boost::optional<mapping_tree_detail::block_time> maybe_address;
thin_dev_t get_dev_t() const; thin_dev_t get_dev_t() const;
maybe_address lookup(block_address thin_block); maybe_address lookup(block_address thin_block);