From 6c90f9483e0d5e76e431a07654919f754468c6ae Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Wed, 12 Aug 2020 11:37:39 +0800 Subject: [PATCH] [metadata_checker] Support in-place metadata space map modification --- persistent-data/transaction_manager.h | 6 ++++++ thin-provisioning/metadata_checker.cc | 21 ++++++++++++++++++--- thin-provisioning/metadata_checker.h | 1 + 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/persistent-data/transaction_manager.h b/persistent-data/transaction_manager.h index 7df2cc5..cbf11ce 100644 --- a/persistent-data/transaction_manager.h +++ b/persistent-data/transaction_manager.h @@ -69,6 +69,12 @@ namespace persistent_data { 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: void add_shadow(block_address b); void remove_shadow(block_address b); diff --git a/thin-provisioning/metadata_checker.cc b/thin-provisioning/metadata_checker.cc index 5a6eebb..e81e22c 100644 --- a/thin-provisioning/metadata_checker.cc +++ b/thin-provisioning/metadata_checker.cc @@ -274,6 +274,17 @@ namespace { 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, block_counter const &expected) { error_state err = NO_ERROR; @@ -410,7 +421,7 @@ namespace { optional()); } - bool fix_metadata_leaks() { + bool fix_metadata_leaks(bool open_transaction) { if (!verify_preconditions_before_fixing()) { out_ << "metadata has not been fully examined" << end_message(); return false; @@ -429,6 +440,9 @@ namespace { open_metadata_sm(*tm, static_cast(&sb.metadata_space_map_root_)); tm->set_sm(metadata_sm); + if (!open_transaction) + mark_sm_shadowed(tm, metadata_sm); + err_ = clear_leaked_blocks(metadata_sm, expected_rc_); if (err_ != NO_ERROR) @@ -562,7 +576,8 @@ check_options::check_options() sm_opts_(SPACE_MAP_FULL), ignore_non_fatal_(false), fix_metadata_leaks_(false), - clear_needs_check_(false) { + clear_needs_check_(false), + open_transaction_(false) { } void check_options::set_superblock_only() { @@ -634,7 +649,7 @@ thin_provisioning::check_metadata(std::string const &path, checker.check(); if (check_opts.fix_metadata_leaks_) - checker.fix_metadata_leaks(); + checker.fix_metadata_leaks(check_opts.open_transaction_); if (check_opts.fix_metadata_leaks_ || check_opts.clear_needs_check_) checker.clear_needs_check_flag(); diff --git a/thin-provisioning/metadata_checker.h b/thin-provisioning/metadata_checker.h index 2871932..5569d27 100644 --- a/thin-provisioning/metadata_checker.h +++ b/thin-provisioning/metadata_checker.h @@ -55,6 +55,7 @@ namespace thin_provisioning { bool ignore_non_fatal_; bool fix_metadata_leaks_; bool clear_needs_check_; + bool open_transaction_; }; enum output_options {