thin-provisioning-tools/block.h
2011-06-23 14:47:08 +01:00

117 lines
2.4 KiB
C++

#ifndef BLOCK_H
#define BLOCK_H
#include <stdint.h>
#include <map>
#include <vector>
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
//----------------------------------------------------------------
namespace persistent_data {
typedef uint64_t block_address;
template <uint32_t BlockSize>
class block_manager : private boost::noncopyable {
public:
typedef boost::shared_ptr<block_manager> ptr;
block_manager(std::string const &path);
~block_manager();
typedef unsigned char buffer[BlockSize];
typedef unsigned char const const_buffer[BlockSize];
class block;
class block_validator {
public:
virtual ~block_validator() {}
virtual void check(block const &b) const = 0;
virtual void prepare(block &b) const = 0;
};
struct block {
typedef boost::optional<block_validator> maybe_validator;
block(block_address location,
maybe_validator v = maybe_validator())
: location_(location),
validator_(v) {
}
block_address location_;
buffer data_;
boost::optional<block_validator> validator_;
};
typedef boost::shared_ptr<block> block_ptr;
class read_ref {
public:
read_ref(block_ptr b);
virtual ~read_ref() {}
block_address get_location() const;
const_buffer &data() const;
protected:
block_ptr block_;
};
// Inherited from read_ref, since you can read a block that's write
// locked.
class write_ref : public read_ref {
public:
using read_ref::data;
buffer &data();
};
// Locking methods
read_ref
read_lock(block_address location);
boost::optional<read_ref>
read_try_lock(block_address location);
write_ref
write_lock(block_address location);
write_ref
write_lock_zero(block_address location);
// Validator variants
read_ref
read_lock(block_address location, block_validator const &v);
boost::optional<read_ref>
read_try_lock(block_address location, block_validator const &v);
write_ref
write_lock(block_address location, block_validator const &v);
write_ref
write_lock_zero(block_address location, block_validator const &v);
// Use this to commit changes
void flush(write_ref super_block);
private:
void read_block(block &b);
void write_block(block const &b);
void zero_block(block &b);
void write_and_release(block *b);
int fd_;
};
}
//----------------------------------------------------------------
#endif