This commit is contained in:
Joe Thornber
2014-07-28 14:13:28 +01:00
parent ab6d31f136
commit 840be1b6c9
4 changed files with 155 additions and 203 deletions

View File

@@ -6,6 +6,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <stdexcept>
#include <libaio.h>
#include <memory>
#include <stdint.h>
@@ -36,12 +37,13 @@ namespace bcache {
//----------------------------------------------------------------
// FIXME: throw exceptions rather than returning errors
class block_cache : private boost::noncopyable {
public:
enum block_flags {
IO_PENDING = (1 << 0),
DIRTY = (1 << 1)
BF_IO_PENDING = (1 << 0),
BF_DIRTY = (1 << 1),
BF_FLUSH = (1 << 2),
BF_PREVIOUSLY_DIRTY = (1 << 3)
};
class block : private boost::noncopyable {
@@ -58,16 +60,49 @@ namespace bcache {
return data_;
}
void mark_dirty() {
flags_ |= BF_DIRTY;
}
void mark_flush() {
flags_ |= BF_FLUSH;
}
void set_flags(unsigned flags) {
flags_ |= flags;
}
unsigned test_flags(unsigned flags) const {
return flags_ & flags;
}
void clear_flags(unsigned flags) {
flags_ &= ~flags;
}
void get() {
ref_count_++;
};
void put() {
if (!ref_count_)
throw std::runtime_error("bad put");
if (!--ref_count_)
bc_->release(*this);
}
private:
friend class block_cache;
block_cache *bc_;
uint64_t index_;
void *data_;
list_head list_;
list_head hash_list_;
block_cache *bc_;
unsigned ref_count_;
int error_;
@@ -87,18 +122,12 @@ namespace bcache {
enum get_flags {
GF_ZERO = (1 << 0),
GF_CAN_BLOCK = (1 << 1)
GF_DIRTY = (1 << 1),
GF_BARRIER = (1 << 1)
};
// FIXME: what if !GF_CAN_BLOCK?
block_cache::block &get(block_address index, unsigned flags, validator::ptr v);
enum put_flags {
PF_DIRTY = (1 << 0),
};
void put(block_cache::block &block, unsigned flags);
/*
* Flush can fail if an earlier write failed. You do not know which block
* failed. Make sure you build your recovery with this in mind.
@@ -131,9 +160,10 @@ namespace bcache {
unsigned calc_nr_buckets(unsigned nr_blocks);
void zero_block(block &b);
block *lookup_or_read_block(block_address index, unsigned flags, validator::ptr v);
unsigned test_flags(block &b, unsigned flags);
void clear_flags(block &b, unsigned flags);
void set_flags(block &b, unsigned flags);
void preemptive_writeback();
void release(block_cache::block &block);
void check_index(block_address index) const;
//--------------------------------
@@ -169,60 +199,6 @@ namespace bcache {
unsigned mask_;
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
}
//----------------------------------------------------------------