put space map checking back in
This commit is contained in:
parent
2f1789744f
commit
9f6546f621
@ -288,23 +288,8 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------
|
|
||||||
|
|
||||||
struct ablock_counter {
|
|
||||||
ablock_counter(block_counter &bc)
|
|
||||||
: bc_(bc) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void visit(btree_detail::node_location const &loc, block_address b) {
|
|
||||||
bc_.inc(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
block_counter &bc_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void count_metadata_blocks(block_counter &bc) const {
|
void count_metadata_blocks(block_counter &bc) const {
|
||||||
ablock_counter vc(bc);
|
block_address_counter vc(bc);
|
||||||
count_btree_blocks(block_tree_, bc, vc);
|
count_btree_blocks(block_tree_, bc, vc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef PERSISTENT_DATA_DATA_STRUCTURES_BTREE_COUNTER_H
|
#ifndef PERSISTENT_DATA_DATA_STRUCTURES_BTREE_COUNTER_H
|
||||||
#define PERSISTENT_DATA_DATA_STRUCTURES_BTREE_COUNTER_H
|
#define PERSISTENT_DATA_DATA_STRUCTURES_BTREE_COUNTER_H
|
||||||
|
|
||||||
|
#include "persistent-data/data-structures/btree.h"
|
||||||
#include "persistent-data/block_counter.h"
|
#include "persistent-data/block_counter.h"
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
@ -65,6 +66,19 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct block_address_counter {
|
||||||
|
block_address_counter(block_counter &bc)
|
||||||
|
: bc_(bc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void visit(btree_detail::node_location const &loc, block_address b) {
|
||||||
|
bc_.inc(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
block_counter &bc_;
|
||||||
|
};
|
||||||
|
|
||||||
// Counts how many times each metadata block is referenced in the
|
// Counts how many times each metadata block is referenced in the
|
||||||
// tree. Blocks already referenced in the block counter are not
|
// tree. Blocks already referenced in the block counter are not
|
||||||
// walked. This walk should only be done once you're sure the tree
|
// walked. This walk should only be done once you're sure the tree
|
||||||
|
@ -89,6 +89,10 @@ namespace {
|
|||||||
sm_->iterate(it);
|
sm_->iterate(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void count_metadata(block_counter &bc) const {
|
||||||
|
sm_->count_metadata(bc);
|
||||||
|
}
|
||||||
|
|
||||||
virtual size_t root_size() const {
|
virtual size_t root_size() const {
|
||||||
return sm_->root_size();
|
return sm_->root_size();
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,9 @@ namespace persistent_data {
|
|||||||
throw std::runtime_error("'extend' not implemented");
|
throw std::runtime_error("'extend' not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void count_metadata(block_counter &bc) const {
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: meaningless, but this class is only used for testing
|
// FIXME: meaningless, but this class is only used for testing
|
||||||
size_t root_size() const {
|
size_t root_size() const {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "persistent-data/space-maps/careful_alloc.h"
|
#include "persistent-data/space-maps/careful_alloc.h"
|
||||||
|
|
||||||
#include "persistent-data/data-structures/btree_damage_visitor.h"
|
#include "persistent-data/data-structures/btree_damage_visitor.h"
|
||||||
|
#include "persistent-data/data-structures/btree_counter.h"
|
||||||
#include "persistent-data/checksum.h"
|
#include "persistent-data/checksum.h"
|
||||||
#include "persistent-data/endian_utils.h"
|
#include "persistent-data/endian_utils.h"
|
||||||
#include "persistent-data/math_utils.h"
|
#include "persistent-data/math_utils.h"
|
||||||
@ -222,6 +223,7 @@ namespace {
|
|||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<index_store> ptr;
|
typedef boost::shared_ptr<index_store> ptr;
|
||||||
|
|
||||||
|
virtual void count_metadata(block_counter &bc) const = 0;
|
||||||
virtual void resize(block_address nr_indexes) = 0;
|
virtual void resize(block_address nr_indexes) = 0;
|
||||||
virtual index_entry find_ie(block_address b) const = 0;
|
virtual index_entry find_ie(block_address b) const = 0;
|
||||||
virtual void save_ie(block_address b, struct index_entry ie) = 0;
|
virtual void save_ie(block_address b, struct index_entry ie) = 0;
|
||||||
@ -405,6 +407,13 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void count_metadata(block_counter &bc) const {
|
||||||
|
indexes_->count_metadata(bc);
|
||||||
|
|
||||||
|
noop_value_counter<uint32_t> vc;
|
||||||
|
count_btree_blocks(ref_counts_, bc, vc);
|
||||||
|
}
|
||||||
|
|
||||||
virtual size_t root_size() const {
|
virtual size_t root_size() const {
|
||||||
return sizeof(sm_root_disk);
|
return sizeof(sm_root_disk);
|
||||||
}
|
}
|
||||||
@ -554,6 +563,29 @@ namespace {
|
|||||||
bitmaps_(tm, root, index_entry_traits::ref_counter()) {
|
bitmaps_(tm, root, index_entry_traits::ref_counter()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
struct index_entry_counter {
|
||||||
|
index_entry_counter(block_counter &bc)
|
||||||
|
: bc_(bc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void visit(btree_detail::node_location const &loc, index_entry const &ie) {
|
||||||
|
if (ie.blocknr_ != 0)
|
||||||
|
bc_.inc(ie.blocknr_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
block_counter &bc_;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void count_metadata(block_counter &bc) const {
|
||||||
|
index_entry_counter vc(bc);
|
||||||
|
count_btree_blocks(bitmaps_, bc, vc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
virtual void resize(block_address nr_entries) {
|
virtual void resize(block_address nr_entries) {
|
||||||
// No op
|
// No op
|
||||||
}
|
}
|
||||||
@ -612,6 +644,15 @@ namespace {
|
|||||||
load_ies();
|
load_ies();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void count_metadata(block_counter &bc) const {
|
||||||
|
for (unsigned i = 0; i < entries_.size(); i++) {
|
||||||
|
block_address b = entries_[i].blocknr_;
|
||||||
|
|
||||||
|
if (b != 0)
|
||||||
|
bc.inc(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void resize(block_address nr_indexes) {
|
virtual void resize(block_address nr_indexes) {
|
||||||
entries_.resize(nr_indexes);
|
entries_.resize(nr_indexes);
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,10 @@ namespace {
|
|||||||
sm_->iterate(it);
|
sm_->iterate(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void count_metadata(block_counter &bc) const {
|
||||||
|
sm_->count_metadata(bc);
|
||||||
|
}
|
||||||
|
|
||||||
virtual size_t root_size() const {
|
virtual size_t root_size() const {
|
||||||
cant_recurse("root_size");
|
cant_recurse("root_size");
|
||||||
recursing_const_lock lock(*this);
|
recursing_const_lock lock(*this);
|
||||||
|
@ -141,6 +141,7 @@ namespace persistent_data {
|
|||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<persistent_space_map> ptr;
|
typedef boost::shared_ptr<persistent_space_map> ptr;
|
||||||
|
|
||||||
|
virtual void count_metadata(block_counter &bc) const = 0;
|
||||||
virtual size_t root_size() const = 0;
|
virtual size_t root_size() const = 0;
|
||||||
virtual void copy_root(void *dest, size_t len) const = 0;
|
virtual void copy_root(void *dest, size_t len) const = 0;
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
|
|
||||||
#include "base/error_state.h"
|
#include "base/error_state.h"
|
||||||
#include "base/nested_output.h"
|
#include "base/nested_output.h"
|
||||||
|
#include "persistent-data/data-structures/btree_counter.h"
|
||||||
#include "persistent-data/space-maps/core.h"
|
#include "persistent-data/space-maps/core.h"
|
||||||
|
#include "persistent-data/space-maps/disk.h"
|
||||||
#include "persistent-data/file_utils.h"
|
#include "persistent-data/file_utils.h"
|
||||||
#include "thin-provisioning/device_tree.h"
|
#include "thin-provisioning/device_tree.h"
|
||||||
#include "thin-provisioning/mapping_tree.h"
|
#include "thin-provisioning/mapping_tree.h"
|
||||||
@ -209,9 +211,71 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return combine_errors(sb_rep.get_error(),
|
error_state mplus_err = combine_errors(sb_rep.get_error(),
|
||||||
combine_errors(mapping_rep.get_error(),
|
combine_errors(mapping_rep.get_error(),
|
||||||
dev_rep.get_error()));
|
dev_rep.get_error()));
|
||||||
|
|
||||||
|
// if we're checking everything, and there were no errors,
|
||||||
|
// then we should check the space maps too.
|
||||||
|
if (fs.check_device_tree && fs.check_mapping_tree_level2 && mplus_err == NO_ERROR) {
|
||||||
|
out << "checking space map counts" << end_message();
|
||||||
|
{
|
||||||
|
nested_output::nest _ = out.push();
|
||||||
|
block_counter bc;
|
||||||
|
|
||||||
|
// Count the device tree
|
||||||
|
{
|
||||||
|
noop_value_counter<device_tree_detail::device_details> vc;
|
||||||
|
device_tree dtree(tm, sb.device_details_root_,
|
||||||
|
device_tree_detail::device_details_traits::ref_counter());
|
||||||
|
count_btree_blocks(dtree, bc, vc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the mapping tree
|
||||||
|
{
|
||||||
|
noop_value_counter<mapping_tree_detail::block_time> vc;
|
||||||
|
mapping_tree mtree(tm, sb.data_mapping_root_,
|
||||||
|
mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
|
||||||
|
count_btree_blocks(mtree, bc, vc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the metadata space map
|
||||||
|
{
|
||||||
|
persistent_space_map::ptr metadata_sm =
|
||||||
|
open_metadata_sm(tm, static_cast<void *>(&sb.metadata_space_map_root_));
|
||||||
|
metadata_sm->count_metadata(bc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the data space map
|
||||||
|
{
|
||||||
|
persistent_space_map::ptr data_sm =
|
||||||
|
open_disk_sm(tm, static_cast<void *>(&sb.data_space_map_root_));
|
||||||
|
data_sm->count_metadata(bc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally we need to check the metadata
|
||||||
|
// space map agrees with the counts we've
|
||||||
|
// just calculated.
|
||||||
|
{
|
||||||
|
persistent_space_map::ptr metadata_sm =
|
||||||
|
open_metadata_sm(tm, static_cast<void *>(&sb.metadata_space_map_root_));
|
||||||
|
for (unsigned b = 0; b < metadata_sm->get_nr_blocks(); b++) {
|
||||||
|
ref_t c_actual = metadata_sm->get_count(b);
|
||||||
|
ref_t c_expected = bc.get_count(b);
|
||||||
|
|
||||||
|
if (c_actual != c_expected) {
|
||||||
|
out << "metadata reference counts differ for block " << b
|
||||||
|
<< ", expected " << c_expected
|
||||||
|
<< ", but got " << c_actual
|
||||||
|
<< end_message();
|
||||||
|
mplus_err = combine_errors(mplus_err, FATAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mplus_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int check(string const &path, flags fs) {
|
int check(string const &path, flags fs) {
|
||||||
|
Loading…
Reference in New Issue
Block a user