[thin-repair] stop using c++0x features
This commit is contained in:
parent
987a8360c9
commit
04d7b7ce5b
3
Makefile
3
Makefile
@ -15,7 +15,8 @@ TEST_SOURCE=\
|
||||
OBJECTS=$(subst .cc,.o,$(SOURCE))
|
||||
TEST_PROGRAMS=$(subst .cc,,$(TEST_SOURCE))
|
||||
TOP_DIR:=$(PWD)
|
||||
CPPFLAGS=-Wall -std=c++0x -g -I$(TOP_DIR)
|
||||
CPPFLAGS=-Wall -g -I$(TOP_DIR)
|
||||
#CPPFLAGS=-Wall -std=c++0x -g -I$(TOP_DIR)
|
||||
LIBS=-lstdc++
|
||||
|
||||
.PHONEY: unit-tests test-programs
|
||||
|
3
block.h
3
block.h
@ -181,7 +181,8 @@ namespace persistent_data {
|
||||
mutable unsigned superblock_count_;
|
||||
mutable unsigned ordinary_count_;
|
||||
|
||||
mutable std::map<block_address, std::pair<lock_type, unsigned> > held_locks_;
|
||||
typedef std::map<block_address, std::pair<lock_type, unsigned> > held_map;
|
||||
mutable held_map held_locks_;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "block.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@ -352,7 +353,7 @@ template <uint32_t BlockSize>
|
||||
void
|
||||
block_manager<BlockSize>::register_lock(block_address b, lock_type t) const
|
||||
{
|
||||
auto it = held_locks_.find(b);
|
||||
typename held_map::iterator it = held_locks_.find(b);
|
||||
if (it == held_locks_.end())
|
||||
held_locks_.insert(make_pair(b, make_pair(t, 1)));
|
||||
else {
|
||||
@ -370,7 +371,7 @@ template <uint32_t BlockSize>
|
||||
void
|
||||
block_manager<BlockSize>::unregister_lock(block_address b, lock_type t) const
|
||||
{
|
||||
auto it = held_locks_.find(b);
|
||||
typename held_map::iterator it = held_locks_.find(b);
|
||||
if (it == held_locks_.end())
|
||||
throw std::runtime_error("lock not held");
|
||||
|
||||
|
22
btree.h
22
btree.h
@ -189,13 +189,16 @@ namespace persistent_data {
|
||||
template <uint32_t BlockSize>
|
||||
class shadow_spine : private noncopyable {
|
||||
public:
|
||||
typedef typename transaction_manager<BlockSize>::read_ref read_ref;
|
||||
typedef typename transaction_manager<BlockSize>::write_ref write_ref;
|
||||
|
||||
shadow_spine(typename transaction_manager<BlockSize>::ptr tm)
|
||||
: tm_(tm) {
|
||||
}
|
||||
|
||||
// true if the children of the shadow need incrementing
|
||||
bool step(block_address b) {
|
||||
auto p = tm_->shadow(b);
|
||||
pair<write_ref, bool> p = tm_->shadow(b);
|
||||
try {
|
||||
step(p.first);
|
||||
} catch (...) {
|
||||
@ -261,16 +264,16 @@ namespace persistent_data {
|
||||
|
||||
for (;;) {
|
||||
spine.step(block);
|
||||
auto leaf = spine.template get_node<ValueTraits>();
|
||||
node_ref<ValueTraits, BlockSize> leaf = spine.template get_node<ValueTraits>();
|
||||
|
||||
auto mi = leaf.exact_search(key);
|
||||
optional<unsigned> mi = leaf.exact_search(key);
|
||||
if (!mi)
|
||||
return optional<leaf_type>();
|
||||
|
||||
if (leaf.get_type() == btree_detail::LEAF)
|
||||
return optional<leaf_type>(leaf.value_at(*mi));
|
||||
|
||||
auto internal = spine.template get_node<uint64_traits>();
|
||||
node_ref<uint64_traits, BlockSize> internal = spine.template get_node<uint64_traits>();
|
||||
block = internal.value_at(*mi);
|
||||
}
|
||||
}
|
||||
@ -287,6 +290,8 @@ namespace persistent_data {
|
||||
typedef boost::optional<std::pair<unsigned, value_type> > maybe_pair;
|
||||
typedef typename block_manager<BlockSize>::read_ref read_ref;
|
||||
typedef typename block_manager<BlockSize>::write_ref write_ref;
|
||||
typedef typename btree_detail::node_ref<ValueTraits, BlockSize> leaf_node;
|
||||
typedef typename btree_detail::node_ref<uint64_traits, BlockSize> internal_node;
|
||||
|
||||
btree(typename persistent_data::transaction_manager<BlockSize>::ptr tm,
|
||||
typename ValueTraits::ref_counter rc);
|
||||
@ -320,12 +325,9 @@ namespace persistent_data {
|
||||
virtual ~visitor() {}
|
||||
typedef boost::shared_ptr<visitor> ptr;
|
||||
|
||||
virtual void visit_internal(unsigned level, bool is_root,
|
||||
btree_detail::node_ref<uint64_traits, BlockSize> const &n) = 0;
|
||||
virtual void visit_internal_leaf(unsigned level, bool is_root,
|
||||
btree_detail::node_ref<uint64_traits, BlockSize> const &n) = 0;
|
||||
virtual void visit_leaf(unsigned level, bool is_root,
|
||||
btree_detail::node_ref<ValueTraits, BlockSize> const &n) = 0;
|
||||
virtual void visit_internal(unsigned level, bool is_root, internal_node const &n) = 0;
|
||||
virtual void visit_internal_leaf(unsigned level, bool is_root, internal_node const &n) = 0;
|
||||
virtual void visit_leaf(unsigned level, bool is_root, leaf_node const &n) = 0;
|
||||
};
|
||||
|
||||
// Walks the tree in depth first order
|
||||
|
75
btree.tcc
75
btree.tcc
@ -277,7 +277,7 @@ btree(typename transaction_manager<BlockSize>::ptr tm,
|
||||
|
||||
write_ref root = tm_->new_block();
|
||||
|
||||
auto n = to_node<ValueTraits, BlockSize>(root);
|
||||
leaf_node n = to_node<ValueTraits, BlockSize>(root);
|
||||
n.set_type(btree_detail::LEAF);
|
||||
n.set_nr_entries(0);
|
||||
n.set_max_entries();
|
||||
@ -357,7 +357,7 @@ insert(key const &key,
|
||||
for (unsigned level = 0; level < Levels - 1; ++level) {
|
||||
bool need_insert = insert_location<uint64_traits>(spine, block, key[level], &index);
|
||||
|
||||
auto n = spine.template get_node<uint64_traits>();
|
||||
internal_node n = spine.template get_node<uint64_traits>();
|
||||
if (need_insert) {
|
||||
btree<Levels - 1, ValueTraits, BlockSize> new_tree(tm_, rc_);
|
||||
n.insert_at(index, key[level], new_tree.get_root());
|
||||
@ -368,7 +368,7 @@ insert(key const &key,
|
||||
|
||||
bool need_insert = insert_location<ValueTraits>(spine, block, key[Levels - 1], &index);
|
||||
|
||||
auto n = spine.template get_node<ValueTraits>();
|
||||
leaf_node n = spine.template get_node<ValueTraits>();
|
||||
if (need_insert)
|
||||
n.insert_at(index, key[Levels - 1], value);
|
||||
else
|
||||
@ -406,17 +406,17 @@ btree<Levels, ValueTraits, BlockSize>::clone() const
|
||||
ro_spine<BlockSize> spine(tm_);
|
||||
|
||||
spine.step(root_);
|
||||
auto new_root = tm_->new_block();
|
||||
write_ref new_root = tm_->new_block();
|
||||
|
||||
auto o = spine.template get_node<uint64_traits>();
|
||||
internal_node o = spine.template get_node<uint64_traits>();
|
||||
if (o.get_type() == INTERNAL) {
|
||||
auto n = to_node<uint64_traits, BlockSize>(new_root);
|
||||
internal_node n = to_node<uint64_traits, BlockSize>(new_root);
|
||||
::memcpy(n.raw(), o.raw(), BlockSize);
|
||||
|
||||
typename uint64_traits::ref_counter rc(internal_rc_);
|
||||
n.inc_children(rc);
|
||||
} else {
|
||||
auto n = to_node<ValueTraits, BlockSize>(new_root);
|
||||
leaf_node n = to_node<ValueTraits, BlockSize>(new_root);
|
||||
::memcpy(n.raw(), o.raw(), BlockSize);
|
||||
|
||||
typename ValueTraits::ref_counter rc(rc_);
|
||||
@ -447,7 +447,7 @@ split_node(btree_detail::shadow_spine<BlockSize> &spine,
|
||||
uint64_t key,
|
||||
bool top)
|
||||
{
|
||||
auto n = spine.template get_node<ValueTraits>();
|
||||
node_ref<ValueTraits, BlockSize> n = spine.template get_node<ValueTraits>();
|
||||
if (n.get_nr_entries() == n.get_max_entries()) {
|
||||
if (top)
|
||||
split_beneath<ValueTraits>(spine, key);
|
||||
@ -468,18 +468,18 @@ split_beneath(btree_detail::shadow_spine<BlockSize> &spine,
|
||||
node_type type;
|
||||
unsigned nr_left, nr_right;
|
||||
|
||||
auto left = tm_->new_block();
|
||||
auto l = to_node<ValueTraits, BlockSize>(left);
|
||||
write_ref left = tm_->new_block();
|
||||
node_ref<ValueTraits, BlockSize> l = to_node<ValueTraits, BlockSize>(left);
|
||||
l.set_nr_entries(0);
|
||||
l.set_max_entries();
|
||||
|
||||
auto right = tm_->new_block();
|
||||
auto r = to_node<ValueTraits, BlockSize>(right);
|
||||
write_ref right = tm_->new_block();
|
||||
node_ref<ValueTraits, BlockSize> r = to_node<ValueTraits, BlockSize>(right);
|
||||
r.set_nr_entries(0);
|
||||
r.set_max_entries();
|
||||
|
||||
{
|
||||
auto p = spine.template get_node<ValueTraits>();
|
||||
node_ref<ValueTraits, BlockSize> p = spine.template get_node<ValueTraits>();
|
||||
nr_left = p.get_nr_entries() / 2;
|
||||
nr_right = p.get_nr_entries() - nr_left;
|
||||
type = p.get_type();
|
||||
@ -493,10 +493,11 @@ split_beneath(btree_detail::shadow_spine<BlockSize> &spine,
|
||||
|
||||
{
|
||||
// The parent may have changed value type, so we re-get it.
|
||||
auto p = spine.template get_node<uint64_traits>();
|
||||
internal_node p = spine.template get_node<uint64_traits>();
|
||||
p.set_type(btree_detail::INTERNAL);
|
||||
p.set_nr_entries(2);
|
||||
|
||||
// FIXME: set the value_size
|
||||
p.overwrite_at(0, l.key_at(0), left.get_location());
|
||||
p.overwrite_at(1, r.key_at(0), right.get_location());
|
||||
}
|
||||
@ -517,11 +518,11 @@ split_sibling(btree_detail::shadow_spine<BlockSize> &spine,
|
||||
{
|
||||
using namespace btree_detail;
|
||||
|
||||
auto l = spine.template get_node<ValueTraits>();
|
||||
auto left = spine.get_block();
|
||||
node_ref<ValueTraits, BlockSize> l = spine.template get_node<ValueTraits>();
|
||||
block_address left = spine.get_block();
|
||||
|
||||
auto right = tm_->new_block();
|
||||
auto r = to_node<ValueTraits, BlockSize>(right);
|
||||
write_ref right = tm_->new_block();
|
||||
node_ref<ValueTraits, BlockSize> r = to_node<ValueTraits, BlockSize>(right);
|
||||
|
||||
unsigned nr_left = l.get_nr_entries() / 2;
|
||||
unsigned nr_right = l.get_nr_entries() - nr_left;
|
||||
@ -532,7 +533,7 @@ split_sibling(btree_detail::shadow_spine<BlockSize> &spine,
|
||||
r.copy_entries(l, nr_left, nr_left + nr_right);
|
||||
l.set_nr_entries(nr_left);
|
||||
|
||||
auto p = spine.get_parent();
|
||||
internal_node p = spine.get_parent();
|
||||
p.overwrite_at(parent_index, l.key_at(0), left);
|
||||
p.insert_at(parent_index + 1, r.key_at(0), right.get_location());
|
||||
|
||||
@ -568,11 +569,11 @@ insert_location(btree_detail::shadow_spine<BlockSize> &spine,
|
||||
|
||||
// patch up the parent to point to the new shadow
|
||||
if (spine.has_parent()) {
|
||||
auto p = spine.get_parent();
|
||||
internal_node p = spine.get_parent();
|
||||
p.set_value(i, spine.get_block());
|
||||
}
|
||||
|
||||
auto internal = spine.template get_node<uint64_traits>();
|
||||
internal_node internal = spine.template get_node<uint64_traits>();
|
||||
|
||||
// Split the node if we're full
|
||||
if (internal.get_type() == INTERNAL)
|
||||
@ -594,7 +595,7 @@ insert_location(btree_detail::shadow_spine<BlockSize> &spine,
|
||||
top = false;
|
||||
}
|
||||
|
||||
auto leaf = spine.template get_node<ValueTraits>();
|
||||
node_ref<ValueTraits, BlockSize> leaf = spine.template get_node<ValueTraits>();
|
||||
// FIXME: gross
|
||||
if (i < 0 || leaf.key_at(i) != key)
|
||||
i++;
|
||||
@ -626,21 +627,25 @@ walk_tree(typename visitor::ptr visitor,
|
||||
{
|
||||
using namespace btree_detail;
|
||||
|
||||
auto blk = tm_->read_lock(b);
|
||||
auto o = to_node<uint64_traits, BlockSize>(blk);
|
||||
if (o.get_type() == INTERNAL) {
|
||||
visitor->visit_internal(level, is_root, o);
|
||||
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
||||
walk_tree(visitor, level, false, o.value_at(i));
|
||||
try {
|
||||
read_ref blk = tm_->read_lock(b);
|
||||
internal_node o = to_node<uint64_traits, BlockSize>(blk);
|
||||
if (o.get_type() == INTERNAL) {
|
||||
visitor->visit_internal(level, is_root, o);
|
||||
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
||||
walk_tree(visitor, level, false, o.value_at(i));
|
||||
|
||||
} else if (level < Levels - 1) {
|
||||
visitor->visit_internal_leaf(level, is_root, o);
|
||||
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
||||
walk_tree(visitor, level + 1, true, o.value_at(i));
|
||||
} else if (level < Levels - 1) {
|
||||
visitor->visit_internal_leaf(level, is_root, o);
|
||||
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
||||
walk_tree(visitor, level + 1, true, o.value_at(i));
|
||||
|
||||
} else {
|
||||
leaf_node ov = to_node<ValueTraits, BlockSize>(blk);
|
||||
visitor->visit_leaf(level, is_root, ov);
|
||||
}
|
||||
} catch (...) { // FIXME: we should only catch terminate_walk type exceptions
|
||||
|
||||
} else {
|
||||
auto ov = to_node<ValueTraits, BlockSize>(blk);
|
||||
visitor->visit_leaf(level, is_root, ov);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,15 @@
|
||||
|
||||
#include "btree.h"
|
||||
|
||||
#include "error_set.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
using namespace persistent_data;
|
||||
using namespace std;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace persistent_data {
|
||||
@ -16,8 +21,10 @@ namespace persistent_data {
|
||||
//----------------------------------------------------------------
|
||||
class block_counter {
|
||||
public:
|
||||
typedef typename std::map<block_address, unsigned> count_map;
|
||||
|
||||
void inc(block_address b) {
|
||||
auto it = counts_.find(b);
|
||||
typename count_map::iterator it = counts_.find(b);
|
||||
if (it == counts_.end())
|
||||
counts_.insert(make_pair(b, 1));
|
||||
#if 0
|
||||
@ -27,16 +34,16 @@ namespace persistent_data {
|
||||
}
|
||||
|
||||
unsigned get_count(block_address b) const {
|
||||
auto it = counts_.find(b);
|
||||
count_map::const_iterator it = counts_.find(b);
|
||||
return (it == counts_.end()) ? 0 : it->second;
|
||||
}
|
||||
|
||||
std::map<block_address, unsigned> const &get_counts() const {
|
||||
count_map const &get_counts() const {
|
||||
return counts_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<block_address, unsigned> counts_;
|
||||
count_map counts_;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@ -63,7 +70,8 @@ namespace persistent_data {
|
||||
class btree_validator : public btree<Levels, ValueTraits, BlockSize>::visitor {
|
||||
public:
|
||||
btree_validator(block_counter &counter)
|
||||
: counter_(counter) {
|
||||
: counter_(counter),
|
||||
errs_(new error_set("btree errors")) {
|
||||
}
|
||||
|
||||
void visit_internal(unsigned level, bool is_root,
|
||||
@ -93,12 +101,17 @@ namespace persistent_data {
|
||||
check_nr_entries(n, is_root);
|
||||
}
|
||||
|
||||
boost::optional<error_set::ptr> get_errors() const {
|
||||
return errs_;
|
||||
}
|
||||
|
||||
private:
|
||||
void check_duplicate_block(block_address b) {
|
||||
if (seen_.count(b)) {
|
||||
std::ostringstream out;
|
||||
out << "duplicate block in btree: " << b;
|
||||
throw std::runtime_error(out.str());
|
||||
errs_->add_child(out.str());
|
||||
throw runtime_error(out.str());
|
||||
}
|
||||
|
||||
seen_.insert(b);
|
||||
@ -111,7 +124,8 @@ namespace persistent_data {
|
||||
out << "block number mismatch: actually "
|
||||
<< n.get_location()
|
||||
<< ", claims " << n.get_block_nr();
|
||||
throw std::runtime_error(out.str());
|
||||
errs_->add_child(out.str());
|
||||
throw runtime_error(out.str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,13 +135,14 @@ namespace persistent_data {
|
||||
if (elt_size * n.get_max_entries() + sizeof(node_header) > BlockSize) {
|
||||
std::ostringstream out;
|
||||
out << "max entries too large: " << n.get_max_entries();
|
||||
throw std::runtime_error(out.str());
|
||||
errs_->add_child(out.str());
|
||||
}
|
||||
|
||||
if (n.get_max_entries() % 3) {
|
||||
std::ostringstream out;
|
||||
out << "max entries is not divisible by 3: " << n.get_max_entries();
|
||||
throw std::runtime_error(out.str());
|
||||
errs_->add_child(out.str());
|
||||
throw runtime_error(out.str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,6 +153,7 @@ namespace persistent_data {
|
||||
out << "bad nr_entries: "
|
||||
<< n.get_nr_entries() << " < "
|
||||
<< n.get_max_entries();
|
||||
errs_->add_child(out.str());
|
||||
throw std::runtime_error(out.str());
|
||||
}
|
||||
|
||||
@ -148,12 +164,14 @@ namespace persistent_data {
|
||||
<< n.get_nr_entries()
|
||||
<< ", expected at least "
|
||||
<< min;
|
||||
errs_->add_child(out.str());
|
||||
throw runtime_error(out.str());
|
||||
}
|
||||
}
|
||||
|
||||
block_counter &counter_;
|
||||
std::set<block_address> seen_;
|
||||
error_set::ptr errs_;
|
||||
};
|
||||
}
|
||||
|
||||
|
25
error_set.cc
25
error_set.cc
@ -3,20 +3,21 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace persistent_data;
|
||||
using namespace std;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
error_set::error_set(std::string const &err)
|
||||
error_set::error_set(string const &err)
|
||||
: err_(err) {
|
||||
}
|
||||
|
||||
std::string const &
|
||||
string const &
|
||||
error_set::get_description() const
|
||||
{
|
||||
return err_;
|
||||
}
|
||||
|
||||
std::list<error_set::ptr> const &
|
||||
list<error_set::ptr> const &
|
||||
error_set::get_children() const
|
||||
{
|
||||
return children_;
|
||||
@ -29,7 +30,7 @@ error_set::add_child(error_set::ptr err)
|
||||
}
|
||||
|
||||
void
|
||||
error_set::add_child(std::string const &err)
|
||||
error_set::add_child(string const &err)
|
||||
{
|
||||
error_set::ptr e(new error_set(err));
|
||||
add_child(e);
|
||||
@ -38,21 +39,21 @@ error_set::add_child(std::string const &err)
|
||||
//--------------------------------
|
||||
|
||||
namespace {
|
||||
void indent_by(std::ostream &out, unsigned indent) {
|
||||
void indent_by(ostream &out, unsigned indent) {
|
||||
for (unsigned i = 0; i < indent; i++)
|
||||
out << ' ';
|
||||
}
|
||||
|
||||
void print_errs(std::ostream &out, error_set::ptr e, unsigned depth, unsigned indent) {
|
||||
void print_errs(ostream &out, error_set::ptr e, unsigned depth, unsigned indent) {
|
||||
if (depth == 0)
|
||||
return;
|
||||
|
||||
indent_by(out, indent);
|
||||
|
||||
out << e->get_description() << std::endl;
|
||||
out << e->get_description() << endl;
|
||||
if (depth > 1) {
|
||||
auto children = e->get_children();
|
||||
for (auto it = children.begin(); it != children.end(); ++it)
|
||||
list<error_set::ptr> const &children = e->get_children();
|
||||
for (list<error_set::ptr>::const_iterator it = children.begin(); it != children.end(); ++it)
|
||||
print_errs(out, *it, depth - 1, indent + 2);
|
||||
}
|
||||
}
|
||||
@ -65,13 +66,13 @@ error_selector::error_selector(error_set::ptr errs, unsigned depth)
|
||||
}
|
||||
|
||||
void
|
||||
error_selector::print(std::ostream &out) const
|
||||
error_selector::print(ostream &out) const
|
||||
{
|
||||
print_errs(out, errs_, depth_, 0);
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
persistent_data::operator << (std::ostream &out, error_selector const &errs)
|
||||
ostream &
|
||||
persistent_data::operator << (ostream &out, error_selector const &errs)
|
||||
{
|
||||
errs.print(out);
|
||||
return out;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <list>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
|
35
metadata.cc
35
metadata.cc
@ -35,7 +35,7 @@ namespace {
|
||||
|
||||
superblock read_superblock(block_manager<4096>::ptr bm) {
|
||||
superblock sb;
|
||||
auto r = bm->read_lock(SUPERBLOCK_LOCATION);
|
||||
block_manager<4096>::read_ref r = bm->read_lock(SUPERBLOCK_LOCATION);
|
||||
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data());
|
||||
superblock_traits::unpack(*sbd, sb);
|
||||
return sb;
|
||||
@ -70,7 +70,7 @@ namespace {
|
||||
data_counter_.inc(n.value_at(i).block_);
|
||||
}
|
||||
|
||||
set<uint64_t> get_devices() const {
|
||||
set<uint64_t> const &get_devices() const {
|
||||
return devices_;
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ namespace {
|
||||
devices_.insert(n.key_at(i));
|
||||
}
|
||||
|
||||
set<uint64_t> get_devices() const {
|
||||
set<uint64_t> const &get_devices() const {
|
||||
return devices_;
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ void
|
||||
thin::set_snapshot_time(uint32_t time)
|
||||
{
|
||||
uint64_t key[1] = { dev_ };
|
||||
auto mdetail = metadata_->details_.lookup(key);
|
||||
optional<device_details> mdetail = metadata_->details_.lookup(key);
|
||||
if (!mdetail)
|
||||
throw runtime_error("no such device");
|
||||
|
||||
@ -158,7 +158,7 @@ block_address
|
||||
thin::get_mapped_blocks() const
|
||||
{
|
||||
uint64_t key[1] = { dev_ };
|
||||
auto mdetail = metadata_->details_.lookup(key);
|
||||
optional<device_details> mdetail = metadata_->details_.lookup(key);
|
||||
if (!mdetail)
|
||||
throw runtime_error("no such device");
|
||||
|
||||
@ -169,7 +169,7 @@ void
|
||||
thin::set_mapped_blocks(block_address count)
|
||||
{
|
||||
uint64_t key[1] = { dev_ };
|
||||
auto mdetail = metadata_->details_.lookup(key);
|
||||
optional<device_details> mdetail = metadata_->details_.lookup(key);
|
||||
if (!mdetail)
|
||||
throw runtime_error("no such device");
|
||||
|
||||
@ -207,8 +207,8 @@ metadata::commit()
|
||||
sb_.data_mapping_root_ = mappings_.get_root();
|
||||
sb_.device_details_root_ = details_.get_root();
|
||||
|
||||
auto superblock = tm_->get_bm()->superblock(SUPERBLOCK_LOCATION);
|
||||
auto disk = reinterpret_cast<superblock_disk *>(superblock.data());
|
||||
write_ref superblock = tm_->get_bm()->superblock(SUPERBLOCK_LOCATION);
|
||||
superblock_disk *disk = reinterpret_cast<superblock_disk *>(superblock.data());
|
||||
superblock_traits::pack(sb_, *disk);
|
||||
}
|
||||
|
||||
@ -231,7 +231,7 @@ metadata::create_snap(thin_dev_t dev, thin_dev_t origin)
|
||||
uint64_t snap_key[1] = {dev};
|
||||
uint64_t origin_key[1] = {origin};
|
||||
|
||||
auto mtree_root = mappings_top_level_.lookup(origin_key);
|
||||
optional<uint64_t> mtree_root = mappings_top_level_.lookup(origin_key);
|
||||
if (!mtree_root)
|
||||
throw std::runtime_error("unknown origin");
|
||||
|
||||
@ -244,8 +244,8 @@ metadata::create_snap(thin_dev_t dev, thin_dev_t origin)
|
||||
|
||||
sb_.time_++;
|
||||
|
||||
auto o = open_thin(origin);
|
||||
auto s = open_thin(dev);
|
||||
thin::ptr o = open_thin(origin);
|
||||
thin::ptr s = open_thin(dev);
|
||||
o->set_snapshot_time(sb_.time_);
|
||||
s->set_snapshot_time(sb_.time_);
|
||||
s->set_mapped_blocks(o->get_mapped_blocks());
|
||||
@ -310,7 +310,7 @@ thin::ptr
|
||||
metadata::open_thin(thin_dev_t dev)
|
||||
{
|
||||
uint64_t key[1] = {dev};
|
||||
auto mdetails = details_.lookup(key);
|
||||
optional<device_details> mdetails = details_.lookup(key);
|
||||
if (!mdetails)
|
||||
throw runtime_error("no such device");
|
||||
|
||||
@ -336,13 +336,13 @@ metadata::check()
|
||||
mapping_validator::ptr mv(new mapping_validator(metadata_counter,
|
||||
data_counter));
|
||||
mappings_.visit(mv);
|
||||
auto mapped_devs = mv->get_devices();
|
||||
set<uint64_t> const &mapped_devs = mv->get_devices();
|
||||
|
||||
details_validator::ptr dv(new details_validator(metadata_counter));
|
||||
details_.visit(dv);
|
||||
auto details_devs = dv->get_devices();
|
||||
set<uint64_t> const &details_devs = dv->get_devices();
|
||||
|
||||
for (auto it = mapped_devs.begin(); it != mapped_devs.end(); ++it)
|
||||
for (set<uint64_t>::const_iterator it = mapped_devs.begin(); it != mapped_devs.end(); ++it)
|
||||
if (details_devs.count(*it) == 0) {
|
||||
ostringstream out;
|
||||
out << "mapping exists for device " << *it
|
||||
@ -356,8 +356,9 @@ metadata::check()
|
||||
error_set::ptr data_errors(new error_set("Errors in data reference counts"));
|
||||
|
||||
bool bad = false;
|
||||
auto data_counts = data_counter.get_counts();
|
||||
for (auto it = data_counts.begin(); it != data_counts.end(); ++it) {
|
||||
block_counter::count_map const &data_counts = data_counter.get_counts();
|
||||
for (block_counter::count_map::const_iterator it = data_counts.begin();
|
||||
it != data_counts.end(); ++it) {
|
||||
uint32_t ref_count = data_sm_->get_count(it->first);
|
||||
if (ref_count != it->second) {
|
||||
ostringstream out;
|
||||
|
@ -146,6 +146,8 @@ namespace thin_provisioning {
|
||||
class metadata {
|
||||
public:
|
||||
typedef boost::shared_ptr<metadata> ptr;
|
||||
typedef typename block_manager<MD_BLOCK_SIZE>::read_ref read_ref;
|
||||
typedef typename block_manager<MD_BLOCK_SIZE>::write_ref write_ref;
|
||||
|
||||
metadata(std::string const &dev_path);
|
||||
~metadata();
|
||||
|
@ -19,6 +19,9 @@ namespace persistent_data {
|
||||
template <uint32_t BlockSize>
|
||||
class bitmap {
|
||||
public:
|
||||
typedef typename transaction_manager<BlockSize>::read_ref read_ref;
|
||||
typedef typename transaction_manager<BlockSize>::write_ref write_ref;
|
||||
|
||||
bitmap(typename transaction_manager<BlockSize>::ptr tm,
|
||||
index_entry const &ie)
|
||||
: tm_(tm),
|
||||
@ -26,7 +29,7 @@ namespace persistent_data {
|
||||
}
|
||||
|
||||
ref_t lookup(unsigned b) const {
|
||||
auto rr = tm_->read_lock(ie_.blocknr_);
|
||||
read_ref rr = tm_->read_lock(ie_.blocknr_);
|
||||
void const *bits = bitmap_data(rr);
|
||||
ref_t b1 = test_bit_le(bits, b * 2);
|
||||
ref_t b2 = test_bit_le(bits, b * 2 + 1);
|
||||
@ -36,7 +39,7 @@ namespace persistent_data {
|
||||
}
|
||||
|
||||
void insert(unsigned b, ref_t n) {
|
||||
auto wr = tm_->shadow(ie_.blocknr_).first;
|
||||
write_ref wr = tm_->shadow(ie_.blocknr_).first;
|
||||
void *bits = bitmap_data(wr);
|
||||
bool was_free = !test_bit_le(bits, b * 2) && !test_bit_le(bits, b * 2 + 1);
|
||||
if (n == 1 || n == 3)
|
||||
@ -113,6 +116,8 @@ namespace persistent_data {
|
||||
class sm_disk_base : public persistent_space_map {
|
||||
public:
|
||||
typedef boost::shared_ptr<sm_disk_base<BlockSize> > ptr;
|
||||
typedef typename transaction_manager<BlockSize>::read_ref read_ref;
|
||||
typedef typename transaction_manager<BlockSize>::write_ref write_ref;
|
||||
|
||||
sm_disk_base(typename transaction_manager<BlockSize>::ptr tm)
|
||||
: tm_(tm),
|
||||
@ -140,7 +145,7 @@ namespace persistent_data {
|
||||
}
|
||||
|
||||
ref_t get_count(block_address b) const {
|
||||
auto count = lookup_bitmap(b);
|
||||
ref_t count = lookup_bitmap(b);
|
||||
if (count == 3)
|
||||
return lookup_ref_count(b);
|
||||
|
||||
@ -188,7 +193,7 @@ namespace persistent_data {
|
||||
// beginning.
|
||||
block_address nr_indexes = div_up<block_address>(nr_blocks_, entries_per_block_);
|
||||
for (block_address index = 0; index < nr_indexes; index++) {
|
||||
auto ie = find_ie(index);
|
||||
index_entry ie = find_ie(index);
|
||||
|
||||
bitmap<BlockSize> bm(tm_, ie);
|
||||
block_address b = bm.find_free((index == nr_indexes - 1) ?
|
||||
@ -213,7 +218,7 @@ namespace persistent_data {
|
||||
block_address bitmap_count = div_up<block_address>(nr_blocks, entries_per_block_);
|
||||
block_address old_bitmap_count = div_up<block_address>(nr_blocks_, entries_per_block_);
|
||||
for (block_address i = old_bitmap_count; i < bitmap_count; i++) {
|
||||
auto wr = tm_->new_block();
|
||||
write_ref wr = tm_->new_block();
|
||||
|
||||
struct index_entry ie;
|
||||
ie.blocknr_ = wr.get_location();
|
||||
@ -258,7 +263,7 @@ namespace persistent_data {
|
||||
if (n > 3)
|
||||
throw runtime_error("bitmap can only hold 2 bit values");
|
||||
|
||||
auto ie = find_ie(b);
|
||||
index_entry ie = find_ie(b);
|
||||
bitmap<BlockSize> bm(tm_, ie);
|
||||
bm.insert(b % entries_per_block_, n);
|
||||
save_ie(b, bm.get_ie());
|
||||
@ -266,7 +271,7 @@ namespace persistent_data {
|
||||
|
||||
ref_t lookup_ref_count(block_address b) const {
|
||||
uint64_t key[1] = {b};
|
||||
auto mvalue = ref_counts_.lookup(key);
|
||||
optional<ref_t> mvalue = ref_counts_.lookup(key);
|
||||
if (!mvalue)
|
||||
throw runtime_error("ref count not in tree");
|
||||
return *mvalue;
|
||||
@ -343,7 +348,7 @@ namespace persistent_data {
|
||||
private:
|
||||
index_entry find_ie(block_address b) const {
|
||||
uint64_t key[1] = {b / sm_disk_base<BlockSize>::get_entries_per_block()};
|
||||
auto mindex = bitmaps_.lookup(key);
|
||||
optional<index_entry> mindex = bitmaps_.lookup(key);
|
||||
if (!mindex)
|
||||
throw runtime_error("Couldn't lookup bitmap");
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "metadata.h"
|
||||
|
||||
using namespace boost;
|
||||
using namespace persistent_data;
|
||||
using namespace std;
|
||||
using namespace thin_provisioning;
|
||||
@ -10,7 +11,7 @@ namespace {
|
||||
int check(string const &path) {
|
||||
metadata md(path);
|
||||
|
||||
auto maybe_errors = md.check();
|
||||
optional<error_set::ptr> maybe_errors = md.check();
|
||||
if (maybe_errors) {
|
||||
cerr << error_selector(*maybe_errors, 3);
|
||||
return 1;
|
||||
|
@ -25,7 +25,7 @@ template <uint32_t BlockSize>
|
||||
typename transaction_manager<BlockSize>::write_ref
|
||||
transaction_manager<BlockSize>::begin(block_address superblock)
|
||||
{
|
||||
auto wr = bm_->superblock(superblock);
|
||||
write_ref wr = bm_->superblock(superblock);
|
||||
wipe_shadow_table();
|
||||
return wr;
|
||||
}
|
||||
@ -35,7 +35,7 @@ typename transaction_manager<BlockSize>::write_ref
|
||||
transaction_manager<BlockSize>::begin(block_address superblock,
|
||||
validator v)
|
||||
{
|
||||
auto wr = bm_->superblock(superblock, v);
|
||||
write_ref wr = bm_->superblock(superblock, v);
|
||||
wipe_shadow_table();
|
||||
return wr;
|
||||
}
|
||||
@ -89,8 +89,8 @@ transaction_manager<BlockSize>::shadow(block_address orig)
|
||||
!sm_->count_possibly_greater_than_one(orig))
|
||||
return make_pair(bm_->write_lock(orig), false);
|
||||
|
||||
auto src = bm_->read_lock(orig);
|
||||
auto dest = bm_->write_lock_zero(sm_->new_block());
|
||||
read_ref src = bm_->read_lock(orig);
|
||||
write_ref dest = bm_->write_lock_zero(sm_->new_block());
|
||||
::memcpy(dest.data(), src.data(), BlockSize);
|
||||
|
||||
ref_t count = sm_->get_count(orig);
|
||||
@ -110,8 +110,8 @@ transaction_manager<BlockSize>::shadow(block_address orig, validator v)
|
||||
sm_->count_possibly_greater_than_one(orig))
|
||||
return make_pair(bm_->write_lock(orig), false);
|
||||
|
||||
auto src = bm_->read_lock(orig, v);
|
||||
auto dest = bm_->write_lock_zero(sm_->new_block(), v);
|
||||
read_ref src = bm_->read_lock(orig, v);
|
||||
write_ref dest = bm_->write_lock_zero(sm_->new_block(), v);
|
||||
::memcpy(dest->data_, src->data_, BlockSize);
|
||||
|
||||
ref_t count = sm_->get_count(orig);
|
||||
|
Loading…
Reference in New Issue
Block a user