[cache] a lot of format 2 changes

This commit is contained in:
Joe Thornber 2016-09-30 11:21:20 -04:00
parent bce4acf214
commit 05c4b7b400
10 changed files with 98 additions and 40 deletions

View File

@ -248,7 +248,12 @@ namespace {
{ {
nested_output::nest _ = out.push(); nested_output::nest _ = out.push();
mapping_array ma(*tm, mapping_array::ref_counter(), sb.mapping_root, sb.cache_blocks); mapping_array ma(*tm, mapping_array::ref_counter(), sb.mapping_root, sb.cache_blocks);
check_mapping_array(ma, mapping_rep); check_mapping_array(ma, mapping_rep, sb.version);
}
if (sb.version >= 2) {
persistent_data::bitset dirty(*tm, *sb.dirty_root, sb.cache_blocks);
// FIXME: is there no bitset checker?
} }
} }
@ -275,6 +280,7 @@ namespace {
{ {
nested_output::nest _ = out.push(); nested_output::nest _ = out.push();
persistent_data::bitset discards(*tm, sb.discard_root, sb.discard_nr_blocks); persistent_data::bitset discards(*tm, sb.discard_root, sb.discard_nr_blocks);
// FIXME: is there no bitset checker?
} }
} }
} }

View File

@ -43,29 +43,33 @@ namespace {
struct flags { struct flags {
flags() flags()
: metadata_version(1), : metadata_version(1),
override_metadata_version(false),
clean_shutdown(true), clean_shutdown(true),
quiet(false) { quiet(false),
override_metadata_version(false),
override_version(1) {
} }
optional<string> input; optional<string> input;
optional<string> output; optional<string> output;
uint32_t metadata_version; uint32_t metadata_version;
bool override_metadata_version;
bool clean_shutdown; bool clean_shutdown;
bool quiet; bool quiet;
bool override_metadata_version;
unsigned override_version;
}; };
int restore(flags const &fs) { int restore(flags const &fs) {
try { try {
block_manager<>::ptr bm = open_bm(*fs.output, block_manager<>::READ_WRITE); block_manager<>::ptr bm = open_bm(*fs.output, block_manager<>::READ_WRITE);
metadata::ptr md(new metadata(bm, metadata::CREATE)); metadata::ptr md(new metadata(bm, metadata::CREATE));
emitter::ptr restorer = create_restore_emitter(md, fs.clean_shutdown); emitter::ptr restorer = create_restore_emitter(md, fs.clean_shutdown,
fs.metadata_version);
if (fs.override_metadata_version) { if (fs.override_metadata_version) {
cerr << "overriding" << endl; cerr << "overriding" << endl;
md->sb_.version = fs.metadata_version; md->sb_.version = fs.override_version;
} }
check_file_exists(*fs.input); check_file_exists(*fs.input);
@ -95,12 +99,13 @@ cache_restore_cmd::usage(std::ostream &out) const
{ {
out << "Usage: " << get_name() << " [options]" << endl out << "Usage: " << get_name() << " [options]" << endl
<< "Options:" << endl << "Options:" << endl
<< " {-h|--help}" << endl << " {-h|--help}\n"
<< " {-i|--input} <input xml file>" << endl << " {-i|--input} <input xml file>\n"
<< " {-o|--output} <output device or file>" << endl << " {-o|--output} <output device or file>\n"
<< " {-q|--quiet}" << endl << " {-q|--quiet}\n"
<< " {-V|--version}" << endl << " {--metadata-version} <1 or 2>\n"
<< endl << " {-V|--version}\n"
<< "\n"
<< " {--debug-override-metadata-version} <integer>" << endl << " {--debug-override-metadata-version} <integer>" << endl
<< " {--omit-clean-shutdown}" << endl; << " {--omit-clean-shutdown}" << endl;
} }
@ -114,6 +119,7 @@ cache_restore_cmd::run(int argc, char **argv)
option const long_opts[] = { option const long_opts[] = {
{ "debug-override-metadata-version", required_argument, NULL, 0 }, { "debug-override-metadata-version", required_argument, NULL, 0 },
{ "omit-clean-shutdown", no_argument, NULL, 1 }, { "omit-clean-shutdown", no_argument, NULL, 1 },
{ "metadata-version", required_argument, NULL, 2 },
{ "help", no_argument, NULL, 'h'}, { "help", no_argument, NULL, 'h'},
{ "input", required_argument, NULL, 'i' }, { "input", required_argument, NULL, 'i' },
{ "output", required_argument, NULL, 'o'}, { "output", required_argument, NULL, 'o'},
@ -125,14 +131,23 @@ cache_restore_cmd::run(int argc, char **argv)
while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
switch(c) { switch(c) {
case 0: case 0:
fs.metadata_version = lexical_cast<uint32_t>(optarg);
fs.override_metadata_version = true; fs.override_metadata_version = true;
fs.override_version = lexical_cast<uint32_t>(optarg);
break; break;
case 1: case 1:
fs.clean_shutdown = false; fs.clean_shutdown = false;
break; break;
case 2:
fs.metadata_version = lexical_cast<uint32_t>(optarg);
if ((fs.metadata_version < MIN_METADATA_VERSION) ||
(fs.metadata_version > MAX_METADATA_VERSION)) {
cerr << "Bad metadata version\n\n";
return 1;
}
break;
case 'h': case 'h':
usage(cout); usage(cout);
return 0; return 0;

View File

@ -60,8 +60,9 @@ invalid_mapping::visit(damage_visitor &v) const
namespace { namespace {
class check_mapping_visitor : public mapping_visitor { class check_mapping_visitor : public mapping_visitor {
public: public:
check_mapping_visitor(damage_visitor &visitor) check_mapping_visitor(damage_visitor &visitor, unsigned metadata_version)
: visitor_(visitor) { : visitor_(visitor),
allowed_flags_(metadata_version == 1 ? (M_VALID | M_DIRTY) : M_VALID) {
} }
virtual void visit(block_address cblock, mapping const &m) { virtual void visit(block_address cblock, mapping const &m) {
@ -90,12 +91,13 @@ namespace {
seen_oblocks_.insert(m.oblock_); seen_oblocks_.insert(m.oblock_);
} }
static bool unknown_flags(mapping const &m) { bool unknown_flags(mapping const &m) {
return (m.flags_ & ~(M_VALID | M_DIRTY)); return m.flags_ & ~allowed_flags_;
} }
damage_visitor &visitor_; damage_visitor &visitor_;
set<block_address> seen_oblocks_; set<block_address> seen_oblocks_;
uint32_t allowed_flags_;
}; };
class ll_damage_visitor { class ll_damage_visitor {
@ -123,9 +125,9 @@ caching::walk_mapping_array(mapping_array const &array,
} }
void void
caching::check_mapping_array(mapping_array const &array, damage_visitor &visitor) caching::check_mapping_array(mapping_array const &array, damage_visitor &visitor, unsigned metadata_version)
{ {
check_mapping_visitor mv(visitor); check_mapping_visitor mv(visitor, metadata_version);
walk_mapping_array(array, mv, visitor); walk_mapping_array(array, mv, visitor);
} }

View File

@ -91,7 +91,8 @@ namespace caching {
mapping_array_damage::damage_visitor &dv); mapping_array_damage::damage_visitor &dv);
void check_mapping_array(mapping_array const &array, void check_mapping_array(mapping_array const &array,
mapping_array_damage::damage_visitor &visitor); mapping_array_damage::damage_visitor &visitor,
unsigned metadata_version);
} }
//---------------------------------------------------------------- //----------------------------------------------------------------

View File

@ -3,6 +3,7 @@
#include "persistent-data/space-maps/core.h" #include "persistent-data/space-maps/core.h"
using namespace caching; using namespace caching;
namespace pd = persistent_data;
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -30,15 +31,11 @@ namespace {
//---------------------------------------------------------------- //----------------------------------------------------------------
metadata::metadata(block_manager<>::ptr bm, open_type ot) metadata::metadata(block_manager<>::ptr bm, open_type ot, unsigned metadata_version)
{ {
switch (ot) { switch (ot) {
case CREATE: case CREATE:
create_metadata(bm); create_metadata(bm, metadata_version);
break;
case OPEN:
open_metadata(bm);
break; break;
default: default:
@ -46,6 +43,11 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot)
} }
} }
metadata::metadata(block_manager<>::ptr bm)
{
open_metadata(bm);
}
void void
metadata::commit(bool clean_shutdown) metadata::commit(bool clean_shutdown)
{ {
@ -65,7 +67,7 @@ metadata::setup_hint_array(size_t width)
} }
void void
metadata::create_metadata(block_manager<>::ptr bm) metadata::create_metadata(block_manager<>::ptr bm, unsigned metadata_version)
{ {
tm_ = open_tm(bm); tm_ = open_tm(bm);
@ -79,7 +81,10 @@ metadata::create_metadata(block_manager<>::ptr bm)
// We can't instantiate the hint array yet, since we don't know the // We can't instantiate the hint array yet, since we don't know the
// hint width. // hint width.
discard_bits_ = persistent_data::bitset::ptr(new persistent_data::bitset(*tm_)); discard_bits_ = pd::bitset::ptr(new pd::bitset(*tm_));
if (metadata_version >= 2)
dirty_bits_ = pd::bitset::ptr(new pd::bitset(*tm_));
} }
void void
@ -100,8 +105,12 @@ metadata::open_metadata(block_manager<>::ptr bm)
sb_.hint_root, sb_.cache_blocks)); sb_.hint_root, sb_.cache_blocks));
if (sb_.discard_root) if (sb_.discard_root)
discard_bits_ = persistent_data::bitset::ptr( discard_bits_ = pd::bitset::ptr(
new persistent_data::bitset(*tm_, sb_.discard_root, sb_.discard_nr_blocks)); new pd::bitset(*tm_, sb_.discard_root, sb_.discard_nr_blocks));
if (sb_.version >= 2)
dirty_bits_ = pd::bitset::ptr(
new pd::bitset(*tm_, *sb_.dirty_root, sb_.cache_blocks));
} }
void void

View File

@ -27,7 +27,8 @@ namespace caching {
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;
metadata(block_manager<>::ptr bm, open_type ot); metadata(block_manager<>::ptr bm, open_type ot, unsigned metadata_version = 2); // Create only
metadata(block_manager<>::ptr bm);
void commit(bool clean_shutdown = true); void commit(bool clean_shutdown = true);
void setup_hint_array(size_t width); void setup_hint_array(size_t width);
@ -40,11 +41,12 @@ namespace caching {
mapping_array::ptr mappings_; mapping_array::ptr mappings_;
hint_array::ptr hints_; hint_array::ptr hints_;
persistent_data::bitset::ptr discard_bits_; persistent_data::bitset::ptr discard_bits_;
persistent_data::bitset::ptr dirty_bits_;
private: private:
void init_superblock(); void init_superblock();
void create_metadata(block_manager<>::ptr bm); void create_metadata(block_manager<>::ptr bm, unsigned metadata_version);
void open_metadata(block_manager<>::ptr bm); void open_metadata(block_manager<>::ptr bm);
void commit_space_map(); void commit_space_map();

View File

@ -11,10 +11,11 @@ using namespace superblock_damage;
namespace { namespace {
class restorer : public emitter { class restorer : public emitter {
public: public:
restorer(metadata::ptr md, bool clean_shutdown) restorer(metadata::ptr md, bool clean_shutdown, unsigned metadata_version)
: in_superblock_(false), : in_superblock_(false),
md_(md), md_(md),
clean_shutdown_(clean_shutdown) { clean_shutdown_(clean_shutdown),
metadata_version_(metadata_version) {
} }
virtual void begin_superblock(std::string const &uuid, virtual void begin_superblock(std::string const &uuid,
@ -24,6 +25,7 @@ namespace {
size_t hint_width) { size_t hint_width) {
superblock &sb = md_->sb_; superblock &sb = md_->sb_;
sb.version = metadata_version_;
strncpy((char *) sb.policy_name, policy.c_str(), sizeof(sb.policy_name)); strncpy((char *) sb.policy_name, policy.c_str(), sizeof(sb.policy_name));
memset(sb.policy_version, 0, sizeof(sb.policy_version)); // FIXME: should come from xml memset(sb.policy_version, 0, sizeof(sb.policy_version)); // FIXME: should come from xml
sb.policy_hint_size = hint_width; sb.policy_hint_size = hint_width;
@ -37,6 +39,10 @@ namespace {
unmapped_value.flags_ = 0; unmapped_value.flags_ = 0;
md_->mappings_->grow(nr_cache_blocks, unmapped_value); md_->mappings_->grow(nr_cache_blocks, unmapped_value);
if (metadata_version_ > 1)
// make everything dirty by default
md_->dirty_bits_->grow(nr_cache_blocks, true);
vector<unsigned char> hint_value(hint_width, '\0'); vector<unsigned char> hint_value(hint_width, '\0');
md_->hints_->grow(nr_cache_blocks, hint_value); md_->hints_->grow(nr_cache_blocks, hint_value);
} }
@ -60,8 +66,11 @@ namespace {
m.oblock_ = oblock; m.oblock_ = oblock;
m.flags_ = M_VALID; m.flags_ = M_VALID;
if (metadata_version_ == 1) {
if (dirty) if (dirty)
m.flags_ = m.flags_ | M_DIRTY; m.flags_ = m.flags_ | M_DIRTY;
} else
md_->dirty_bits_->set(cblock, dirty);
md_->mappings_->set(cblock, m); md_->mappings_->set(cblock, m);
} }
@ -98,15 +107,17 @@ namespace {
bool in_superblock_; bool in_superblock_;
metadata::ptr md_; metadata::ptr md_;
bool clean_shutdown_; bool clean_shutdown_;
unsigned metadata_version_;
}; };
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
emitter::ptr emitter::ptr
caching::create_restore_emitter(metadata::ptr md, bool clean_shutdown) caching::create_restore_emitter(metadata::ptr md, unsigned metadata_version,
bool clean_shutdown)
{ {
return emitter::ptr(new restorer(md, clean_shutdown)); return emitter::ptr(new restorer(md, clean_shutdown, metadata_version));
} }
//---------------------------------------------------------------- //----------------------------------------------------------------

View File

@ -7,7 +7,9 @@
//---------------------------------------------------------------- //----------------------------------------------------------------
namespace caching { namespace caching {
emitter::ptr create_restore_emitter(metadata::ptr md, bool clean_shutdown = true); emitter::ptr create_restore_emitter(metadata::ptr md,
unsigned metadata_version,
bool clean_shutdown = true);
} }
//---------------------------------------------------------------- //----------------------------------------------------------------

View File

@ -45,6 +45,8 @@ namespace {
le32 write_misses; le32 write_misses;
le32 policy_version[CACHE_POLICY_VERSION_SIZE]; le32 policy_version[CACHE_POLICY_VERSION_SIZE];
le64 dirty_root; // format 2 only
} __attribute__ ((packed)); } __attribute__ ((packed));
struct superblock_traits { struct superblock_traits {
@ -57,7 +59,7 @@ namespace {
uint32_t const SUPERBLOCK_MAGIC = 06142003; uint32_t const SUPERBLOCK_MAGIC = 06142003;
uint32_t const VERSION_BEGIN = 1; uint32_t const VERSION_BEGIN = 1;
uint32_t const VERSION_END = 2; uint32_t const VERSION_END = 3;
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -195,6 +197,9 @@ superblock_traits::unpack(superblock_disk const &disk, superblock &core)
core.read_misses = to_cpu<uint32_t>(disk.read_misses); core.read_misses = to_cpu<uint32_t>(disk.read_misses);
core.write_hits = to_cpu<uint32_t>(disk.write_hits); core.write_hits = to_cpu<uint32_t>(disk.write_hits);
core.write_misses = to_cpu<uint32_t>(disk.write_misses); core.write_misses = to_cpu<uint32_t>(disk.write_misses);
if (core.version >= 2)
core.dirty_root = to_cpu<uint64_t>(disk.dirty_root);
} }
void void

View File

@ -4,6 +4,7 @@
#include "base/endian_utils.h" #include "base/endian_utils.h"
#include "persistent-data/data-structures/btree.h" #include "persistent-data/data-structures/btree.h"
#include <boost/optional.hpp>
#include <set> #include <set>
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -11,6 +12,8 @@
namespace caching { namespace caching {
typedef unsigned char __u8; typedef unsigned char __u8;
unsigned const MIN_METADATA_VERSION = 1;
unsigned const MAX_METADATA_VERSION = 2;
unsigned const SPACE_MAP_ROOT_SIZE = 128; unsigned const SPACE_MAP_ROOT_SIZE = 128;
unsigned const CACHE_POLICY_NAME_SIZE = 16; unsigned const CACHE_POLICY_NAME_SIZE = 16;
unsigned const CACHE_POLICY_VERSION_SIZE = 3; unsigned const CACHE_POLICY_VERSION_SIZE = 3;
@ -78,6 +81,8 @@ namespace caching {
uint32_t read_misses; uint32_t read_misses;
uint32_t write_hits; uint32_t write_hits;
uint32_t write_misses; uint32_t write_misses;
boost::optional<uint64_t> dirty_root;
}; };
enum incompat_bits { enum incompat_bits {