wip
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user