[block_manager] Track the number of superblocks, throw an exception if someone tries to open two a once.
This commit is contained in:
parent
94356a1648
commit
6f804cab24
@ -78,17 +78,17 @@ namespace persistent_data {
|
|||||||
class write_ref : public read_ref {
|
class write_ref : public read_ref {
|
||||||
public:
|
public:
|
||||||
write_ref(block_cache::block &b);
|
write_ref(block_cache::block &b);
|
||||||
|
write_ref(block_cache::block &b, unsigned &ref_count);
|
||||||
|
write_ref(write_ref const &rhs);
|
||||||
|
~write_ref();
|
||||||
|
|
||||||
|
write_ref const &operator =(write_ref const &rhs);
|
||||||
|
|
||||||
using read_ref::data;
|
using read_ref::data;
|
||||||
void *data();
|
void *data();
|
||||||
};
|
|
||||||
|
|
||||||
class super_ref : public write_ref {
|
private:
|
||||||
public:
|
unsigned *ref_count_;
|
||||||
super_ref(block_cache::block &b);
|
|
||||||
|
|
||||||
using read_ref::data;
|
|
||||||
using write_ref::data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Locking methods
|
// Locking methods
|
||||||
@ -140,6 +140,7 @@ namespace persistent_data {
|
|||||||
|
|
||||||
int fd_;
|
int fd_;
|
||||||
mutable block_cache bc_;
|
mutable block_cache bc_;
|
||||||
|
unsigned superblock_ref_count_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A little utility to help build validators
|
// A little utility to help build validators
|
||||||
|
@ -152,10 +152,51 @@ namespace persistent_data {
|
|||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
block_manager<BlockSize>::write_ref::write_ref(block_cache::block &b)
|
block_manager<BlockSize>::write_ref::write_ref(block_cache::block &b)
|
||||||
: read_ref(b)
|
: read_ref(b),
|
||||||
|
ref_count_(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <uint32_t BlockSize>
|
||||||
|
block_manager<BlockSize>::write_ref::write_ref(block_cache::block &b, unsigned &ref_count)
|
||||||
|
: read_ref(b),
|
||||||
|
ref_count_(&ref_count) {
|
||||||
|
if (*ref_count_)
|
||||||
|
throw std::runtime_error("superblock already locked");
|
||||||
|
(*ref_count_)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t BlockSize>
|
||||||
|
block_manager<BlockSize>::write_ref::write_ref(write_ref const &rhs)
|
||||||
|
: read_ref(rhs),
|
||||||
|
ref_count_(rhs.ref_count_) {
|
||||||
|
if (ref_count_)
|
||||||
|
(*ref_count_)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t BlockSize>
|
||||||
|
block_manager<BlockSize>::write_ref::~write_ref()
|
||||||
|
{
|
||||||
|
if (ref_count_) {
|
||||||
|
if (!*ref_count_)
|
||||||
|
throw std::runtime_error("write_ref ref_count going below zero");
|
||||||
|
|
||||||
|
(*ref_count_)--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t BlockSize>
|
||||||
|
typename block_manager<BlockSize>::write_ref const &
|
||||||
|
block_manager<BlockSize>::write_ref::operator =(write_ref const &rhs)
|
||||||
|
{
|
||||||
|
if (&rhs != this) {
|
||||||
|
read_ref::operator =(rhs);
|
||||||
|
ref_count_ = rhs.ref_count_;
|
||||||
|
if (ref_count_)
|
||||||
|
(*ref_count_)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
void *
|
void *
|
||||||
block_manager<BlockSize>::write_ref::data()
|
block_manager<BlockSize>::write_ref::data()
|
||||||
@ -163,14 +204,6 @@ namespace persistent_data {
|
|||||||
return read_ref::b_.get_data();
|
return read_ref::b_.get_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------
|
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
|
||||||
block_manager<BlockSize>::super_ref::super_ref(block_cache::block &b)
|
|
||||||
: write_ref(b)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
@ -179,7 +212,8 @@ namespace persistent_data {
|
|||||||
unsigned max_concurrent_blocks,
|
unsigned max_concurrent_blocks,
|
||||||
mode m)
|
mode m)
|
||||||
: fd_(open_or_create_block_file(path, nr_blocks * BlockSize, m)),
|
: fd_(open_or_create_block_file(path, nr_blocks * BlockSize, m)),
|
||||||
bc_(fd_, BlockSize >> SECTOR_SHIFT, nr_blocks, 1024u * 1024u * 16)
|
bc_(fd_, BlockSize >> SECTOR_SHIFT, nr_blocks, 1024u * 1024u * 16),
|
||||||
|
superblock_ref_count_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +269,7 @@ namespace persistent_data {
|
|||||||
typename bcache::validator::ptr v)
|
typename bcache::validator::ptr v)
|
||||||
{
|
{
|
||||||
block_cache::block &b = bc_.get(location, block_cache::GF_BARRIER, v);
|
block_cache::block &b = bc_.get(location, block_cache::GF_BARRIER, v);
|
||||||
return super_ref(b);
|
return write_ref(b, superblock_ref_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
@ -244,7 +278,7 @@ namespace persistent_data {
|
|||||||
typename bcache::validator::ptr v)
|
typename bcache::validator::ptr v)
|
||||||
{
|
{
|
||||||
block_cache::block &b = bc_.get(location, block_cache::GF_ZERO | block_cache::GF_BARRIER, v);
|
block_cache::block &b = bc_.get(location, block_cache::GF_ZERO | block_cache::GF_BARRIER, v);
|
||||||
return super_ref(b);
|
return write_ref(b, superblock_ref_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
|
Loading…
Reference in New Issue
Block a user