diff --git a/caching/hint_array.cc b/caching/hint_array.cc index 315ed42..8e9f275 100644 --- a/caching/hint_array.cc +++ b/caching/hint_array.cc @@ -234,14 +234,14 @@ missing_hints::visit(damage_visitor &v) const //---------------------------------------------------------------- hint_array::hint_array(tm_ptr tm, unsigned width) - : width_(width), + : width_(check_width(width)), impl_(mk_array(tm, width)) { } hint_array::hint_array(typename hint_array::tm_ptr tm, unsigned width, block_address root, unsigned nr_entries) - : width_(width), + : width_(check_width(width)), impl_(mk_array(tm, width, root, nr_entries)) { } @@ -283,4 +283,16 @@ hint_array::check(hint_array_damage::damage_visitor &visitor) walk(vv, visitor); } +uint32_t +hint_array::check_width(uint32_t width) +{ + if (width % 4 || width == 0 || width > 128) { + ostringstream msg; + msg << "invalid hint width: " << width; + throw runtime_error(msg.str()); + } + + return width; +} + //---------------------------------------------------------------- diff --git a/caching/hint_array.h b/caching/hint_array.h index fccf7b3..dfd3bcd 100644 --- a/caching/hint_array.h +++ b/caching/hint_array.h @@ -75,6 +75,8 @@ namespace caching { void check(hint_array_damage::damage_visitor &visitor); private: + static uint32_t check_width(uint32_t width); + unsigned width_; boost::shared_ptr impl_; }; diff --git a/caching/superblock.cc b/caching/superblock.cc index 46c2e04..30c733c 100644 --- a/caching/superblock.cc +++ b/caching/superblock.cc @@ -55,7 +55,7 @@ namespace { uint32_t const SUPERBLOCK_MAGIC = 06142003; uint32_t const VERSION_BEGIN = 1; - uint32_t const VERSION_END = 2; + uint32_t const VERSION_END = 3; } //---------------------------------------------------------------- @@ -109,7 +109,7 @@ superblock::superblock() : csum(0), blocknr(SUPERBLOCK_LOCATION), magic(SUPERBLOCK_MAGIC), - version(VERSION_BEGIN), + version(VERSION_END - 1u), policy_hint_size(0), mapping_root(0), hint_root(0), @@ -152,7 +152,7 @@ superblock_traits::unpack(superblock_disk const &disk, superblock &core) for (unsigned i = 0; i < CACHE_POLICY_VERSION_SIZE; i++) core.policy_version[i] = to_cpu(disk.policy_version[i]); - core.policy_hint_size = to_cpu(disk.policy_hint_size); + core.policy_hint_size = core.version == 1 ? 4 : to_cpu(disk.policy_hint_size); ::memcpy(core.metadata_space_map_root, disk.metadata_space_map_root, @@ -194,7 +194,6 @@ superblock_traits::pack(superblock const &core, superblock_disk &disk) for (unsigned i = 0; i < CACHE_POLICY_VERSION_SIZE; i++) disk.policy_version[i] = to_disk(core.policy_version[i]); - disk.policy_hint_size = to_disk(core.policy_hint_size); ::memcpy(disk.metadata_space_map_root,