[metadata_checker] Support in-place metadata space map modification
This commit is contained in:
parent
0349e9c9e2
commit
6c90f9483e
@ -69,6 +69,12 @@ namespace persistent_data {
|
|||||||
bm_->prefetch(b);
|
bm_->prefetch(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mark a block as shadowed,
|
||||||
|
// for the purpose of in-place modification
|
||||||
|
void mark_shadowed(block_address b) {
|
||||||
|
add_shadow(b);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void add_shadow(block_address b);
|
void add_shadow(block_address b);
|
||||||
void remove_shadow(block_address b);
|
void remove_shadow(block_address b);
|
||||||
|
@ -274,6 +274,17 @@ namespace {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mark_sm_shadowed(transaction_manager::ptr tm, persistent_space_map::ptr sm) {
|
||||||
|
block_counter bc(true);
|
||||||
|
sm->count_metadata(bc);
|
||||||
|
|
||||||
|
block_address nr_blocks = sm->get_nr_blocks();
|
||||||
|
for (block_address b = 0; b < nr_blocks; b++) {
|
||||||
|
if (bc.get_count(b))
|
||||||
|
tm->mark_shadowed(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
error_state clear_leaked_blocks(space_map::ptr actual,
|
error_state clear_leaked_blocks(space_map::ptr actual,
|
||||||
block_counter const &expected) {
|
block_counter const &expected) {
|
||||||
error_state err = NO_ERROR;
|
error_state err = NO_ERROR;
|
||||||
@ -410,7 +421,7 @@ namespace {
|
|||||||
optional<space_map::ptr>());
|
optional<space_map::ptr>());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fix_metadata_leaks() {
|
bool fix_metadata_leaks(bool open_transaction) {
|
||||||
if (!verify_preconditions_before_fixing()) {
|
if (!verify_preconditions_before_fixing()) {
|
||||||
out_ << "metadata has not been fully examined" << end_message();
|
out_ << "metadata has not been fully examined" << end_message();
|
||||||
return false;
|
return false;
|
||||||
@ -429,6 +440,9 @@ namespace {
|
|||||||
open_metadata_sm(*tm, static_cast<void const*>(&sb.metadata_space_map_root_));
|
open_metadata_sm(*tm, static_cast<void const*>(&sb.metadata_space_map_root_));
|
||||||
tm->set_sm(metadata_sm);
|
tm->set_sm(metadata_sm);
|
||||||
|
|
||||||
|
if (!open_transaction)
|
||||||
|
mark_sm_shadowed(tm, metadata_sm);
|
||||||
|
|
||||||
err_ = clear_leaked_blocks(metadata_sm, expected_rc_);
|
err_ = clear_leaked_blocks(metadata_sm, expected_rc_);
|
||||||
|
|
||||||
if (err_ != NO_ERROR)
|
if (err_ != NO_ERROR)
|
||||||
@ -562,7 +576,8 @@ check_options::check_options()
|
|||||||
sm_opts_(SPACE_MAP_FULL),
|
sm_opts_(SPACE_MAP_FULL),
|
||||||
ignore_non_fatal_(false),
|
ignore_non_fatal_(false),
|
||||||
fix_metadata_leaks_(false),
|
fix_metadata_leaks_(false),
|
||||||
clear_needs_check_(false) {
|
clear_needs_check_(false),
|
||||||
|
open_transaction_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_options::set_superblock_only() {
|
void check_options::set_superblock_only() {
|
||||||
@ -634,7 +649,7 @@ thin_provisioning::check_metadata(std::string const &path,
|
|||||||
|
|
||||||
checker.check();
|
checker.check();
|
||||||
if (check_opts.fix_metadata_leaks_)
|
if (check_opts.fix_metadata_leaks_)
|
||||||
checker.fix_metadata_leaks();
|
checker.fix_metadata_leaks(check_opts.open_transaction_);
|
||||||
if (check_opts.fix_metadata_leaks_ ||
|
if (check_opts.fix_metadata_leaks_ ||
|
||||||
check_opts.clear_needs_check_)
|
check_opts.clear_needs_check_)
|
||||||
checker.clear_needs_check_flag();
|
checker.clear_needs_check_flag();
|
||||||
|
@ -55,6 +55,7 @@ namespace thin_provisioning {
|
|||||||
bool ignore_non_fatal_;
|
bool ignore_non_fatal_;
|
||||||
bool fix_metadata_leaks_;
|
bool fix_metadata_leaks_;
|
||||||
bool clear_needs_check_;
|
bool clear_needs_check_;
|
||||||
|
bool open_transaction_;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum output_options {
|
enum output_options {
|
||||||
|
Loading…
Reference in New Issue
Block a user