[thin_repair] speed up ref count validation
This commit is contained in:
parent
d02fcde793
commit
13e26684f7
2
Makefile
2
Makefile
@ -17,7 +17,7 @@ SOURCE=\
|
|||||||
|
|
||||||
OBJECTS=$(subst .cc,.o,$(SOURCE))
|
OBJECTS=$(subst .cc,.o,$(SOURCE))
|
||||||
TOP_DIR:=$(PWD)
|
TOP_DIR:=$(PWD)
|
||||||
CPPFLAGS=-Wall -g -I$(TOP_DIR)
|
CPPFLAGS=-Wall -g -I$(TOP_DIR) -O8
|
||||||
#CPPFLAGS=-Wall -std=c++0x -g -I$(TOP_DIR)
|
#CPPFLAGS=-Wall -std=c++0x -g -I$(TOP_DIR)
|
||||||
LIBS=-lstdc++ -lboost_program_options
|
LIBS=-lstdc++ -lboost_program_options
|
||||||
|
|
||||||
|
34
metadata.cc
34
metadata.cc
@ -3,6 +3,7 @@
|
|||||||
#include "btree_checker.h"
|
#include "btree_checker.h"
|
||||||
#include "core_map.h"
|
#include "core_map.h"
|
||||||
#include "math_utils.h"
|
#include "math_utils.h"
|
||||||
|
#include "space_map_disk.h"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -396,26 +397,37 @@ metadata::device_exists(thin_dev_t dev) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
optional<error_set::ptr>
|
struct check_count : public space_map::iterator {
|
||||||
check_ref_counts(string const &desc, block_counter const &counts,
|
check_count(string const &desc, block_counter const &expected)
|
||||||
space_map::ptr sm) {
|
: bad_(false),
|
||||||
error_set::ptr errors(new error_set(desc));
|
expected_(expected),
|
||||||
|
errors_(new error_set(desc)) {
|
||||||
|
}
|
||||||
|
|
||||||
bool bad = false;
|
virtual void operator() (block_address b, ref_t actual) {
|
||||||
for (block_address b = 0; b < sm->get_nr_blocks(); b++) {
|
ref_t expected = expected_.get_count(b);
|
||||||
uint32_t actual = sm->get_count(b);
|
|
||||||
uint32_t expected = counts.get_count(b);
|
|
||||||
|
|
||||||
if (actual != expected) {
|
if (actual != expected) {
|
||||||
ostringstream out;
|
ostringstream out;
|
||||||
out << b << ": was " << actual
|
out << b << ": was " << actual
|
||||||
<< ", expected " << expected;
|
<< ", expected " << expected;
|
||||||
errors->add_child(out.str());
|
errors_->add_child(out.str());
|
||||||
bad = true;
|
bad_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bad ? optional<error_set::ptr>(errors) : optional<error_set::ptr>();
|
bool bad_;
|
||||||
|
block_counter const &expected_;
|
||||||
|
error_set::ptr errors_;
|
||||||
|
};
|
||||||
|
|
||||||
|
optional<error_set::ptr>
|
||||||
|
check_ref_counts(string const &desc, block_counter const &counts,
|
||||||
|
space_map::ptr sm) {
|
||||||
|
|
||||||
|
check_count checker(desc, counts);
|
||||||
|
sm->iterate(checker);
|
||||||
|
return checker.bad_ ? optional<error_set::ptr>(checker.errors_) : optional<error_set::ptr>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
space_map.h
10
space_map.h
@ -29,6 +29,16 @@ namespace persistent_data {
|
|||||||
virtual bool count_possibly_greater_than_one(block_address b) const = 0;
|
virtual bool count_possibly_greater_than_one(block_address b) const = 0;
|
||||||
|
|
||||||
virtual void extend(block_address extra_blocks) = 0;
|
virtual void extend(block_address extra_blocks) = 0;
|
||||||
|
|
||||||
|
struct iterator {
|
||||||
|
virtual ~iterator() {}
|
||||||
|
|
||||||
|
virtual void operator() (block_address b, ref_t c) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void iterate(iterator &it) const {
|
||||||
|
throw std::runtime_error("not implemented");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class persistent_space_map : public space_map {
|
class persistent_space_map : public space_map {
|
||||||
|
@ -80,6 +80,19 @@ namespace {
|
|||||||
return ie_;
|
return ie_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iterate(block_address offset, block_address hi, space_map::iterator &it) const {
|
||||||
|
read_ref rr = tm_->read_lock(ie_.blocknr_);
|
||||||
|
void const *bits = bitmap_data(rr);
|
||||||
|
|
||||||
|
for (unsigned b = 0; b < hi; b++) {
|
||||||
|
ref_t b1 = test_bit_le(bits, b * 2);
|
||||||
|
ref_t b2 = test_bit_le(bits, b * 2 + 1);
|
||||||
|
ref_t result = b2 ? 1 : 0;
|
||||||
|
result |= b1 ? 0b10 : 0;
|
||||||
|
it(offset + b, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void check_crc(transaction_manager::read_ref &rr) {
|
void check_crc(transaction_manager::read_ref &rr) {
|
||||||
crc32c sum(240779);
|
crc32c sum(240779);
|
||||||
@ -248,6 +261,34 @@ namespace {
|
|||||||
ref_counts_.visit(v);
|
ref_counts_.visit(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct look_aside_iterator : public iterator {
|
||||||
|
look_aside_iterator(sm_disk_base const &smd, iterator &it)
|
||||||
|
: smd_(smd),
|
||||||
|
it_(it) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator () (block_address b, ref_t c) {
|
||||||
|
it_(b, c == 3 ? smd_.lookup_ref_count(b) : c);
|
||||||
|
}
|
||||||
|
|
||||||
|
sm_disk_base const &smd_;
|
||||||
|
iterator &it_;
|
||||||
|
};
|
||||||
|
|
||||||
|
friend struct look_aside_iterator;
|
||||||
|
|
||||||
|
virtual void iterate(iterator &it) const {
|
||||||
|
look_aside_iterator wrapper(*this, it);
|
||||||
|
unsigned nr_indexes = div_up<block_address>(nr_blocks_, entries_per_block_);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < nr_indexes; i++) {
|
||||||
|
unsigned hi = (i == nr_indexes - 1) ? (nr_blocks_ % entries_per_block_) : entries_per_block_;
|
||||||
|
index_entry ie = find_ie(i);
|
||||||
|
bitmap bm(tm_, ie);
|
||||||
|
bm.iterate(i * entries_per_block_, hi, wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
transaction_manager::ptr get_tm() const {
|
transaction_manager::ptr get_tm() const {
|
||||||
return tm_;
|
return tm_;
|
||||||
|
Loading…
Reference in New Issue
Block a user