Merge branch 'era' of github.com:jthornber/thin-provisioning-tools into era
This commit is contained in:
commit
e1e9e34a55
112
era/bloom_tree.h
Normal file
112
era/bloom_tree.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#ifndef ERA_BLOOM_TREE_H
|
||||||
|
#define ERA_BLOOM_TREE_H
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace era {
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
class dm_era {
|
||||||
|
public:
|
||||||
|
dm_era(block_address nr_blocks)
|
||||||
|
: nr_blocks_(nr_blocks),
|
||||||
|
era_base_(0),
|
||||||
|
base_(nr_blocks, false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
set<block_address> blocks_written_since(unsigned era) const {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned get_era() const {
|
||||||
|
return era_base_ + eras_.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void record_write(block_address b) {
|
||||||
|
current_era.record_write(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(block_address new_size) {
|
||||||
|
nr_blocks_ = new_size;
|
||||||
|
push_era();
|
||||||
|
base_.resize(new_size, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
era_details ¤t_era() {
|
||||||
|
return eras_.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void need_new_era() {
|
||||||
|
// ???
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_era() {
|
||||||
|
eras_.push_back(era(nr_blocks_));
|
||||||
|
if (eras_.size() > 100)
|
||||||
|
pop_era();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_era() {
|
||||||
|
era_base_++;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
eras_.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned NR_PROBES = 6;
|
||||||
|
|
||||||
|
class era_details {
|
||||||
|
public:
|
||||||
|
era_details(block_address nr_blocks)
|
||||||
|
: nr_blocks_(nr_blocks),
|
||||||
|
f(power_bits(nr_blocks, NR_PROBES)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void record_write(block_address b) {
|
||||||
|
f.add(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_blocks_written(set<block_address &result) const {
|
||||||
|
for (block_address b = 0; b < nr_blocks; b++)
|
||||||
|
if (f.test(b))
|
||||||
|
result.insert(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static unsigned power_bits(block_address nr_blocks) {
|
||||||
|
// We're expecting 1% of the cache to change per era
|
||||||
|
block_address expected_writes = nr_blocks / 100;
|
||||||
|
|
||||||
|
unsigned r = 1;
|
||||||
|
while ((1ull << r) < (16 * expected_writes))
|
||||||
|
r++;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef bloom_filter<block_address_bloom_traits> filter;
|
||||||
|
|
||||||
|
block_address nr_blocks;
|
||||||
|
filter f;
|
||||||
|
};
|
||||||
|
|
||||||
|
space_map::ptr setup_core_map() {
|
||||||
|
space_map::ptr sm(new core_map(NR_BLOCKS));
|
||||||
|
sm->inc(SUPERBLOCK);
|
||||||
|
return sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
block_address nr_blocks_;
|
||||||
|
unsigned era_base_;
|
||||||
|
vector<bool> base_;
|
||||||
|
deque<era_details> eras_;
|
||||||
|
};
|
||||||
|
#endif
|
118
era/superblock.cc
Normal file
118
era/superblock.cc
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#include "era/superblock.h"
|
||||||
|
|
||||||
|
#include "persistent-data/checksum.h"
|
||||||
|
|
||||||
|
using namespace base;
|
||||||
|
using namespace era;
|
||||||
|
using namespace persistent_data;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using namespace base;
|
||||||
|
|
||||||
|
struct superblock_disk {
|
||||||
|
le32 csum;
|
||||||
|
le32 flags;
|
||||||
|
le64 blocknr;
|
||||||
|
|
||||||
|
__u8 uuid[16];
|
||||||
|
le64 magic;
|
||||||
|
le32 version;
|
||||||
|
|
||||||
|
le32 data_block_size;
|
||||||
|
le32 metadata_block_size;
|
||||||
|
le32 nr_blocks;
|
||||||
|
|
||||||
|
le32 current_era;
|
||||||
|
era_detail_disk current_detail;
|
||||||
|
|
||||||
|
le64 bloom_filters_root;
|
||||||
|
le64 era_array_root;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct superblock_traits {
|
||||||
|
typedef superblock_disk disk_type;
|
||||||
|
typedef superblock value_type;
|
||||||
|
|
||||||
|
static void unpack(disk_type const &disk, value_type &value);
|
||||||
|
static void pack(value_type const &value, disk_type &disk);
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t const SUPERBLOCK_MAGIC = 2126579579;
|
||||||
|
uint32_t const VERSION_BEGIN = 1;
|
||||||
|
uint32_t const VERSION_END = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
superblock::superblock()
|
||||||
|
: csum(0),
|
||||||
|
blocknr(0),
|
||||||
|
flags(),
|
||||||
|
magic(SUPERBLOCK_MAGIC),
|
||||||
|
version(VERSION_END - 1),
|
||||||
|
data_block_size(0),
|
||||||
|
metadata_block_size(8),
|
||||||
|
nr_blocks(0),
|
||||||
|
current_era(0),
|
||||||
|
era_root(0),
|
||||||
|
era_array_root(0)
|
||||||
|
{
|
||||||
|
memset(uuid, 0, sizeof(uuid));
|
||||||
|
memset(metadata_space_map_root, 0, sizeof(metadata_space_map_root));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace validator {
|
||||||
|
using namespace persistent_data;
|
||||||
|
|
||||||
|
uint32_t const VERSION = 1;
|
||||||
|
unsigned const SECTOR_TO_BLOCK_SHIFT = 3;
|
||||||
|
uint32_t const SUPERBLOCK_CSUM_SEED = 146538381;
|
||||||
|
|
||||||
|
// FIXME: turn into a template, we have 3 similar classes now
|
||||||
|
struct sb_validator : public block_manager<>::validator {
|
||||||
|
virtual void check(buffer<> const &b, block_address location) const {
|
||||||
|
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&b);
|
||||||
|
crc32c sum(SUPERBLOCK_CSUM_SEED);
|
||||||
|
sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t));
|
||||||
|
if (sum.get_sum() != to_cpu<uint32_t>(sbd->csum))
|
||||||
|
throw checksum_error("bad checksum in superblock");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void prepare(buffer<> &b, block_address location) const {
|
||||||
|
superblock_disk *sbd = reinterpret_cast<superblock_disk *>(&b);
|
||||||
|
crc32c sum(SUPERBLOCK_CSUM_SEED);
|
||||||
|
sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t));
|
||||||
|
sbd->csum = to_disk<base::le32>(sum.get_sum());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
block_manager<>::validator::ptr mk_v() {
|
||||||
|
return block_manager<>::validator::ptr(new sb_validator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
superblock
|
||||||
|
era::read_superblock(block_manager<>::ptr bm, block_address location)
|
||||||
|
{
|
||||||
|
superblock sb;
|
||||||
|
block_manager<>::read_ref r = bm->read_lock(location, validator::mk_v());
|
||||||
|
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data());
|
||||||
|
superblock_traits::unpack(*sbd, sb);
|
||||||
|
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
era::write_superblock(block_manager<>::ptr bm, superblock const &sb, block_address location)
|
||||||
|
{
|
||||||
|
block_manager<>::write_ref w = bm->superblock_zero(location, validator::mk_v());
|
||||||
|
superblock_traits::pack(sb, *reinterpret_cast<superblock_disk *>(w.data().raw()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
84
era/superblock.h
Normal file
84
era/superblock.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#ifndef ERA_SUPERBLOCK_H
|
||||||
|
#define ERA_SUPERBLOCK_h
|
||||||
|
|
||||||
|
#include "persistent-data/block.h"
|
||||||
|
#include "era/era_detail.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace era {
|
||||||
|
typedef unsigned char __u8;
|
||||||
|
|
||||||
|
class superblock_flags {
|
||||||
|
public:
|
||||||
|
enum flag {
|
||||||
|
CLEAN_SHUTDOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
enum flag_bits {
|
||||||
|
CLEAN_SHUTDOWN_BIT = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
superblock_flags();
|
||||||
|
superblock_flags(uint32_t bits);
|
||||||
|
|
||||||
|
void set_flag(flag f);
|
||||||
|
void clear_flag(flag f);
|
||||||
|
bool get_flag(flag f) const;
|
||||||
|
uint32_t encode() const;
|
||||||
|
uint32_t get_unhandled_flags() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t unhandled_flags_;
|
||||||
|
std::set<flag> flags_;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned const SPACE_MAP_ROOT_SIZE = 128;
|
||||||
|
uint64_t const SUPERBLOCK_LOCATION = 0;
|
||||||
|
|
||||||
|
struct superblock {
|
||||||
|
superblock();
|
||||||
|
|
||||||
|
uint32_t csum;
|
||||||
|
uint64_t blocknr;
|
||||||
|
superblock_flags flags;
|
||||||
|
|
||||||
|
__u8 uuid[16]; // FIXME: do we really need this?
|
||||||
|
uint64_t magic;
|
||||||
|
uint32_t version;
|
||||||
|
|
||||||
|
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
|
||||||
|
|
||||||
|
uint32_t data_block_size;
|
||||||
|
uint32_t metadata_block_size;
|
||||||
|
uint32_t nr_blocks;
|
||||||
|
|
||||||
|
uint32_t current_era;
|
||||||
|
era_detail current_detail;
|
||||||
|
|
||||||
|
// A btree of undigested era_details
|
||||||
|
uint64_t era_root;
|
||||||
|
|
||||||
|
// Big array holding the digested era/block info.
|
||||||
|
uint64_t era_array_root;
|
||||||
|
};
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
superblock read_superblock(persistent_data::block_manager<>::ptr bm,
|
||||||
|
persistent_data::block_address location = SUPERBLOCK_LOCATION);
|
||||||
|
|
||||||
|
void write_superblock(persistent_data::block_manager<>::ptr bm,
|
||||||
|
superblock const &sb,
|
||||||
|
persistent_data::block_address location = SUPERBLOCK_LOCATION);
|
||||||
|
#if 0
|
||||||
|
void check_superblock(superblock const &sb,
|
||||||
|
superblock_damage::damage_visitor &visitor);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user