[thin tools] Change the metadata contructors to take a block_manager<>::ptr

Also check any metadata snap passed in matches what's in the superblock.
This commit is contained in:
Joe Thornber 2015-12-14 15:29:57 +00:00
parent 2b12854ecd
commit 30a3bf67d1
6 changed files with 46 additions and 93 deletions

View File

@ -60,80 +60,6 @@ namespace {
//---------------------------------------------------------------- //----------------------------------------------------------------
metadata::metadata(std::string const &dev_path, open_type ot,
sector_t data_block_size, block_address nr_data_blocks)
{
switch (ot) {
case OPEN:
tm_ = open_tm(open_bm(dev_path, block_manager<>::READ_ONLY));
sb_ = read_superblock(tm_->get_bm());
if (sb_.version_ != 1)
throw runtime_error("unknown metadata version");
metadata_sm_ = open_metadata_sm(*tm_, &sb_.metadata_space_map_root_);
tm_->set_sm(metadata_sm_);
data_sm_ = open_disk_sm(*tm_, static_cast<void *>(&sb_.data_space_map_root_));
details_ = device_tree::ptr(
new device_tree(*tm_, sb_.device_details_root_,
device_tree_detail::device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(
new dev_tree(*tm_, sb_.data_mapping_root_,
mapping_tree_detail::mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(
new mapping_tree(*tm_, sb_.data_mapping_root_,
mapping_tree_detail::block_time_ref_counter(data_sm_)));
break;
case CREATE:
tm_ = open_tm(open_bm(dev_path, block_manager<>::READ_WRITE));
space_map::ptr core = tm_->get_sm();
metadata_sm_ = create_metadata_sm(*tm_, tm_->get_bm()->get_nr_blocks());
copy_space_maps(metadata_sm_, core);
tm_->set_sm(metadata_sm_);
data_sm_ = create_disk_sm(*tm_, nr_data_blocks);
details_ = device_tree::ptr(new device_tree(*tm_, device_tree_detail::device_details_traits::ref_counter()));
mappings_ = mapping_tree::ptr(new mapping_tree(*tm_,
mapping_tree_detail::block_time_ref_counter(data_sm_)));
mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, mappings_->get_root(),
mapping_tree_detail::mtree_ref_counter(tm_)));
::memset(&sb_, 0, sizeof(sb_));
sb_.magic_ = SUPERBLOCK_MAGIC;
sb_.version_ = 1;
sb_.data_mapping_root_ = mappings_->get_root();
sb_.device_details_root_ = details_->get_root();
sb_.data_block_size_ = data_block_size;
sb_.metadata_block_size_ = MD_BLOCK_SIZE;
sb_.metadata_nr_blocks_ = tm_->get_bm()->get_nr_blocks();
break;
}
}
metadata::metadata(std::string const &dev_path, block_address metadata_snap)
{
tm_ = open_tm(open_bm(dev_path, block_manager<>::READ_ONLY, !metadata_snap));
sb_ = read_superblock(tm_->get_bm(), metadata_snap);
// We don't open the metadata sm for a held root
//metadata_sm_ = open_metadata_sm(tm_, &sb_.metadata_space_map_root_);
//tm_->set_sm(metadata_sm_);
data_sm_ = open_disk_sm(*tm_, static_cast<void *>(&sb_.data_space_map_root_));
details_ = device_tree::ptr(new device_tree(*tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, sb_.data_mapping_root_,
mapping_tree_detail::mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(new mapping_tree(*tm_, sb_.data_mapping_root_,
mapping_tree_detail::block_time_ref_counter(data_sm_)));
}
// FIXME: duplication
metadata::metadata(block_manager<>::ptr bm, open_type ot, metadata::metadata(block_manager<>::ptr bm, open_type ot,
sector_t data_block_size, sector_t data_block_size,
block_address nr_data_blocks) block_address nr_data_blocks)
@ -150,7 +76,8 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
tm_->set_sm(metadata_sm_); tm_->set_sm(metadata_sm_);
data_sm_ = open_disk_sm(*tm_, static_cast<void *>(&sb_.data_space_map_root_)); data_sm_ = open_disk_sm(*tm_, static_cast<void *>(&sb_.data_space_map_root_));
details_ = device_tree::ptr(new device_tree(*tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(*tm_, sb_.device_details_root_,
device_tree_detail::device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, sb_.data_mapping_root_, mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, sb_.data_mapping_root_,
mapping_tree_detail::mtree_ref_counter(tm_))); mapping_tree_detail::mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(new mapping_tree(*tm_, sb_.data_mapping_root_, mappings_ = mapping_tree::ptr(new mapping_tree(*tm_, sb_.data_mapping_root_,
@ -165,7 +92,8 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
tm_->set_sm(metadata_sm_); tm_->set_sm(metadata_sm_);
data_sm_ = create_disk_sm(*tm_, nr_data_blocks); data_sm_ = create_disk_sm(*tm_, nr_data_blocks);
details_ = device_tree::ptr(new device_tree(*tm_, device_tree_detail::device_details_traits::ref_counter())); details_ = device_tree::ptr(new device_tree(*tm_,
device_tree_detail::device_details_traits::ref_counter()));
mappings_ = mapping_tree::ptr(new mapping_tree(*tm_, mappings_ = mapping_tree::ptr(new mapping_tree(*tm_,
mapping_tree_detail::block_time_ref_counter(data_sm_))); mapping_tree_detail::block_time_ref_counter(data_sm_)));
mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, mappings_->get_root(), mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, mappings_->get_root(),
@ -184,6 +112,35 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
} }
} }
metadata::metadata(block_manager<>::ptr bm, block_address metadata_snap)
{
tm_ = open_tm(bm);
if (metadata_snap) {
if (metadata_snap != sb_.metadata_snap_)
throw runtime_error("metadata snapshot does not match that in superblock");
sb_ = read_superblock(tm_->get_bm(), metadata_snap);
// metadata snaps don't record the space maps
} else {
sb_ = read_superblock(tm_->get_bm(), SUPERBLOCK_LOCATION);
metadata_sm_ = open_metadata_sm(*tm_, &sb_.metadata_space_map_root_);
tm_->set_sm(metadata_sm_);
data_sm_ = open_disk_sm(*tm_, static_cast<void *>(&sb_.data_space_map_root_));
}
details_ = device_tree::ptr(new device_tree(*tm_, sb_.device_details_root_,
device_tree_detail::device_details_traits::ref_counter()));
mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, sb_.data_mapping_root_,
mapping_tree_detail::mtree_ref_counter(tm_)));
mappings_ = mapping_tree::ptr(new mapping_tree(*tm_, sb_.data_mapping_root_,
mapping_tree_detail::block_time_ref_counter(data_sm_)));
}
void void
metadata::commit() metadata::commit()
{ {

View File

@ -59,21 +59,10 @@ namespace thin_provisioning {
typedef block_manager<>::write_ref write_ref; typedef block_manager<>::write_ref write_ref;
typedef boost::shared_ptr<metadata> ptr; typedef boost::shared_ptr<metadata> ptr;
// Deprecated: it would be better if we passed in an already
// constructed block_manager.
metadata(std::string const &dev_path, open_type ot,
sector_t data_block_size = 128, // Only used if CREATE
block_address nr_data_blocks = 0); // Only used if CREATE
metadata(std::string const &dev_path,
block_address metadata_snap = 0);
// ... use these instead ...
metadata(block_manager<>::ptr bm, open_type ot, metadata(block_manager<>::ptr bm, open_type ot,
sector_t data_block_size = 128, sector_t data_block_size = 128,
block_address nr_data_blocks = 0); // Only used if CREATE block_address nr_data_blocks = 0); // Only used if CREATE
metadata(block_manager<>::ptr bm, block_address metadata_snap); metadata(block_manager<>::ptr bm, block_address metadata_snap = 0);
void commit(); void commit();

View File

@ -42,7 +42,8 @@ namespace {
int dump_(string const &path, ostream &out, string const &format, struct flags &flags, int dump_(string const &path, ostream &out, string const &format, struct flags &flags,
block_address metadata_snap) { block_address metadata_snap) {
try { try {
metadata::ptr md(new metadata(path, metadata_snap)); block_manager<>::ptr bm = open_bm(path, block_manager<>::READ_ONLY, !metadata_snap);
metadata::ptr md(new metadata(bm, metadata_snap));
emitter::ptr e; emitter::ptr e;
if (format == "xml") if (format == "xml")

View File

@ -2,6 +2,7 @@
#include <getopt.h> #include <getopt.h>
#include <libgen.h> #include <libgen.h>
#include "persistent-data/file_utils.h"
#include "thin-provisioning/commands.h" #include "thin-provisioning/commands.h"
#include "human_readable_format.h" #include "human_readable_format.h"
#include "metadata_dumper.h" #include "metadata_dumper.h"
@ -17,10 +18,12 @@ namespace {
int repair(string const &old_path, string const &new_path) { int repair(string const &old_path, string const &new_path) {
try { try {
// block size gets updated by the restorer // block size gets updated by the restorer
metadata::ptr new_md(new metadata(new_path, metadata::CREATE, 128, 0)); block_manager<>::ptr new_bm = open_bm(new_path, block_manager<>::READ_WRITE);
metadata::ptr new_md(new metadata(new_bm, metadata::CREATE, 128, 0));
emitter::ptr e = create_restore_emitter(new_md); emitter::ptr e = create_restore_emitter(new_md);
metadata::ptr old_md(new metadata(old_path)); block_manager<>::ptr old_bm = open_bm(old_path, block_manager<>::READ_ONLY);
metadata::ptr old_md(new metadata(old_bm));
metadata_dump(old_md, e, true); metadata_dump(old_md, e, true);
} catch (std::exception &e) { } catch (std::exception &e) {

View File

@ -45,7 +45,8 @@ namespace {
int restore(string const &backup_file, string const &dev, bool quiet) { int restore(string const &backup_file, string const &dev, bool quiet) {
try { try {
// The block size gets updated by the restorer. // The block size gets updated by the restorer.
metadata::ptr md(new metadata(dev, metadata::CREATE, 128, 0)); block_manager<>::ptr bm(open_bm(dev, block_manager<>::READ_WRITE));
metadata::ptr md(new metadata(bm, metadata::CREATE, 128, 0));
emitter::ptr restorer = create_restore_emitter(md); emitter::ptr restorer = create_restore_emitter(md);
parse_xml(backup_file, restorer, quiet); parse_xml(backup_file, restorer, quiet);

View File

@ -6,6 +6,7 @@
#undef BLOCK_SIZE #undef BLOCK_SIZE
#include "persistent-data/file_utils.h"
#include "thin-provisioning/commands.h" #include "thin-provisioning/commands.h"
#include "metadata.h" #include "metadata.h"
#include "version.h" #include "version.h"
@ -118,7 +119,8 @@ namespace {
int trim(string const &metadata_dev, string const &data_dev) { int trim(string const &metadata_dev, string const &data_dev) {
// We can trim any block that has zero count in the data // We can trim any block that has zero count in the data
// space map. // space map.
metadata md(metadata_dev, 0); block_manager<>::ptr bm = open_bm(metadata_dev, block_manager<>::READ_ONLY);
metadata md(bm);
if (!md.data_sm_->get_nr_free()) if (!md.data_sm_->get_nr_free())
return 0; return 0;