thin-provisioning-tools/thin-provisioning/device_checker.cc

104 lines
2.6 KiB
C++
Raw Normal View History

2013-04-29 17:54:19 +05:30
#include "thin-provisioning/device_checker.h"
2013-04-29 20:07:53 +05:30
#include "persistent-data/data-structures/btree_checker.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;
2013-04-29 17:54:19 +05:30
using namespace thin_provisioning;
//----------------------------------------------------------------
2013-04-29 20:07:53 +05:30
namespace {
// FIXME: duplication with metadata.cc
transaction_manager::ptr
open_tm(block_manager<>::ptr bm) {
space_map::ptr sm(new core_map(bm->get_nr_blocks()));
sm->inc(SUPERBLOCK_LOCATION);
transaction_manager::ptr tm(new transaction_manager(bm, sm));
return tm;
}
class device_visitor : public btree<1, device_details_traits>::visitor {
public:
typedef boost::shared_ptr<device_visitor> ptr;
typedef btree_checker<1, device_details_traits> checker;
device_visitor(block_counter &counter)
: checker_(counter) {
}
bool visit_internal(unsigned level,
bool sub_root,
optional<uint64_t> key,
btree_detail::node_ref<uint64_traits> const &n) {
return checker_.visit_internal(level, sub_root, key, n);
}
bool visit_internal_leaf(unsigned level,
bool sub_root,
optional<uint64_t> key,
btree_detail::node_ref<uint64_traits> const &n) {
return checker_.visit_internal_leaf(level, sub_root, key, n);
}
bool visit_leaf(unsigned level,
bool sub_root,
optional<uint64_t> key,
btree_detail::node_ref<device_details_traits> const &n) {
if (!checker_.visit_leaf(level, sub_root, key, n))
return false;
for (unsigned i = 0; i < n.get_nr_entries(); i++)
devices_.insert(n.key_at(i));
return true;
}
set<uint64_t> const &get_devices() const {
return devices_;
}
private:
checker checker_;
set<uint64_t> devices_;
};
}
//----------------------------------------------------------------
device_checker::device_checker(block_manager::ptr bm,
block_address root)
: checker(bm),
root_(root)
2013-04-29 17:54:19 +05:30
{
}
damage_list_ptr
device_checker::check()
{
2013-04-29 20:07:53 +05:30
block_counter counter;
device_visitor::ptr v(new device_visitor(counter));
transaction_manager::ptr tm(open_tm(bm_));
detail_tree::ptr details(new detail_tree(tm, root_,
device_details_traits::ref_counter()));
damage_list_ptr damage(new damage_list);
try {
details->visit(v);
} catch (std::exception const &e) {
metadata_damage::ptr d(new missing_device_details(range64()));
damage->push_back(d);
}
return damage;
2013-04-29 17:54:19 +05:30
}
//----------------------------------------------------------------