start removing block_manager<>::block

This commit is contained in:
Joe Thornber 2014-07-25 14:46:51 +01:00
parent b32908d5c2
commit 7e870ea5a6
18 changed files with 208 additions and 183 deletions

View File

@ -150,6 +150,7 @@ namespace bcache {
int r; int r;
iocb *control_blocks[1]; iocb *control_blocks[1];
// FIXME: put this back in
assert(!test_flags(b, IO_PENDING)); assert(!test_flags(b, IO_PENDING));
set_flags(b, IO_PENDING); set_flags(b, IO_PENDING);
nr_io_pending_++; nr_io_pending_++;
@ -175,13 +176,16 @@ namespace bcache {
int int
block_cache::issue_read(block &b) block_cache::issue_read(block &b)
{ {
std::cerr << "issuing read - that's a shame: " << b.index_ << "\n";
assert(!test_flags(b, IO_PENDING));
return issue_low_level(b, IO_CMD_PREAD, "read"); return issue_low_level(b, IO_CMD_PREAD, "read");
} }
int int
block_cache::issue_write(block &b) block_cache::issue_write(block &b)
{ {
std::cerr << "issuing write for block " << b.index_ << "\n"; assert(!test_flags(b, IO_PENDING));
b.v_->prepare(b.data_, b.index_);
return issue_low_level(b, IO_CMD_PWRITE, "write"); return issue_low_level(b, IO_CMD_PWRITE, "write");
} }
@ -303,7 +307,7 @@ namespace bcache {
} }
block_cache::block * block_cache::block *
block_cache::hash_lookup(block_index index) block_cache::hash_lookup(block_address index)
{ {
block *b; block *b;
unsigned bucket = hash(index); unsigned bucket = hash(index);
@ -347,7 +351,7 @@ namespace bcache {
} }
block_cache::block * block_cache::block *
block_cache::new_block(block_index index) block_cache::new_block(block_address index)
{ {
block *b; block *b;
@ -485,7 +489,8 @@ namespace bcache {
} }
block_cache::block * block_cache::block *
block_cache::lookup_or_read_block(block_index index, unsigned flags) block_cache::lookup_or_read_block(block_address index, unsigned flags,
validator::ptr v)
{ {
block *b = hash_lookup(index); block *b = hash_lookup(index);
@ -495,16 +500,26 @@ namespace bcache {
if (flags & GF_ZERO) if (flags & GF_ZERO)
zero_block(*b); zero_block(*b);
else {
if (b->v_.get() &&
b->v_.get() != v.get() &&
test_flags(*b, DIRTY))
b->v_->prepare(b->data_, b->index_);
}
b->v_ = v;
} else { } else {
if (flags & GF_CAN_BLOCK) { if (flags & GF_CAN_BLOCK) {
b = new_block(index); b = new_block(index);
if (b) { if (b) {
b->v_ = v;
if (flags & GF_ZERO) if (flags & GF_ZERO)
zero_block(*b); zero_block(*b);
else { else {
issue_read(*b); issue_read(*b);
wait_specific(*b); wait_specific(*b);
v->check(b->data_, b->index_);
} }
} }
} }
@ -514,9 +529,9 @@ namespace bcache {
} }
block_cache::block & block_cache::block &
block_cache::get(block_index index, unsigned flags) block_cache::get(block_address index, unsigned flags, validator::ptr v)
{ {
block *b = lookup_or_read_block(index, flags); block *b = lookup_or_read_block(index, flags, v);
if (b) { if (b) {
hit(*b); hit(*b);
@ -549,24 +564,26 @@ namespace bcache {
int int
block_cache::flush() block_cache::flush()
{ {
block *b; block *b, *tmp;
list_for_each_entry (b, &dirty_, list_) { std::cerr << "in flush\n";
if (b->ref_count_) { list_for_each_entry_safe (b, tmp, &dirty_, list_) {
info("attempt to lock an already locked block\n"); if (b->ref_count_ || test_flags(*b, IO_PENDING))
return -EAGAIN; // The superblock may well be still locked.
} continue;
issue_write(*b); issue_write(*b);
} }
std::cerr << "issued all writes\n";
wait_all(); wait_all();
std::cerr << "wait all returned\n";
return list_empty(&errored_) ? 0 : -EIO; return list_empty(&errored_) ? 0 : -EIO;
} }
void void
block_cache::prefetch(block_index index) block_cache::prefetch(block_address index)
{ {
block *b = hash_lookup(index); block *b = hash_lookup(index);

View File

@ -16,23 +16,25 @@
//---------------------------------------------------------------- //----------------------------------------------------------------
namespace bcache { namespace bcache {
#if 0 typedef uint64_t block_address;
typedef uint64_t sector_t;
class validator { class validator {
public: public:
typedef boost::shared_ptr<validator> ptr; typedef boost::shared_ptr<validator> ptr;
virtual ~validator() {} virtual ~validator() {}
virtual void check(buffer<BlockSize> const &b, block_address location) const = 0; virtual void check(void const *data, block_address location) const = 0;
virtual void prepare(buffer<BlockSize> &b, block_address location) const = 0; virtual void prepare(void *data, block_address location) const = 0;
}; };
class noop_validator : public validator { class noop_validator : public validator {
public: public:
void check(buffer<BlockSize> const &b, block_address location) const {} void check(void const *data, block_address location) const {}
void prepare(buffer<BlockSize> &b, block_address location) const {} void prepare(void *data, block_address location) const {}
}; };
#endif
//---------------------------------------------------------------- //----------------------------------------------------------------
// FIXME: throw exceptions rather than returning errors // FIXME: throw exceptions rather than returning errors
@ -45,6 +47,10 @@ namespace bcache {
class block : private boost::noncopyable { class block : private boost::noncopyable {
public: public:
block()
: v_() {
}
uint64_t get_index() const { uint64_t get_index() const {
return index_; return index_;
} }
@ -69,11 +75,9 @@ namespace bcache {
unsigned flags_; unsigned flags_;
iocb control_block_; iocb control_block_;
validator::ptr v_;
}; };
typedef uint64_t block_index;
typedef uint64_t sector_t;
//-------------------------------- //--------------------------------
block_cache(int fd, sector_t block_size, block_cache(int fd, sector_t block_size,
@ -88,7 +92,7 @@ namespace bcache {
}; };
// FIXME: what if !GF_CAN_BLOCK? // FIXME: what if !GF_CAN_BLOCK?
block_cache::block &get(block_index index, unsigned flags); block_cache::block &get(block_address index, unsigned flags, validator::ptr v);
enum put_flags { enum put_flags {
PF_DIRTY = (1 << 0), PF_DIRTY = (1 << 0),
@ -101,7 +105,7 @@ namespace bcache {
* failed. Make sure you build your recovery with this in mind. * failed. Make sure you build your recovery with this in mind.
*/ */
int flush(); int flush();
void prefetch(block_index index); void prefetch(block_address index);
private: private:
int init_free_list(unsigned count); int init_free_list(unsigned count);
@ -118,16 +122,16 @@ namespace bcache {
unsigned writeback(unsigned count); unsigned writeback(unsigned count);
void hash_init(unsigned nr_buckets); void hash_init(unsigned nr_buckets);
unsigned hash(uint64_t index); unsigned hash(uint64_t index);
block *hash_lookup(block_index index); block *hash_lookup(block_address index);
void hash_insert(block &b); void hash_insert(block &b);
void hash_remove(block &b); void hash_remove(block &b);
void setup_control_block(block &b); void setup_control_block(block &b);
block *new_block(block_index index); block *new_block(block_address index);
void mark_dirty(block &b); void mark_dirty(block &b);
unsigned calc_nr_cache_blocks(size_t mem, sector_t block_size); unsigned calc_nr_cache_blocks(size_t mem, sector_t block_size);
unsigned calc_nr_buckets(unsigned nr_blocks); unsigned calc_nr_buckets(unsigned nr_blocks);
void zero_block(block &b); void zero_block(block &b);
block *lookup_or_read_block(block_index index, unsigned flags); block *lookup_or_read_block(block_address index, unsigned flags, validator::ptr v);
unsigned test_flags(block &b, unsigned flags); unsigned test_flags(block &b, unsigned flags);
void clear_flags(block &b, unsigned flags); void clear_flags(block &b, unsigned flags);
void set_flags(block &b, unsigned flags); void set_flags(block &b, unsigned flags);
@ -154,11 +158,11 @@ namespace bcache {
list_head dirty_; list_head dirty_;
list_head clean_; list_head clean_;
unsigned nr_dirty_;
unsigned nr_io_pending_; unsigned nr_io_pending_;
struct list_head io_pending_; struct list_head io_pending_;
unsigned nr_dirty_;
/* /*
* Hash table fields. * Hash table fields.
*/ */
@ -166,6 +170,60 @@ namespace bcache {
unsigned mask_; unsigned mask_;
std::vector<list_head> buckets_; std::vector<list_head> buckets_;
}; };
#if 0
class auto_lock {
public:
auto_lock(block_cache &bc, block_address index, bool zero, validator::ptr v, unsigned put_flags)
: bc_(bc),
b_(bc.get(index, (zero ? block_cache::GF_ZERO : 0) | block_cache::GF_CAN_BLOCK, v)),
put_flags_(put_flags),
holders_(new unsigned) {
*holders_ = 1;
}
virtual ~auto_lock() {
bc_.put(b_, put_flags_);
}
auto_lock operator =(auto_lock const &rhs) {
if (this != &rhs) {
bc_ = rhs.bc_;
void const *data() const {
return b_.get_data();
}
private:
block_cache &bc_;
block_cache::block &b_;
unsigned put_flags_;
unsigned *holders_;
};
class auto_read_lock : public auto_lock {
public:
auto_read_lock(block_cache &bc, block_address index, bool zero, validator::ptr v)
: auto_lock(bc, index, zero, v, 0) {
}
using auto_lock::data();
};
class auto_write_lock : public auto_lock {
public:
auto_write_lock(block_cache &bc, block_address index, bool zero, validator::ptr v)
: auto_lock(bc, index, zero, v, block_cache::DIRTY) {
}
using auto_lock::data();
void *data() {
return b_.get_data();
}
};
#endif
} }
//---------------------------------------------------------------- //----------------------------------------------------------------

View File

@ -30,7 +30,7 @@
//---------------------------------------------------------------- //----------------------------------------------------------------
namespace persistent_data { namespace bcache {
uint32_t const DEFAULT_BUFFER_SIZE = 4096; uint32_t const DEFAULT_BUFFER_SIZE = 4096;
template <uint32_t Size = DEFAULT_BUFFER_SIZE> template <uint32_t Size = DEFAULT_BUFFER_SIZE>

View File

@ -275,25 +275,25 @@ namespace validator {
unsigned const SECTOR_TO_BLOCK_SHIFT = 3; unsigned const SECTOR_TO_BLOCK_SHIFT = 3;
uint32_t const SUPERBLOCK_CSUM_SEED = 9031977; uint32_t const SUPERBLOCK_CSUM_SEED = 9031977;
struct sb_validator : public block_manager<>::validator { struct sb_validator : public bcache::validator {
virtual void check(buffer<> const &b, block_address location) const { virtual void check(void const *raw, block_address location) const {
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(b.raw()); superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(raw);
crc32c sum(SUPERBLOCK_CSUM_SEED); crc32c sum(SUPERBLOCK_CSUM_SEED);
sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t));
if (sum.get_sum() != to_cpu<uint32_t>(sbd->csum)) if (sum.get_sum() != to_cpu<uint32_t>(sbd->csum))
throw checksum_error("bad checksum in superblock"); throw checksum_error("bad checksum in superblock");
} }
virtual void prepare(buffer<> &b, block_address location) const { virtual void prepare(void *raw, block_address location) const {
superblock_disk *sbd = reinterpret_cast<superblock_disk *>(b.raw()); superblock_disk *sbd = reinterpret_cast<superblock_disk *>(raw);
crc32c sum(SUPERBLOCK_CSUM_SEED); crc32c sum(SUPERBLOCK_CSUM_SEED);
sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t));
sbd->csum = to_disk<base::le32>(sum.get_sum()); sbd->csum = to_disk<base::le32>(sum.get_sum());
} }
}; };
block_manager<>::validator::ptr mk_v() { bcache::validator::ptr mk_v() {
return block_manager<>::validator::ptr(new sb_validator); return bcache::validator::ptr(new sb_validator);
} }
} }
@ -304,7 +304,7 @@ caching::read_superblock(block_manager<>::ptr bm, block_address location)
{ {
superblock sb; superblock sb;
block_manager<>::read_ref r = bm->read_lock(location, validator::mk_v()); block_manager<>::read_ref r = bm->read_lock(location, validator::mk_v());
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data()); superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(r.data());
superblock_traits::unpack(*sbd, sb); superblock_traits::unpack(*sbd, sb);
return sb; return sb;
@ -314,7 +314,7 @@ void
caching::write_superblock(block_manager<>::ptr bm, superblock const &sb, block_address location) caching::write_superblock(block_manager<>::ptr bm, superblock const &sb, block_address location)
{ {
block_manager<>::write_ref w = bm->superblock_zero(location, validator::mk_v()); block_manager<>::write_ref w = bm->superblock_zero(location, validator::mk_v());
superblock_traits::pack(sb, *reinterpret_cast<superblock_disk *>(w.data().raw())); superblock_traits::pack(sb, *reinterpret_cast<superblock_disk *>(w.data()));
} }
void void

View File

@ -128,7 +128,7 @@ namespace caching {
//-------------------------------- //--------------------------------
persistent_data::block_manager<>::validator::ptr superblock_validator(); bcache::validator::ptr superblock_validator();
superblock read_superblock(persistent_data::block_manager<>::ptr bm, superblock read_superblock(persistent_data::block_manager<>::ptr bm,
persistent_data::block_address location = SUPERBLOCK_LOCATION); persistent_data::block_address location = SUPERBLOCK_LOCATION);

View File

@ -210,25 +210,25 @@ namespace era_validator {
uint32_t const SUPERBLOCK_CSUM_SEED = 146538381; uint32_t const SUPERBLOCK_CSUM_SEED = 146538381;
// FIXME: turn into a template, we have 3 similar classes now // FIXME: turn into a template, we have 3 similar classes now
struct sb_validator : public block_manager<>::validator { struct sb_validator : public bcache::validator {
virtual void check(buffer<> const &b, block_address location) const { virtual void check(void const *raw, block_address location) const {
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(b.raw()); superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(raw);
crc32c sum(SUPERBLOCK_CSUM_SEED); crc32c sum(SUPERBLOCK_CSUM_SEED);
sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t));
if (sum.get_sum() != to_cpu<uint32_t>(sbd->csum)) if (sum.get_sum() != to_cpu<uint32_t>(sbd->csum))
throw checksum_error("bad checksum in superblock"); throw checksum_error("bad checksum in superblock");
} }
virtual void prepare(buffer<> &b, block_address location) const { virtual void prepare(void *raw, block_address location) const {
superblock_disk *sbd = reinterpret_cast<superblock_disk *>(b.raw()); superblock_disk *sbd = reinterpret_cast<superblock_disk *>(raw);
crc32c sum(SUPERBLOCK_CSUM_SEED); crc32c sum(SUPERBLOCK_CSUM_SEED);
sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t));
sbd->csum = to_disk<base::le32>(sum.get_sum()); sbd->csum = to_disk<base::le32>(sum.get_sum());
} }
}; };
block_manager<>::validator::ptr mk_v() { bcache::validator::ptr mk_v() {
return block_manager<>::validator::ptr(new sb_validator); return bcache::validator::ptr(new sb_validator);
} }
} }
@ -239,7 +239,7 @@ era::read_superblock(block_manager<>::ptr bm, block_address location)
{ {
superblock sb; superblock sb;
block_manager<>::read_ref r = bm->read_lock(location, era_validator::mk_v()); block_manager<>::read_ref r = bm->read_lock(location, era_validator::mk_v());
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data()); superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(r.data());
superblock_traits::unpack(*sbd, sb); superblock_traits::unpack(*sbd, sb);
return sb; return sb;
@ -249,7 +249,7 @@ void
era::write_superblock(block_manager<>::ptr bm, superblock const &sb, block_address location) era::write_superblock(block_manager<>::ptr bm, superblock const &sb, block_address location)
{ {
block_manager<>::write_ref w = bm->superblock_zero(location, era_validator::mk_v()); block_manager<>::write_ref w = bm->superblock_zero(location, era_validator::mk_v());
superblock_traits::pack(sb, *reinterpret_cast<superblock_disk *>(w.data().raw())); superblock_traits::pack(sb, *reinterpret_cast<superblock_disk *>(w.data()));
} }
void void

View File

@ -40,8 +40,6 @@ namespace persistent_data {
uint32_t const MD_BLOCK_SIZE = 4096; uint32_t const MD_BLOCK_SIZE = 4096;
typedef uint64_t block_address;
template <uint32_t BlockSize = MD_BLOCK_SIZE> template <uint32_t BlockSize = MD_BLOCK_SIZE>
class block_manager : private boost::noncopyable { class block_manager : private boost::noncopyable {
public: public:
@ -58,22 +56,6 @@ namespace persistent_data {
unsigned max_concurrent_locks, unsigned max_concurrent_locks,
mode m); mode m);
class validator {
public:
typedef boost::shared_ptr<validator> ptr;
virtual ~validator() {}
virtual void check(buffer<BlockSize> const &b, block_address location) const = 0;
virtual void prepare(buffer<BlockSize> &b, block_address location) const = 0;
};
class noop_validator : public validator {
public:
void check(buffer<BlockSize> const &b, block_address location) const {}
void prepare(buffer<BlockSize> &b, block_address location) const {}
};
enum block_type { enum block_type {
BT_SUPERBLOCK, BT_SUPERBLOCK,
BT_NORMAL BT_NORMAL
@ -86,7 +68,7 @@ namespace persistent_data {
block(block_cache &bc, block(block_cache &bc,
block_address location, block_address location,
block_type bt, block_type bt,
typename validator::ptr v, typename bcache::validator::ptr v,
bool zero = false); bool zero = false);
~block(); ~block();
@ -98,14 +80,11 @@ namespace persistent_data {
// FIXME: finish // FIXME: finish
} }
void change_validator(typename block_manager<BlockSize>::validator::ptr v,
bool check = true);
block_type get_type() const; block_type get_type() const;
uint64_t get_location() const; uint64_t get_location() const;
buffer<BlockSize> const &get_buffer() const; void const *get_data() const;
buffer<BlockSize> &get_buffer(); void *get_data();
void mark_dirty(); void mark_dirty();
void unlock(); void unlock();
@ -115,11 +94,9 @@ namespace persistent_data {
block_cache &bc_; block_cache &bc_;
block_cache::block *internal_; block_cache::block *internal_;
typename validator::ptr validator_;
block_type bt_; block_type bt_;
bool dirty_; bool dirty_;
bool unlocked_; bool unlocked_;
buffer<BlockSize> buffer_;
}; };
class read_ref { class read_ref {
@ -134,7 +111,7 @@ namespace persistent_data {
read_ref const &operator =(read_ref const &rhs); read_ref const &operator =(read_ref const &rhs);
block_address get_location() const; block_address get_location() const;
buffer<BlockSize> const &data() const; void const * data() const;
protected: protected:
block_manager<BlockSize> const *bm_; block_manager<BlockSize> const *bm_;
@ -150,24 +127,24 @@ namespace persistent_data {
typename block::ptr b); typename block::ptr b);
using read_ref::data; using read_ref::data;
buffer<BlockSize> &data(); void *data();
}; };
// Locking methods // Locking methods
read_ref read_ref
read_lock(block_address location, read_lock(block_address location,
typename validator::ptr v = typename validator::ptr v =
typename validator::ptr(new noop_validator())) const; typename validator::ptr(new bcache::noop_validator())) const;
write_ref write_ref
write_lock(block_address location, write_lock(block_address location,
typename validator::ptr v = typename validator::ptr v =
typename validator::ptr(new noop_validator())); typename validator::ptr(new bcache::noop_validator()));
write_ref write_ref
write_lock_zero(block_address location, write_lock_zero(block_address location,
typename validator::ptr v = typename validator::ptr v =
typename validator::ptr(new noop_validator())); typename validator::ptr(new bcache::noop_validator()));
// The super block is the one that should be written last. // The super block is the one that should be written last.
// Unlocking this block triggers the following events: // Unlocking this block triggers the following events:
@ -181,10 +158,10 @@ namespace persistent_data {
// being unlocked then an exception will be thrown. // being unlocked then an exception will be thrown.
write_ref superblock(block_address b, write_ref superblock(block_address b,
typename validator::ptr v = typename validator::ptr v =
typename validator::ptr(new noop_validator())); typename validator::ptr(new bcache::noop_validator()));
write_ref superblock_zero(block_address b, write_ref superblock_zero(block_address b,
typename validator::ptr v = typename validator::ptr v =
typename validator::ptr(new noop_validator())); typename validator::ptr(new bcache::noop_validator()));
block_address get_nr_blocks() const; block_address get_nr_blocks() const;
@ -206,9 +183,9 @@ namespace persistent_data {
}; };
// A little utility to help build validators // A little utility to help build validators
inline block_manager<>::validator::ptr inline bcache::validator::ptr
mk_validator(block_manager<>::validator *v) { mk_validator(bcache::validator *v) {
return block_manager<>::validator::ptr(v); return bcache::validator::ptr(v);
} }
} }

View File

@ -112,20 +112,15 @@ namespace persistent_data {
typename validator::ptr v, typename validator::ptr v,
bool zero) bool zero)
: bc_(bc), : bc_(bc),
validator_(v),
bt_(bt), bt_(bt),
dirty_(false), dirty_(false),
unlocked_(false), unlocked_(false)
buffer_(0, true) // FIXME: we don't know if it's writeable here :(
{ {
if (zero) { if (zero) {
internal_ = &bc.get(location, block_cache::GF_ZERO | block_cache::GF_CAN_BLOCK); internal_ = &bc.get(location, block_cache::GF_ZERO | block_cache::GF_CAN_BLOCK, v);
dirty_ = true; dirty_ = true;
buffer_.set_data(internal_->get_data());
} else { } else {
internal_ = &bc.get(location, block_cache::GF_CAN_BLOCK); internal_ = &bc.get(location, block_cache::GF_CAN_BLOCK, v);
buffer_.set_data(internal_->get_data());
validator_->check(buffer_, internal_->get_index());
} }
} }
@ -140,8 +135,6 @@ namespace persistent_data {
void void
block_manager<BlockSize>::block::unlock() block_manager<BlockSize>::block::unlock()
{ {
if (dirty_)
validator_->prepare(buffer_, internal_->get_index());
bc_.put(*internal_, dirty_ ? block_cache::PF_DIRTY : 0); bc_.put(*internal_, dirty_ ? block_cache::PF_DIRTY : 0);
unlocked_ = true; unlocked_ = true;
} }
@ -162,17 +155,17 @@ namespace persistent_data {
} }
template <uint32_t BlockSize> template <uint32_t BlockSize>
buffer<BlockSize> const & void const *
block_manager<BlockSize>::block::get_buffer() const block_manager<BlockSize>::block::get_data() const
{ {
return buffer_; return internal_->get_data();
} }
template <uint32_t BlockSize> template <uint32_t BlockSize>
buffer<BlockSize> & void *
block_manager<BlockSize>::block::get_buffer() block_manager<BlockSize>::block::get_data()
{ {
return buffer_; return internal_->get_data();
} }
template <uint32_t BlockSize> template <uint32_t BlockSize>
@ -183,25 +176,6 @@ namespace persistent_data {
dirty_ = true; dirty_ = true;
} }
template <uint32_t BlockSize>
void
block_manager<BlockSize>::block::change_validator(typename block_manager<BlockSize>::validator::ptr v,
bool check)
{
check_not_unlocked();
if (v.get() != validator_.get()) {
if (dirty_)
// It may have already happened, by calling
// this we ensure we're consistent.
validator_->prepare(*internal_->get_data(), internal_->get_index());
validator_ = v;
if (check)
validator_->check(*internal_->get_data(), internal_->get_index());
}
}
template <uint32_t BlockSize> template <uint32_t BlockSize>
void void
block_manager<BlockSize>::block::check_not_unlocked() const block_manager<BlockSize>::block::check_not_unlocked() const
@ -268,10 +242,10 @@ namespace persistent_data {
} }
template <uint32_t BlockSize> template <uint32_t BlockSize>
buffer<BlockSize> const & void const *
block_manager<BlockSize>::read_ref::data() const block_manager<BlockSize>::read_ref::data() const
{ {
return block_->get_buffer(); return block_->get_data();
} }
//-------------------------------- //--------------------------------
@ -285,10 +259,10 @@ namespace persistent_data {
} }
template <uint32_t BlockSize> template <uint32_t BlockSize>
buffer<BlockSize> & void *
block_manager<BlockSize>::write_ref::data() block_manager<BlockSize>::write_ref::data()
{ {
return read_ref::block_->get_buffer(); return read_ref::block_->get_data();
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -299,14 +273,14 @@ namespace persistent_data {
unsigned max_concurrent_blocks, unsigned max_concurrent_blocks,
mode m) mode m)
: fd_(open_block_file(path, nr_blocks * BlockSize, m == READ_WRITE)), : fd_(open_block_file(path, nr_blocks * BlockSize, m == READ_WRITE)),
bc_(fd_, BlockSize >> SECTOR_SHIFT, nr_blocks, 1024u * 1024u * 4) bc_(fd_, BlockSize >> SECTOR_SHIFT, nr_blocks, 1024u * 1024u * 256)
{ {
} }
template <uint32_t BlockSize> template <uint32_t BlockSize>
typename block_manager<BlockSize>::read_ref typename block_manager<BlockSize>::read_ref
block_manager<BlockSize>::read_lock(block_address location, block_manager<BlockSize>::read_lock(block_address location,
typename block_manager<BlockSize>::validator::ptr v) const typename bcache::validator::ptr v) const
{ {
typename block::ptr b(new block(bc_, location, BT_NORMAL, v, false)); typename block::ptr b(new block(bc_, location, BT_NORMAL, v, false));
return read_ref(*this, b); return read_ref(*this, b);
@ -315,7 +289,7 @@ namespace persistent_data {
template <uint32_t BlockSize> template <uint32_t BlockSize>
typename block_manager<BlockSize>::write_ref typename block_manager<BlockSize>::write_ref
block_manager<BlockSize>::write_lock(block_address location, block_manager<BlockSize>::write_lock(block_address location,
typename block_manager<BlockSize>::validator::ptr v) typename bcache::validator::ptr v)
{ {
typename block::ptr b(new block(bc_, location, BT_NORMAL, v, false)); typename block::ptr b(new block(bc_, location, BT_NORMAL, v, false));
return write_ref(*this, b); return write_ref(*this, b);
@ -324,7 +298,7 @@ namespace persistent_data {
template <uint32_t BlockSize> template <uint32_t BlockSize>
typename block_manager<BlockSize>::write_ref typename block_manager<BlockSize>::write_ref
block_manager<BlockSize>::write_lock_zero(block_address location, block_manager<BlockSize>::write_lock_zero(block_address location,
typename block_manager<BlockSize>::validator::ptr v) typename bcache::validator::ptr v)
{ {
typename block::ptr b(new block(bc_, location, BT_NORMAL, v, true)); typename block::ptr b(new block(bc_, location, BT_NORMAL, v, true));
return write_ref(*this, b); return write_ref(*this, b);
@ -333,7 +307,7 @@ namespace persistent_data {
template <uint32_t BlockSize> template <uint32_t BlockSize>
typename block_manager<BlockSize>::write_ref typename block_manager<BlockSize>::write_ref
block_manager<BlockSize>::superblock(block_address location, block_manager<BlockSize>::superblock(block_address location,
typename block_manager<BlockSize>::validator::ptr v) typename bcache::validator::ptr v)
{ {
typename block::ptr b(new block(bc_, location, BT_SUPERBLOCK, v, false)); typename block::ptr b(new block(bc_, location, BT_SUPERBLOCK, v, false));
return write_ref(*this, b); return write_ref(*this, b);
@ -342,7 +316,7 @@ namespace persistent_data {
template <uint32_t BlockSize> template <uint32_t BlockSize>
typename block_manager<BlockSize>::write_ref typename block_manager<BlockSize>::write_ref
block_manager<BlockSize>::superblock_zero(block_address location, block_manager<BlockSize>::superblock_zero(block_address location,
typename block_manager<BlockSize>::validator::ptr v) typename bcache::validator::ptr v)
{ {
typename block::ptr b(new block(bc_, location, BT_SUPERBLOCK, v, true)); typename block::ptr b(new block(bc_, location, BT_SUPERBLOCK, v, true));
return write_ref(*this, b); return write_ref(*this, b);

View File

@ -31,9 +31,9 @@ namespace persistent_data {
namespace array_detail { namespace array_detail {
uint32_t const ARRAY_CSUM_XOR = 595846735; uint32_t const ARRAY_CSUM_XOR = 595846735;
struct array_block_validator : public block_manager<>::validator { struct array_block_validator : public bcache::validator {
virtual void check(buffer<> const &b, block_address location) const { virtual void check(void const *raw, block_address location) const {
array_block_disk const *data = reinterpret_cast<array_block_disk const *>(b.raw()); array_block_disk const *data = reinterpret_cast<array_block_disk const *>(raw);
crc32c sum(ARRAY_CSUM_XOR); crc32c sum(ARRAY_CSUM_XOR);
sum.append(&data->max_entries, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&data->max_entries, MD_BLOCK_SIZE - sizeof(uint32_t));
if (sum.get_sum() != to_cpu<uint32_t>(data->csum)) if (sum.get_sum() != to_cpu<uint32_t>(data->csum))
@ -43,8 +43,8 @@ namespace persistent_data {
throw checksum_error("bad block nr in array block"); throw checksum_error("bad block nr in array block");
} }
virtual void prepare(buffer<> &b, block_address location) const { virtual void prepare(void *raw, block_address location) const {
array_block_disk *data = reinterpret_cast<array_block_disk *>(b.raw()); array_block_disk *data = reinterpret_cast<array_block_disk *>(raw);
data->blocknr = to_disk<base::le64, uint64_t>(location); data->blocknr = to_disk<base::le64, uint64_t>(location);
crc32c sum(ARRAY_CSUM_XOR); crc32c sum(ARRAY_CSUM_XOR);
@ -432,7 +432,7 @@ namespace persistent_data {
block_ref_counter block_rc_; block_ref_counter block_rc_;
btree<1, block_traits> block_tree_; btree<1, block_traits> block_tree_;
typename ValueTraits::ref_counter rc_; typename ValueTraits::ref_counter rc_;
block_manager<>::validator::ptr validator_; bcache::validator::ptr validator_;
}; };
} }

View File

@ -163,11 +163,11 @@ namespace persistent_data {
} }
array_block_disk *get_header() { array_block_disk *get_header() {
return reinterpret_cast<array_block_disk *>(ref_.data().raw()); return reinterpret_cast<array_block_disk *>(ref_.data());
} }
array_block_disk const *get_header() const { array_block_disk const *get_header() const {
return reinterpret_cast<array_block_disk const *>(ref_.data().raw()); return reinterpret_cast<array_block_disk const *>(ref_.data());
} }
disk_type &element_at(unsigned int index) { disk_type &element_at(unsigned int index) {

View File

@ -184,7 +184,7 @@ namespace persistent_data {
return node_ref<ValueTraits>( return node_ref<ValueTraits>(
b.get_location(), b.get_location(),
reinterpret_cast<disk_node *>( reinterpret_cast<disk_node *>(
const_cast<unsigned char *>(b.data().raw()))); const_cast<void *>(b.data())));
} }
template <typename ValueTraits> template <typename ValueTraits>
@ -193,14 +193,13 @@ namespace persistent_data {
{ {
return node_ref<ValueTraits>( return node_ref<ValueTraits>(
b.get_location(), b.get_location(),
reinterpret_cast<disk_node *>( reinterpret_cast<disk_node *>(b.data()));
const_cast<unsigned char *>(b.data().raw())));
} }
class ro_spine : private boost::noncopyable { class ro_spine : private boost::noncopyable {
public: public:
ro_spine(transaction_manager::ptr tm, ro_spine(transaction_manager::ptr tm,
block_manager<>::validator::ptr v) bcache::validator::ptr v)
: tm_(tm), : tm_(tm),
validator_(v) { validator_(v) {
} }
@ -214,7 +213,7 @@ namespace persistent_data {
private: private:
transaction_manager::ptr tm_; transaction_manager::ptr tm_;
block_manager<>::validator::ptr validator_; bcache::validator::ptr validator_;
std::list<block_manager<>::read_ref> spine_; std::list<block_manager<>::read_ref> spine_;
}; };
@ -225,7 +224,7 @@ namespace persistent_data {
typedef boost::optional<block_address> maybe_block; typedef boost::optional<block_address> maybe_block;
shadow_spine(transaction_manager::ptr tm, shadow_spine(transaction_manager::ptr tm,
block_manager<>::validator::ptr v) bcache::validator::ptr v)
: tm_(tm), : tm_(tm),
validator_(v) { validator_(v) {
@ -278,7 +277,7 @@ namespace persistent_data {
private: private:
transaction_manager::ptr tm_; transaction_manager::ptr tm_;
block_manager<>::validator::ptr validator_; bcache::validator::ptr validator_;
std::list<block_manager<>::write_ref> spine_; std::list<block_manager<>::write_ref> spine_;
maybe_block root_; maybe_block root_;
}; };
@ -440,7 +439,7 @@ namespace persistent_data {
block_address root_; block_address root_;
block_ref_counter internal_rc_; block_ref_counter internal_rc_;
typename ValueTraits::ref_counter rc_; typename ValueTraits::ref_counter rc_;
typename block_manager<>::validator::ptr validator_; typename bcache::validator::ptr validator_;
}; };
}; };

View File

@ -32,9 +32,9 @@ namespace {
using namespace btree_detail; using namespace btree_detail;
using namespace std; using namespace std;
struct btree_node_validator : public block_manager<>::validator { struct btree_node_validator : public bcache::validator {
virtual void check(buffer<> const &b, block_address location) const { virtual void check(void const *raw, block_address location) const {
disk_node const *data = reinterpret_cast<disk_node const *>(b.raw()); disk_node const *data = reinterpret_cast<disk_node const *>(raw);
node_header const *n = &data->header; node_header const *n = &data->header;
crc32c sum(BTREE_CSUM_XOR); crc32c sum(BTREE_CSUM_XOR);
sum.append(&n->flags, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&n->flags, MD_BLOCK_SIZE - sizeof(uint32_t));
@ -45,8 +45,8 @@ namespace {
throw checksum_error("bad block nr in btree node"); throw checksum_error("bad block nr in btree node");
} }
virtual void prepare(buffer<> &b, block_address location) const { virtual void prepare(void *raw, block_address location) const {
disk_node *data = reinterpret_cast<disk_node *>(b.raw()); disk_node *data = reinterpret_cast<disk_node *>(raw);
node_header *n = &data->header; node_header *n = &data->header;
n->blocknr = to_disk<base::le64, uint64_t>(location); n->blocknr = to_disk<base::le64, uint64_t>(location);

View File

@ -37,9 +37,9 @@ using namespace sm_disk_detail;
namespace { namespace {
uint64_t const BITMAP_CSUM_XOR = 240779; uint64_t const BITMAP_CSUM_XOR = 240779;
struct bitmap_block_validator : public block_manager<>::validator { struct bitmap_block_validator : public bcache::validator {
virtual void check(buffer<> const &b, block_address location) const { virtual void check(void const *raw, block_address location) const {
bitmap_header const *data = reinterpret_cast<bitmap_header const *>(b.raw()); bitmap_header const *data = reinterpret_cast<bitmap_header const *>(raw);
crc32c sum(BITMAP_CSUM_XOR); crc32c sum(BITMAP_CSUM_XOR);
sum.append(&data->not_used, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&data->not_used, MD_BLOCK_SIZE - sizeof(uint32_t));
if (sum.get_sum() != to_cpu<uint32_t>(data->csum)) if (sum.get_sum() != to_cpu<uint32_t>(data->csum))
@ -49,8 +49,8 @@ namespace {
throw checksum_error("bad block nr in space map bitmap"); throw checksum_error("bad block nr in space map bitmap");
} }
virtual void prepare(buffer<> &b, block_address location) const { virtual void prepare(void *raw, block_address location) const {
bitmap_header *data = reinterpret_cast<bitmap_header *>(b.raw()); bitmap_header *data = reinterpret_cast<bitmap_header *>(raw);
data->blocknr = to_disk<base::le64, uint64_t>(location); data->blocknr = to_disk<base::le64, uint64_t>(location);
crc32c sum(BITMAP_CSUM_XOR); crc32c sum(BITMAP_CSUM_XOR);
@ -64,9 +64,9 @@ namespace {
uint64_t const INDEX_CSUM_XOR = 160478; uint64_t const INDEX_CSUM_XOR = 160478;
// FIXME: factor out the common code in these validators // FIXME: factor out the common code in these validators
struct index_block_validator : public block_manager<>::validator { struct index_block_validator : public bcache::validator {
virtual void check(buffer<> const &b, block_address location) const { virtual void check(void const *raw, block_address location) const {
metadata_index const *mi = reinterpret_cast<metadata_index const *>(b.raw()); metadata_index const *mi = reinterpret_cast<metadata_index const *>(raw);
std::cerr << "check mi = " << mi << "\n"; std::cerr << "check mi = " << mi << "\n";
crc32c sum(INDEX_CSUM_XOR); crc32c sum(INDEX_CSUM_XOR);
sum.append(&mi->padding_, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&mi->padding_, MD_BLOCK_SIZE - sizeof(uint32_t));
@ -77,8 +77,8 @@ namespace {
throw checksum_error("bad block nr in metadata index block"); throw checksum_error("bad block nr in metadata index block");
} }
virtual void prepare(buffer<> &b, block_address location) const { virtual void prepare(void *raw, block_address location) const {
metadata_index *mi = reinterpret_cast<metadata_index *>(b.raw()); metadata_index *mi = reinterpret_cast<metadata_index *>(raw);
std::cerr << "prepare mi = " << mi << "\n"; std::cerr << "prepare mi = " << mi << "\n";
mi->blocknr_ = to_disk<base::le64, uint64_t>(location); mi->blocknr_ = to_disk<base::le64, uint64_t>(location);
@ -88,9 +88,9 @@ namespace {
} }
}; };
block_manager<>::validator::ptr bcache::validator::ptr
index_validator() { index_validator() {
return block_manager<>::validator::ptr(new index_block_validator()); return bcache::validator::ptr(new index_block_validator());
} }
//-------------------------------- //--------------------------------
@ -102,7 +102,7 @@ namespace {
bitmap(transaction_manager::ptr tm, bitmap(transaction_manager::ptr tm,
index_entry const &ie, index_entry const &ie,
block_manager<>::validator::ptr v) bcache::validator::ptr v)
: tm_(tm), : tm_(tm),
validator_(v), validator_(v),
ie_(ie) { ie_(ie) {
@ -174,17 +174,17 @@ namespace {
private: private:
void *bitmap_data(transaction_manager::write_ref &wr) { void *bitmap_data(transaction_manager::write_ref &wr) {
bitmap_header *h = reinterpret_cast<bitmap_header *>(&wr.data()[0]); bitmap_header *h = reinterpret_cast<bitmap_header *>(wr.data());
return h + 1; return h + 1;
} }
void const *bitmap_data(transaction_manager::read_ref &rr) const { void const *bitmap_data(transaction_manager::read_ref &rr) const {
bitmap_header const *h = reinterpret_cast<bitmap_header const *>(&rr.data()[0]); bitmap_header const *h = reinterpret_cast<bitmap_header const *>(rr.data());
return h + 1; return h + 1;
} }
transaction_manager::ptr tm_; transaction_manager::ptr tm_;
block_manager<>::validator::ptr validator_; bcache::validator::ptr validator_;
index_entry ie_; index_entry ie_;
}; };
@ -504,7 +504,7 @@ namespace {
} }
transaction_manager::ptr tm_; transaction_manager::ptr tm_;
block_manager<>::validator::ptr bitmap_validator_; bcache::validator::ptr bitmap_validator_;
index_store::ptr indexes_; index_store::ptr indexes_;
block_address nr_blocks_; block_address nr_blocks_;
block_address nr_allocated_; block_address nr_allocated_;
@ -632,7 +632,7 @@ namespace {
tm_->shadow(bitmap_root_, index_validator()); tm_->shadow(bitmap_root_, index_validator());
bitmap_root_ = p.first.get_location(); bitmap_root_ = p.first.get_location();
metadata_index *mdi = reinterpret_cast<metadata_index *>(p.first.data().raw()); metadata_index *mdi = reinterpret_cast<metadata_index *>(p.first.data());
for (unsigned i = 0; i < entries_.size(); i++) for (unsigned i = 0; i < entries_.size(); i++)
index_entry_traits::pack(entries_[i], mdi->index[i]); index_entry_traits::pack(entries_[i], mdi->index[i]);
@ -665,7 +665,7 @@ namespace {
block_manager<>::read_ref rr = block_manager<>::read_ref rr =
tm_->read_lock(bitmap_root_, index_validator()); tm_->read_lock(bitmap_root_, index_validator());
metadata_index const *mdi = reinterpret_cast<metadata_index const *>(&rr.data()); metadata_index const *mdi = reinterpret_cast<metadata_index const *>(rr.data());
for (unsigned i = 0; i < entries_.size(); i++) for (unsigned i = 0; i < entries_.size(); i++)
index_entry_traits::unpack(*(mdi->index + i), entries_[i]); index_entry_traits::unpack(*(mdi->index + i), entries_[i]);
} }

View File

@ -72,7 +72,7 @@ transaction_manager::shadow(block_address orig, validator v)
throw runtime_error("transaction_manager::shadow() couldn't allocate new block"); throw runtime_error("transaction_manager::shadow() couldn't allocate new block");
write_ref dest = bm_->write_lock_zero(*mb, v); write_ref dest = bm_->write_lock_zero(*mb, v);
::memcpy(dest.data().raw(), src.data().raw(), MD_BLOCK_SIZE); // FIXME: use buffer copy method ::memcpy(dest.data(), src.data(), MD_BLOCK_SIZE);
sm_->dec(orig); sm_->dec(orig);
add_shadow(dest.get_location()); add_shadow(dest.get_location());

View File

@ -33,7 +33,7 @@ namespace persistent_data {
typedef boost::shared_ptr<transaction_manager> ptr; typedef boost::shared_ptr<transaction_manager> ptr;
typedef block_manager<>::read_ref read_ref; typedef block_manager<>::read_ref read_ref;
typedef block_manager<>::write_ref write_ref; typedef block_manager<>::write_ref write_ref;
typedef block_manager<>::validator::ptr validator; typedef bcache::validator::ptr validator;
// If the space map is persistent, then the caller should // If the space map is persistent, then the caller should
// hold onto a reference and remember to call sm_->commit() // hold onto a reference and remember to call sm_->commit()

View File

@ -197,7 +197,7 @@ metadata::commit()
metadata_sm_->copy_root(&sb_.metadata_space_map_root_, sizeof(sb_.metadata_space_map_root_)); metadata_sm_->copy_root(&sb_.metadata_space_map_root_, sizeof(sb_.metadata_space_map_root_));
write_ref superblock = tm_->get_bm()->superblock_zero(SUPERBLOCK_LOCATION, superblock_validator()); write_ref superblock = tm_->get_bm()->superblock_zero(SUPERBLOCK_LOCATION, superblock_validator());
superblock_disk *disk = reinterpret_cast<superblock_disk *>(superblock.data().raw()); superblock_disk *disk = reinterpret_cast<superblock_disk *>(superblock.data());
superblock_traits::pack(sb_, *disk); superblock_traits::pack(sb_, *disk);
} }

View File

@ -85,17 +85,17 @@ namespace {
unsigned const SECTOR_TO_BLOCK_SHIFT = 3; unsigned const SECTOR_TO_BLOCK_SHIFT = 3;
uint32_t const SUPERBLOCK_CSUM_SEED = 160774; uint32_t const SUPERBLOCK_CSUM_SEED = 160774;
struct sb_validator : public block_manager<>::validator { struct sb_validator : public bcache::validator {
virtual void check(buffer<> const &b, block_address location) const { virtual void check(void const *raw, block_address location) const {
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(b.raw()); superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(raw);
crc32c sum(SUPERBLOCK_CSUM_SEED); crc32c sum(SUPERBLOCK_CSUM_SEED);
sum.append(&sbd->flags_, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&sbd->flags_, MD_BLOCK_SIZE - sizeof(uint32_t));
if (sum.get_sum() != to_cpu<uint32_t>(sbd->csum_)) if (sum.get_sum() != to_cpu<uint32_t>(sbd->csum_))
throw checksum_error("bad checksum in superblock"); throw checksum_error("bad checksum in superblock");
} }
virtual void prepare(buffer<> &b, block_address location) const { virtual void prepare(void *raw, block_address location) const {
superblock_disk *sbd = reinterpret_cast<superblock_disk *>(b.raw()); superblock_disk *sbd = reinterpret_cast<superblock_disk *>(raw);
crc32c sum(SUPERBLOCK_CSUM_SEED); crc32c sum(SUPERBLOCK_CSUM_SEED);
sum.append(&sbd->flags_, MD_BLOCK_SIZE - sizeof(uint32_t)); sum.append(&sbd->flags_, MD_BLOCK_SIZE - sizeof(uint32_t));
sbd->csum_ = to_disk<base::le32>(sum.get_sum()); sbd->csum_ = to_disk<base::le32>(sum.get_sum());
@ -103,10 +103,10 @@ namespace {
}; };
} }
block_manager<>::validator::ptr bcache::validator::ptr
thin_provisioning::superblock_validator() thin_provisioning::superblock_validator()
{ {
return block_manager<>::validator::ptr(new sb_validator); return bcache::validator::ptr(new sb_validator);
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -151,7 +151,7 @@ namespace thin_provisioning {
superblock sb; superblock sb;
block_manager<>::read_ref r = bm->read_lock(location, superblock_validator()); block_manager<>::read_ref r = bm->read_lock(location, superblock_validator());
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data()); superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(r.data());
superblock_traits::unpack(*sbd, sb); superblock_traits::unpack(*sbd, sb);
return sb; return sb;
} }
@ -164,7 +164,7 @@ namespace thin_provisioning {
void write_superblock(block_manager<>::ptr bm, superblock_detail::superblock const &sb) void write_superblock(block_manager<>::ptr bm, superblock_detail::superblock const &sb)
{ {
block_manager<>::write_ref w = bm->write_lock(SUPERBLOCK_LOCATION, superblock_validator()); block_manager<>::write_ref w = bm->write_lock(SUPERBLOCK_LOCATION, superblock_validator());
superblock_disk *disk = reinterpret_cast<superblock_disk *>(w.data().raw()); superblock_disk *disk = reinterpret_cast<superblock_disk *>(w.data());
superblock_traits::pack(sb, *disk); superblock_traits::pack(sb, *disk);
} }

View File

@ -124,7 +124,7 @@ namespace thin_provisioning {
}; };
} }
persistent_data::block_manager<>::validator::ptr superblock_validator(); bcache::validator::ptr superblock_validator();
// FIXME: should we put init_superblock in here too? // FIXME: should we put init_superblock in here too?