Introduce mapping_tree.h
This commit is contained in:
parent
35880f3038
commit
8f2ab2d676
107
thin-provisioning/mapping_tree.h
Normal file
107
thin-provisioning/mapping_tree.h
Normal 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
|
@ -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_));
|
||||
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_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_)));
|
||||
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_,
|
||||
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;
|
||||
|
||||
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);
|
||||
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_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(), mtree_ref_counter(tm_)));
|
||||
mappings_ = mapping_tree::ptr(new mapping_tree(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_));
|
||||
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_));
|
||||
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_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_)));
|
||||
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_,
|
||||
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
|
||||
@ -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_));
|
||||
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_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_, block_time_ref_counter(data_sm_)));
|
||||
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_,
|
||||
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;
|
||||
|
||||
case CREATE:
|
||||
@ -182,8 +190,10 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
|
||||
|
||||
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()));
|
||||
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, block_time_ref_counter(data_sm_)));
|
||||
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(), mtree_ref_counter(tm_)));
|
||||
mappings_ = mapping_tree::ptr(new mapping_tree(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_));
|
||||
sb_.magic_ = SUPERBLOCK_MAGIC;
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "thin-provisioning/metadata_disk_structures.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?
|
||||
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 in kernel driver. This class gives access to the low-level
|
||||
|
@ -17,6 +17,7 @@
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "metadata_dumper.h"
|
||||
#include "thin-provisioning/mapping_tree.h"
|
||||
|
||||
using namespace persistent_data;
|
||||
using namespace thin_provisioning;
|
||||
@ -24,11 +25,11 @@ using namespace thin_provisioning;
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
class mappings_extractor : public btree<2, block_traits>::visitor {
|
||||
class mappings_extractor : public mapping_tree::visitor {
|
||||
public:
|
||||
typedef boost::shared_ptr<mappings_extractor> ptr;
|
||||
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,
|
||||
space_map::ptr md_sm, space_map::ptr data_sm)
|
||||
@ -64,14 +65,14 @@ namespace {
|
||||
}
|
||||
|
||||
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)) {
|
||||
found_errors_ = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
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_);
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ namespace {
|
||||
throw runtime_error("not in device");
|
||||
|
||||
uint64_t key[1] = {origin_block};
|
||||
block_time bt;
|
||||
mapping_tree_detail::block_time bt;
|
||||
bt.block_ = data_block;
|
||||
bt.time_ = time;
|
||||
current_mapping_->insert(key, bt);
|
||||
@ -125,7 +125,7 @@ namespace {
|
||||
single_mapping_tree::ptr new_mapping_tree() {
|
||||
return single_mapping_tree::ptr(
|
||||
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 {
|
||||
|
@ -56,7 +56,7 @@ void
|
||||
thin::insert(block_address thin_block, block_address data_block)
|
||||
{
|
||||
uint64_t key[2] = {dev_, thin_block};
|
||||
block_time bt;
|
||||
mapping_tree_detail::block_time bt;
|
||||
bt.block_ = data_block;
|
||||
bt.time_ = 0; // FIXME: use current time.
|
||||
return pool_->md_->mappings_->insert(key, bt);
|
||||
@ -124,7 +124,8 @@ thin_pool::create_thin(thin_dev_t dev)
|
||||
if (device_exists(dev))
|
||||
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_->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");
|
||||
|
||||
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());
|
||||
md_->mappings_top_level_->insert(snap_key, clone->get_root());
|
||||
|
@ -35,7 +35,7 @@ namespace thin_provisioning {
|
||||
class thin {
|
||||
public:
|
||||
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;
|
||||
maybe_address lookup(block_address thin_block);
|
||||
|
Loading…
Reference in New Issue
Block a user