From d517684c95dd4fee53e1f04155bd105d98bfc7f7 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Tue, 22 Jul 2014 16:41:39 +0100 Subject: [PATCH] Initial code drop for merging block_cache --- Makefile.in | 26 +- caching/cache_check.cc | 2 +- caching/cache_dump.cc | 2 +- caching/cache_repair.cc | 4 +- caching/cache_restore.cc | 2 +- era/era_check.cc | 2 +- era/era_dump.cc | 2 +- era/era_invalidate.cc | 2 +- persistent-data/block.h | 74 ++--- persistent-data/block.tcc | 358 +++++++----------------- persistent-data/buffer.h | 47 ++-- persistent-data/cache.h | 284 ------------------- persistent-data/file_utils.cc | 2 +- persistent-data/file_utils.h | 2 +- persistent-data/lock_tracker.cc | 127 --------- persistent-data/lock_tracker.h | 61 ---- persistent-data/space-maps/recursive.cc | 4 +- thin-provisioning/metadata.cc | 6 +- thin-provisioning/metadata_checker.cc | 2 +- thin-provisioning/thin_check.cc | 4 +- thin-provisioning/thin_delta.cc | 2 +- thin-provisioning/thin_rmap.cc | 2 +- unit-tests/array_t.cc | 2 +- unit-tests/bitset_t.cc | 2 +- unit-tests/block_t.cc | 2 +- unit-tests/btree_t.cc | 2 +- unit-tests/space_map_t.cc | 4 +- unit-tests/transaction_manager_t.cc | 2 +- 28 files changed, 186 insertions(+), 845 deletions(-) delete mode 100644 persistent-data/cache.h delete mode 100644 persistent-data/lock_tracker.cc delete mode 100644 persistent-data/lock_tracker.h diff --git a/Makefile.in b/Makefile.in index eab3006..e65667d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -41,6 +41,8 @@ PROGRAMS=\ all: $(PROGRAMS) SOURCE=\ + block-cache/block_cache.cc \ + \ base/base64.cc \ base/endian_utils.cc \ base/error_state.cc \ @@ -65,7 +67,6 @@ SOURCE=\ persistent-data/error_set.cc \ persistent-data/file_utils.cc \ persistent-data/hex_dump.cc \ - persistent-data/lock_tracker.cc \ persistent-data/transaction_manager.cc \ \ persistent-data/data-structures/bitset.cc \ @@ -115,7 +116,7 @@ CXXFLAGS+=-g -Wall -fno-strict-aliasing CXXFLAGS+=@CXXOPTIMISE_FLAG@ CXXFLAGS+=@CXXDEBUG_FLAG@ INCLUDES+=-I$(TOP_BUILDDIR) -I$(TOP_DIR) -I$(TOP_DIR)/thin-provisioning -LIBS:=-lstdc++ +LIBS:=-lstdc++ -laio LIBEXPAT:=-lexpat INSTALL:=@INSTALL@ PREFIX:=@prefix@ @@ -168,6 +169,8 @@ THIN_DUMP_SOURCE=$(SOURCE) THIN_REPAIR_SOURCE=$(SOURCE) THIN_RESTORE_SOURCE=$(SOURCE) THIN_CHECK_SOURCE=\ + block-cache/block_cache.cc \ + \ base/error_state.cc \ base/endian_utils.cc \ \ @@ -175,7 +178,6 @@ THIN_CHECK_SOURCE=\ persistent-data/error_set.cc \ persistent-data/file_utils.cc \ persistent-data/hex_dump.cc \ - persistent-data/lock_tracker.cc \ persistent-data/data-structures/btree.cc \ persistent-data/space_map.cc \ persistent-data/space-maps/disk.cc \ @@ -190,6 +192,8 @@ THIN_CHECK_SOURCE=\ thin-provisioning/superblock.cc THIN_DELTA_SOURCE=\ + block-cache/block_cache.cc \ + \ base/error_state.cc \ base/endian_utils.cc \ \ @@ -197,7 +201,6 @@ THIN_DELTA_SOURCE=\ persistent-data/error_set.cc \ persistent-data/file_utils.cc \ persistent-data/hex_dump.cc \ - persistent-data/lock_tracker.cc \ persistent-data/data-structures/btree.cc \ persistent-data/space_map.cc \ persistent-data/space-maps/disk.cc \ @@ -212,13 +215,14 @@ THIN_DELTA_SOURCE=\ thin-provisioning/superblock.cc THIN_RMAP_SOURCE=\ + block-cache/block_cache.cc \ + \ base/endian_utils.cc \ \ persistent-data/checksum.cc \ persistent-data/error_set.cc \ persistent-data/file_utils.cc \ persistent-data/hex_dump.cc \ - persistent-data/lock_tracker.cc \ persistent-data/data-structures/btree.cc \ persistent-data/space_map.cc \ persistent-data/space-maps/disk.cc \ @@ -276,6 +280,8 @@ thin_metadata_size: thin-provisioning/thin_metadata_size.o # Cache tools CACHE_CHECK_SOURCE=\ + block-cache/block_cache.cc \ + \ base/base64.cc \ base/error_state.cc \ base/endian_utils.cc \ @@ -284,7 +290,6 @@ CACHE_CHECK_SOURCE=\ persistent-data/error_set.cc \ persistent-data/file_utils.cc \ persistent-data/hex_dump.cc \ - persistent-data/lock_tracker.cc \ persistent-data/data-structures/btree.cc \ persistent-data/data-structures/bitset.cc \ persistent-data/space_map.cc \ @@ -336,6 +341,8 @@ cache_metadata_size: caching/cache_metadata_size.o # Era tools ERA_CHECK_SOURCE=\ + block-cache/block_cache.cc \ + \ base/base64.cc \ base/error_state.cc \ base/endian_utils.cc \ @@ -350,7 +357,6 @@ ERA_CHECK_SOURCE=\ persistent-data/error_set.cc \ persistent-data/file_utils.cc \ persistent-data/hex_dump.cc \ - persistent-data/lock_tracker.cc \ persistent-data/data-structures/btree.cc \ persistent-data/data-structures/bitset.cc \ persistent-data/space_map.cc \ @@ -366,6 +372,8 @@ era_check: $(ERA_CHECK_OBJECTS) era/era_check.o $(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS) $(LIBEXPAT) ERA_DUMP_SOURCE=\ + block-cache/block_cache.cc \ + \ base/base64.cc \ base/error_state.cc \ base/endian_utils.cc \ @@ -382,7 +390,6 @@ ERA_DUMP_SOURCE=\ persistent-data/error_set.cc \ persistent-data/file_utils.cc \ persistent-data/hex_dump.cc \ - persistent-data/lock_tracker.cc \ persistent-data/data-structures/btree.cc \ persistent-data/data-structures/bitset.cc \ persistent-data/space_map.cc \ @@ -398,6 +405,8 @@ era_dump: $(ERA_DUMP_OBJECTS) era/era_dump.o $(V) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS) ERA_INVALIDATE_SOURCE=\ + block-cache/block_cache.cc \ + \ base/base64.cc \ base/error_state.cc \ base/endian_utils.cc \ @@ -414,7 +423,6 @@ ERA_INVALIDATE_SOURCE=\ persistent-data/error_set.cc \ persistent-data/file_utils.cc \ persistent-data/hex_dump.cc \ - persistent-data/lock_tracker.cc \ persistent-data/data-structures/btree.cc \ persistent-data/data-structures/bitset.cc \ persistent-data/space_map.cc \ diff --git a/caching/cache_check.cc b/caching/cache_check.cc index 94ea86b..d5ebc19 100644 --- a/caching/cache_check.cc +++ b/caching/cache_check.cc @@ -286,7 +286,7 @@ namespace { throw runtime_error(msg.str()); } - block_manager<>::ptr bm = open_bm(path, block_io<>::READ_ONLY); + block_manager<>::ptr bm = open_bm(path, block_manager<>::READ_ONLY); err = metadata_check(bm, fs); return err == NO_ERROR ? 0 : 1; diff --git a/caching/cache_dump.cc b/caching/cache_dump.cc index ea13c55..938ddd5 100644 --- a/caching/cache_dump.cc +++ b/caching/cache_dump.cc @@ -34,7 +34,7 @@ namespace { int dump(string const &dev, string const &output, flags const &fs) { try { - block_manager<>::ptr bm = open_bm(dev, block_io<>::READ_ONLY); + block_manager<>::ptr bm = open_bm(dev, block_manager<>::READ_ONLY); metadata::ptr md(new metadata(bm, metadata::OPEN)); if (want_stdout(output)) { diff --git a/caching/cache_repair.cc b/caching/cache_repair.cc index 4a8cd9c..77e5ff6 100644 --- a/caching/cache_repair.cc +++ b/caching/cache_repair.cc @@ -16,12 +16,12 @@ using namespace caching; namespace { metadata::ptr open_metadata_for_read(string const &path) { - block_manager<>::ptr bm = open_bm(path, block_io<>::READ_ONLY); + block_manager<>::ptr bm = open_bm(path, block_manager<>::READ_ONLY); return metadata::ptr(new metadata(bm, metadata::OPEN)); } emitter::ptr output_emitter(string const &path) { - block_manager<>::ptr bm = open_bm(path, block_io<>::READ_WRITE); + block_manager<>::ptr bm = open_bm(path, block_manager<>::READ_WRITE); metadata::ptr md(new metadata(bm, metadata::CREATE)); return create_restore_emitter(md, true); } diff --git a/caching/cache_restore.cc b/caching/cache_restore.cc index 536ef82..d38d748 100644 --- a/caching/cache_restore.cc +++ b/caching/cache_restore.cc @@ -37,7 +37,7 @@ namespace { int restore(flags const &fs) { try { - block_manager<>::ptr bm = open_bm(*fs.output, block_io<>::READ_WRITE); + block_manager<>::ptr bm = open_bm(*fs.output, block_manager<>::READ_WRITE); metadata::ptr md(new metadata(bm, metadata::CREATE)); emitter::ptr restorer = create_restore_emitter(md, fs.clean_shutdown); diff --git a/era/era_check.cc b/era/era_check.cc index 3e3f1fd..98af455 100644 --- a/era/era_check.cc +++ b/era/era_check.cc @@ -245,7 +245,7 @@ namespace { throw runtime_error(msg.str()); } - block_manager<>::ptr bm = open_bm(path, block_io<>::READ_ONLY); + block_manager<>::ptr bm = open_bm(path, block_manager<>::READ_ONLY); err = metadata_check(bm, fs); return err == NO_ERROR ? 0 : 1; diff --git a/era/era_dump.cc b/era/era_dump.cc index c9e14ad..760ebff 100644 --- a/era/era_dump.cc +++ b/era/era_dump.cc @@ -37,7 +37,7 @@ namespace { int dump(string const &dev, string const &output, flags const &fs) { try { - block_manager<>::ptr bm = open_bm(dev, block_io<>::READ_ONLY); + block_manager<>::ptr bm = open_bm(dev, block_manager<>::READ_ONLY); metadata::ptr md(new metadata(bm, metadata::OPEN)); if (want_stdout(output)) { diff --git a/era/era_invalidate.cc b/era/era_invalidate.cc index 42bf67b..aba7db8 100644 --- a/era/era_invalidate.cc +++ b/era/era_invalidate.cc @@ -146,7 +146,7 @@ namespace { int invalidate(string const &dev, string const &output, flags const &fs) { try { set blocks; - block_manager<>::ptr bm = open_bm(dev, block_io<>::READ_ONLY); + block_manager<>::ptr bm = open_bm(dev, block_manager<>::READ_ONLY); if (fs.metadata_snapshot_) { superblock sb = read_superblock(bm); diff --git a/persistent-data/block.h b/persistent-data/block.h index f7020d2..c514383 100644 --- a/persistent-data/block.h +++ b/persistent-data/block.h @@ -19,9 +19,8 @@ #ifndef BLOCK_H #define BLOCK_H +#include "block-cache/block_cache.h" #include "persistent-data/buffer.h" -#include "persistent-data/cache.h" -#include "persistent-data/lock_tracker.h" #include #include @@ -42,40 +41,20 @@ namespace persistent_data { typedef uint64_t block_address; template - class block_io : private boost::noncopyable { + class block_manager : private boost::noncopyable { public: - typedef boost::shared_ptr ptr; + typedef boost::shared_ptr ptr; + enum mode { READ_ONLY, READ_WRITE, CREATE }; - block_io(std::string const &path, block_address nr_blocks, mode m); - ~block_io(); - - block_address get_nr_blocks() const { - return nr_blocks_; - } - - void read_buffer(block_address location, buffer &buf) const; - void write_buffer(block_address location, buffer const &buf); - - private: - int fd_; - block_address nr_blocks_; - mode mode_; - }; - - template - class block_manager : private boost::noncopyable { - public: - typedef boost::shared_ptr ptr; - block_manager(std::string const &path, block_address nr_blocks, unsigned max_concurrent_locks, - typename block_io::mode m); + mode m); class validator { public: @@ -101,7 +80,7 @@ namespace persistent_data { struct block : private boost::noncopyable { typedef boost::shared_ptr ptr; - block(typename block_io::ptr io, + block(block_cache *bc, block_address location, block_type bt, typename validator::ptr v, @@ -116,17 +95,27 @@ namespace persistent_data { // FIXME: finish } - void flush(); - void change_validator(typename block_manager::validator::ptr v, bool check = true); - typename block_io::ptr io_; - block_address location_; - std::auto_ptr > data_; + block_type get_type() const; + uint64_t get_location() const; + + buffer const &get_buffer() const; + buffer &get_buffer(); + + void mark_dirty(); + void unlock(); + + private: + void check_not_unlocked() const; + + bc_block *internal_; typename validator::ptr validator_; block_type bt_; bool dirty_; + bool unlocked_; + buffer buffer_; }; class read_ref { @@ -206,25 +195,8 @@ namespace persistent_data { void check(block_address b) const; void write_block(typename block::ptr b) const; - enum lock_type { - READ_LOCK, - WRITE_LOCK - }; - - struct cache_traits { - typedef typename block::ptr value_type; - typedef block_address key_type; - - static key_type get_key(value_type const &v) { - return v->location_; - } - }; - - typename block_io::ptr io_; - mutable base::cache cache_; - - // FIXME: we need a dirty list as well as a cache - mutable lock_tracker tracker_; + int fd_; + block_cache *bc_; }; // A little utility to help build validators diff --git a/persistent-data/block.tcc b/persistent-data/block.tcc index 431cdd0..ab9a129 100644 --- a/persistent-data/block.tcc +++ b/persistent-data/block.tcc @@ -37,6 +37,7 @@ namespace { using namespace std; int const DEFAULT_MODE = 0666; + unsigned const SECTOR_SHIFT = 9; // FIXME: these will slow it down until we start doing async io. int const OPEN_FLAGS = O_DIRECT | O_SYNC; @@ -105,134 +106,84 @@ namespace { namespace persistent_data { template - block_io::block_io(std::string const &path, block_address nr_blocks, mode m) - : nr_blocks_(nr_blocks), - mode_(m) - { - off_t file_size = nr_blocks * BlockSize; - - switch (m) { - case READ_ONLY: - fd_ = open_block_file(path, file_size, false); - break; - - case READ_WRITE: - fd_ = open_block_file(path, file_size, true); - break; - - case CREATE: - fd_ = create_block_file(path, file_size); - break; - - default: - throw runtime_error("unsupported mode"); - } - } - - template - block_io::~block_io() - { - if (::close(fd_) < 0) - syscall_failed("close"); - } - - template - void - block_io::read_buffer(block_address location, buffer &buffer) const - { - off_t r; - r = ::lseek(fd_, BlockSize * location, SEEK_SET); - if (r == (off_t) -1) - throw std::runtime_error("lseek failed"); - - ssize_t n; - size_t remaining = BlockSize; - unsigned char *buf = buffer.raw(); - do { - n = ::read(fd_, buf, remaining); - if (n > 0) { - remaining -= n; - buf += n; - } - } while (remaining && ((n > 0) || (n == EINTR) || (n == EAGAIN))); - - if (n < 0) - throw std::runtime_error("read failed"); - } - - template - void - block_io::write_buffer(block_address location, buffer const &buffer) - { - off_t r; - r = ::lseek(fd_, BlockSize * location, SEEK_SET); - if (r == (off_t) -1) - throw std::runtime_error("lseek failed"); - - ssize_t n; - size_t remaining = BlockSize; - unsigned char const *buf = buffer.raw(); - do { - n = ::write(fd_, buf, remaining); - if (n > 0) { - remaining -= n; - buf += n; - } - } while (remaining && ((n > 0) || (n == EINTR) || (n == EAGAIN))); - - if (n < 0) { - std::ostringstream out; - out << "write failed to block " << location - << ", block size = " << BlockSize - << ", remaining = " << remaining - << ", n = " << n - << ", errno = " << errno - << ", fd_ = " << fd_ - << std::endl; - throw std::runtime_error(out.str()); - } - } - -//---------------------------------------------------------------- - - template - block_manager::block::block(typename block_io::ptr io, + block_manager::block::block(block_cache *bc, block_address location, block_type bt, typename validator::ptr v, bool zero) - : io_(io), - location_(location), - data_(new buffer()), - validator_(v), + : validator_(v), bt_(bt), - dirty_(false) + dirty_(false), + unlocked_(false), + buffer_(0, true) // FIXME: we don't know if it's writeable here :( { if (zero) { - // FIXME: duplicate memset - memset(data_->raw(), 0, BlockSize); - dirty_ = true; // redundant? + internal_ = block_cache_get(bc, location, GF_ZERO | GF_CAN_BLOCK); + if (!internal_) + throw std::runtime_error("Couldn't get block"); + dirty_ = true; } else { - io_->read_buffer(location_, *data_); - validator_->check(*data_, location_); + internal_ = block_cache_get(bc, location, GF_CAN_BLOCK); + if (!internal_) + throw std::runtime_error("Couldn't get block"); + + validator_->check(buffer_, internal_->index); } + + buffer_.set_data(internal_->data); } template block_manager::block::~block() { - flush(); + if (!unlocked_) + unlock(); } template void - block_manager::block::flush() + block_manager::block::unlock() { - if (dirty_) { - validator_->prepare(*data_, location_); - io_->write_buffer(location_, *data_); - dirty_ = false; - } + validator_->prepare(buffer_, internal_->index); + block_cache_put(internal_, dirty_ ? PF_DIRTY : 0); + unlocked_ = true; + } + + template + typename block_manager::block_type + block_manager::block::get_type() const + { + return bt_; + } + + template + uint64_t + block_manager::block::get_location() const + { + check_not_unlocked(); + return internal_->index; + } + + template + buffer const & + block_manager::block::get_buffer() const + { + return buffer_; + } + + template + buffer & + block_manager::block::get_buffer() + { + return buffer_; + } + + template + void + block_manager::block::mark_dirty() + { + check_not_unlocked(); + dirty_ = true; } template @@ -240,20 +191,29 @@ namespace persistent_data { block_manager::block::change_validator(typename block_manager::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(*data_, location_); + validator_->prepare(*internal_->data, internal_->index); validator_ = v; if (check) - validator_->check(*data_, location_); + validator_->check(*internal_->data, internal_->index); } } -//---------------------------------------------------------------- + template + void + block_manager::block::check_not_unlocked() const + { + if (unlocked_) + throw std::runtime_error("block prematurely unlocked"); + } + + //---------------------------------------------------------------- template block_manager::read_ref::read_ref(block_manager const &bm, @@ -278,14 +238,13 @@ namespace persistent_data { block_manager::read_ref::~read_ref() { if (!--(*holders_)) { - if (block_->bt_ == BT_SUPERBLOCK) { + if (block_->get_type() == BT_SUPERBLOCK) { bm_->flush(); - bm_->cache_.put(block_); + block_->unlock(); bm_->flush(); } else - bm_->cache_.put(block_); + block_->unlock(); - bm_->tracker_.unlock(block_->location_); delete holders_; } } @@ -308,44 +267,48 @@ namespace persistent_data { block_address block_manager::read_ref::get_location() const { - return block_->location_; + return block_->get_location(); } template buffer const & block_manager::read_ref::data() const { - return *block_->data_; + return block_->get_buffer(); } -//-------------------------------- + //-------------------------------- template block_manager::write_ref::write_ref(block_manager const &bm, typename block::ptr b) : read_ref(bm, b) { - b->dirty_ = true; + b->mark_dirty(); } template buffer & block_manager::write_ref::data() { - return *read_ref::block_->data_; + return read_ref::block_->get_buffer(); } -//---------------------------------------------------------------- + //---------------------------------------------------------------- template block_manager::block_manager(std::string const &path, block_address nr_blocks, unsigned max_concurrent_blocks, - typename block_io::mode mode) - : io_(new block_io(path, nr_blocks, mode)), - cache_(max(1024u, max_concurrent_blocks)), - tracker_(0, nr_blocks) + mode m) { + // Open the file descriptor + fd_ = open_block_file(path, nr_blocks * BlockSize, m == READ_WRITE); + + // Create the cache + bc_ = block_cache_create(fd_, BlockSize << SECTOR_SHIFT, nr_blocks, 1024u * BlockSize * 1.2); + if (!bc_) + throw std::runtime_error("couldn't create block cache"); } template @@ -353,27 +316,8 @@ namespace persistent_data { block_manager::read_lock(block_address location, typename block_manager::validator::ptr v) const { - tracker_.read_lock(location); - try { - check(location); - boost::optional cached_block = cache_.get(location); - - if (cached_block) { - typename block::ptr cb = *cached_block; - cb->check_read_lockable(); - cb->change_validator(v); - - return read_ref(*this, *cached_block); - } - - typename block::ptr b(new block(io_, location, BT_NORMAL, v)); - cache_.insert(b); - return read_ref(*this, b); - - } catch (...) { - tracker_.unlock(location); - throw; - } + typename block::ptr b(new block(bc_, location, BT_NORMAL, v, false)); + return read_ref(*this, b); } template @@ -381,29 +325,8 @@ namespace persistent_data { block_manager::write_lock(block_address location, typename block_manager::validator::ptr v) { - tracker_.write_lock(location); - try { - check(location); - - boost::optional cached_block = cache_.get(location); - - if (cached_block) { - typename block::ptr cb = *cached_block; - cb->check_write_lockable(); - cb->change_validator(v); - - return write_ref(*this, *cached_block); - } - - typename block::ptr b(new block(io_, location, BT_NORMAL, v)); - cache_.insert(b); - return write_ref(*this, b); - - } catch (...) { - tracker_.unlock(location); - throw; - } - + typename block::ptr b(new block(bc_, location, BT_NORMAL, v, false)); + return write_ref(*this, b); } template @@ -411,28 +334,8 @@ namespace persistent_data { block_manager::write_lock_zero(block_address location, typename block_manager::validator::ptr v) { - tracker_.write_lock(location); - try { - check(location); - - boost::optional cached_block = cache_.get(location); - if (cached_block) { - typename block::ptr cb = *cached_block; - cb->check_write_lockable(); - cb->change_validator(v, false); - memset((*cached_block)->data_->raw(), 0, BlockSize); - - return write_ref(*this, *cached_block); - } - - typename block::ptr b(new block(io_, location, BT_NORMAL, v, true)); - cache_.insert(b); - return write_ref(*this, b); - - } catch (...) { - tracker_.unlock(location); - throw; - } + typename block::ptr b(new block(bc_, location, BT_NORMAL, v, true)); + return write_ref(*this, b); } template @@ -440,29 +343,8 @@ namespace persistent_data { block_manager::superblock(block_address location, typename block_manager::validator::ptr v) { - tracker_.superblock_lock(location); - try { - check(location); - - boost::optional cached_block = cache_.get(location); - - if (cached_block) { - typename block::ptr cb = *cached_block; - cb->check_write_lockable(); - cb->bt_ = BT_SUPERBLOCK; - cb->change_validator(v); - - return write_ref(*this, *cached_block); - } - - typename block::ptr b(new block(io_, location, BT_SUPERBLOCK, v)); - cache_.insert(b); - return write_ref(*this, b); - - } catch (...) { - tracker_.unlock(location); - throw; - } + typename block::ptr b(new block(bc_, location, BT_SUPERBLOCK, v, false)); + return write_ref(*this, b); } template @@ -470,45 +352,15 @@ namespace persistent_data { block_manager::superblock_zero(block_address location, typename block_manager::validator::ptr v) { - tracker_.superblock_lock(location); - try { - check(location); - - boost::optional cached_block = cache_.get(location); - - if (cached_block) { - typename block::ptr cb = *cached_block; - cb->check_write_lockable(); - cb->bt_ = BT_SUPERBLOCK; - cb->change_validator(v, false); - memset(cb->data_->raw(), 0, BlockSize); // FIXME: add a zero method to buffer - - return write_ref(*this, *cached_block); - } - - typename block::ptr b(new block(io_, location, BT_SUPERBLOCK, v, true)); - cache_.insert(b); - return write_ref(*this, b); - - } catch (...) { - tracker_.unlock(location); - throw; - } - } - - template - void - block_manager::check(block_address b) const - { - if (b >= io_->get_nr_blocks()) - throw std::runtime_error("block address out of bounds"); + typename block::ptr b(new block(bc_, location, BT_SUPERBLOCK, v, true)); + return write_ref(*this, b); } template block_address block_manager::get_nr_blocks() const { - return io_->get_nr_blocks(); + return block_cache_get_nr_blocks(bc_); } template @@ -522,15 +374,7 @@ namespace persistent_data { void block_manager::flush() const { - cache_.iterate_unheld( - boost::bind(&block_manager::write_block, this, _1)); - } - - template - bool - block_manager::is_locked(block_address b) const - { - return tracker_.is_locked(b); + block_cache_flush(bc_); } } diff --git a/persistent-data/buffer.h b/persistent-data/buffer.h index 527a239..34aa31f 100644 --- a/persistent-data/buffer.h +++ b/persistent-data/buffer.h @@ -20,10 +20,8 @@ #define BUFFER_H #include -// #include #include -#include #include #include #include @@ -35,18 +33,14 @@ namespace persistent_data { uint32_t const DEFAULT_BUFFER_SIZE = 4096; - // Allocate buffer of Size with Alignment imposed. - // - // Allocation needs to be on the heap in order to provide alignment - // guarantees. - // - // Alignment must be a power of two. - template - class buffer : private boost::noncopyable { + template + class buffer { public: - BOOST_STATIC_ASSERT((Alignment > 1) & !(Alignment & (Alignment - 1))); + buffer(void *data, bool writeable = true) + : data_(static_cast(data)), + writeable_(writeable) { + } - static uint32_t const ALIGNMENT = Alignment; typedef boost::shared_ptr ptr; typedef boost::shared_ptr const_ptr; @@ -55,6 +49,7 @@ namespace persistent_data { } unsigned char &operator[](unsigned index) { + check_writeable(); check_index(index); return data_[index]; @@ -74,31 +69,23 @@ namespace persistent_data { return data_; } - static void *operator new(size_t s) { - // void *r; - // return posix_memalign(&r, Alignment, s) ? NULL : r; - - // Allocates size bytes and returns a pointer to the - // allocated memory. The memory address will be a - // multiple of 'Alignment', which must be a power of two - void *mem = memalign(Alignment, s); - if (!mem) - throw std::bad_alloc(); - - return mem; - } - - static void operator delete(void *p) { - free(p); + void set_data(void *data) { + data_ = static_cast(data); } private: - unsigned char data_[Size]; - static void check_index(unsigned index) { if (index >= Size) throw std::range_error("buffer index out of bounds"); } + + void check_writeable() const { + if (!writeable_) + throw std::runtime_error("buffer isn't writeable"); + } + + unsigned char *data_; + bool writeable_; }; } diff --git a/persistent-data/cache.h b/persistent-data/cache.h deleted file mode 100644 index 6c4e660..0000000 --- a/persistent-data/cache.h +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (C) 2011 Red Hat, Inc. All rights reserved. -// -// This file is part of the thin-provisioning-tools source. -// -// thin-provisioning-tools is free software: you can redistribute it -// and/or modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// thin-provisioning-tools is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with thin-provisioning-tools. If not, see -// . - -#ifndef CACHE_H -#define CACHE_H - -#include "deleter.h" - -#include -#include -#include -#include -#include -#include -#include - -//---------------------------------------------------------------- - -namespace base { - // ValueTraits needs to define value_type, key_type and a get_key() - // static function. Commonly you will want value_type to be a - // shared_ptr, with any teardown specific stuff in the destructor. - template - class cache { - public: - typedef typename ValueTraits::value_type value_type; - typedef typename ValueTraits::key_type key_type; - - cache(unsigned max_entries); - ~cache(); - - void insert(value_type const &v); - - boost::optional get(key_type const &k); - void put(value_type const &k); - - template - void iterate_unheld(T fn) const; - - private: - void make_space(); - - struct value_entry { - // FIXME: this means the cached object must have a - // default constructor also, which is a shame. - // so we can construct the headers. - value_entry() - : ref_count_(1) { - } - - explicit value_entry(value_type v) - : ref_count_(1), - v_(v) { - } - - struct lru { - lru() - : next_(0), - prev_(0) { - } - - value_entry *next_, *prev_; - }; - - struct lookup { - lookup() - : parent_(0), - left_(0), - right_(0), - color_() { - } - - value_entry *parent_, *left_, *right_; - int color_; - }; - - lru lru_; - lookup lookup_; - unsigned ref_count_; - value_type v_; - }; - - struct value_ptr_cmp { - bool operator() (value_entry const *lhs, value_entry const *rhs) { - key_type k1 = ValueTraits::get_key(lhs->v_); - key_type k2 = ValueTraits::get_key(rhs->v_); - - return k1 < k2; - } - }; - - struct key_value_ptr_cmp { - bool operator() (key_type const &k1, value_entry const *rhs) { - key_type k2 = ValueTraits::get_key(rhs->v_); - return k1 < k2; - } - - bool operator() (value_entry const *lhs, key_type const &k2) { - key_type k1 = ValueTraits::get_key(lhs->v_); - return k1 < k2; - } - - }; - - struct list_node_traits { - typedef value_entry node; - typedef value_entry *node_ptr; - typedef const value_entry *const_node_ptr; - - static node_ptr get_next(const_node_ptr n) { - return n->lru_.next_; - } - - static void set_next(node_ptr n, node_ptr next) { - n->lru_.next_ = next; - } - - static node_ptr get_previous(const_node_ptr n) { - return n->lru_.prev_; - } - - static void set_previous(node_ptr n, node_ptr prev) { - n->lru_.prev_ = prev; - } - }; - - struct rbtree_node_traits { - typedef value_entry node; - typedef value_entry *node_ptr; - typedef const value_entry * const_node_ptr; - typedef int color; - - static node_ptr get_parent(const_node_ptr n) { - return n->lookup_.parent_; - } - - static void set_parent(node_ptr n, node_ptr parent) { - n->lookup_.parent_ = parent; - } - - static node_ptr get_left(const_node_ptr n) { - return n->lookup_.left_; - } - - static void set_left(node_ptr n, node_ptr left) { - n->lookup_.left_ = left; - } - - static node_ptr get_right(const_node_ptr n) { - return n->lookup_.right_; - } - - static void set_right(node_ptr n, node_ptr right) { - n->lookup_.right_ = right; - } - - static int get_color(const_node_ptr n) { - return n->lookup_.color_; - } - - static void set_color(node_ptr n, color c) { - n->lookup_.color_ = c; - } - - static color red() { - return 0; - } - - static color black() { - return 1; - } - }; - - typedef boost::intrusive::circular_list_algorithms lru_algo; - typedef boost::intrusive::rbtree_algorithms lookup_algo; - - unsigned max_entries_; - unsigned current_entries_; - - value_entry lru_header_; - value_entry lookup_header_; - }; - - template - cache::cache(unsigned max_entries) - : max_entries_(max_entries), - current_entries_(0) { - lru_algo::init_header(&lru_header_); - lookup_algo::init_header(&lookup_header_); - } - - template - cache::~cache() { - utils::deleter d; - lookup_algo::clear_and_dispose(&lookup_header_, d); - } - - template - void - cache::insert(value_type const &v) { - make_space(); - - std::auto_ptr node(new value_entry(v)); - value_ptr_cmp cmp; - lookup_algo::insert_equal(&lookup_header_, &lookup_header_, node.get(), cmp); - node.release(); - current_entries_++; - } - - template - boost::optional - cache::get(key_type const &k) { - key_value_ptr_cmp cmp; - value_entry *node = lookup_algo::find(&lookup_header_, k, cmp); - if (node == &lookup_header_) - return boost::optional(); - - if (!node->ref_count_++) - lru_algo::unlink(node); - return boost::optional(node->v_); - } - - template - void - cache::put(value_type const &v) { - // FIXME: the lookup will go once we use a proper hook - key_value_ptr_cmp cmp; - key_type k = ValueTraits::get_key(v); - value_entry *node = lookup_algo::find(&lookup_header_, k, cmp); - if (node == &lookup_header_) - throw std::runtime_error("invalid put"); - - if (node->ref_count_ == 0) - throw std::runtime_error("invalid put"); - - if (!--node->ref_count_) - lru_algo::link_after(&lru_header_, node); - } - - template - void - cache::make_space() { - if (current_entries_ == max_entries_) { - value_entry *node = lru_header_.lru_.prev_; - if (node == &lru_header_) - throw std::runtime_error("cache full"); - - lru_algo::unlink(node); - lookup_algo::unlink(node); - delete node; - current_entries_--; - } - } - - template - template - void - cache::iterate_unheld(T fn) const { - value_entry *n = lru_header_.lru_.next_; - while (n != &lru_header_) { - fn(n->v_); - n = n->lru_.next_; - } - } -} - -//---------------------------------------------------------------- - -#endif diff --git a/persistent-data/file_utils.cc b/persistent-data/file_utils.cc index a96aec7..3dc9e2d 100644 --- a/persistent-data/file_utils.cc +++ b/persistent-data/file_utils.cc @@ -48,7 +48,7 @@ persistent_data::get_nr_blocks(string const &path) } persistent_data::block_manager<>::ptr -persistent_data::open_bm(std::string const &dev_path, block_io<>::mode m) +persistent_data::open_bm(std::string const &dev_path, block_manager<>::mode m) { block_address nr_blocks = get_nr_blocks(dev_path); return block_manager<>::ptr(new block_manager<>(dev_path, nr_blocks, 1, m)); diff --git a/persistent-data/file_utils.h b/persistent-data/file_utils.h index be1e492..d08fa96 100644 --- a/persistent-data/file_utils.h +++ b/persistent-data/file_utils.h @@ -10,7 +10,7 @@ // FIXME: move to a different unit namespace persistent_data { persistent_data::block_address get_nr_blocks(string const &path); - block_manager<>::ptr open_bm(std::string const &dev_path, block_io<>::mode m); + block_manager<>::ptr open_bm(std::string const &dev_path, block_manager<>::mode m); void check_file_exists(std::string const &file); } diff --git a/persistent-data/lock_tracker.cc b/persistent-data/lock_tracker.cc deleted file mode 100644 index b7800c3..0000000 --- a/persistent-data/lock_tracker.cc +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (C) 2012 Red Hat, Inc. All rights reserved. -// -// This file is part of the thin-provisioning-tools source. -// -// thin-provisioning-tools is free software: you can redistribute it -// and/or modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// thin-provisioning-tools is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with thin-provisioning-tools. If not, see -// . - -#include "lock_tracker.h" - -#include - -using namespace persistent_data; -using namespace std; - -//---------------------------------------------------------------- - -lock_tracker::lock_tracker(uint64_t low, uint64_t high) - : low_(low), - high_(high) -{ -} - -void -lock_tracker::read_lock(uint64_t key) -{ - check_key(key); - - LockMap::iterator it = locks_.find(key); - if (found(it)) { - if (it->second < 0) - throw runtime_error("already write locked"); - - it->second++; - - } else - locks_.insert(make_pair(key, 1)); -} - -void -lock_tracker::write_lock(uint64_t key) -{ - check_key(key); - - LockMap::const_iterator it = locks_.find(key); - if (found(it)) - throw runtime_error("already locked"); - - locks_.insert(make_pair(key, -1)); -} - -void -lock_tracker::superblock_lock(uint64_t key) -{ - if (superblock_) - throw runtime_error("superblock already held"); - - superblock_ = boost::optional(key); - try { - write_lock(key); - - } catch (...) { - superblock_ = boost::optional(); - } -} - -void -lock_tracker::unlock(uint64_t key) -{ - check_key(key); - - LockMap::const_iterator it = locks_.find(key); - if (!found(it)) - throw runtime_error("not locked"); - - if (superblock_ && *superblock_ == key) { - if (locks_.size() > 1) - throw runtime_error("superblock unlocked while other locks still held"); - - superblock_ = boost::optional(); - } - - if (it->second > 1) - locks_.insert(make_pair(key, it->second - 1)); - else - locks_.erase(key); - -} - -bool -lock_tracker::found(LockMap::const_iterator it) const -{ - return it != locks_.end(); -} - -bool -lock_tracker::valid_key(uint64_t key) const -{ - return (key >= low_ && key <= high_); -} - -void -lock_tracker::check_key(uint64_t key) const -{ - if (!valid_key(key)) - throw runtime_error("invalid key"); -} - -bool -lock_tracker::is_locked(uint64_t key) const -{ - check_key(key); - return found(locks_.find(key)); -} - -//---------------------------------------------------------------- - diff --git a/persistent-data/lock_tracker.h b/persistent-data/lock_tracker.h deleted file mode 100644 index 497e2cd..0000000 --- a/persistent-data/lock_tracker.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2011 Red Hat, Inc. All rights reserved. -// -// This file is part of the thin-provisioning-tools source. -// -// thin-provisioning-tools is free software: you can redistribute it -// and/or modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// thin-provisioning-tools is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with thin-provisioning-tools. If not, see -// . - -#ifndef LOCK_TRACKER_H -#define LOCK_TRACKER_H - -#include -#include -#include -#include - - -//---------------------------------------------------------------- - -namespace persistent_data { - class lock_tracker : private boost::noncopyable { - public: - lock_tracker(uint64_t low, uint64_t high); - - void read_lock(uint64_t key); - void write_lock(uint64_t key); - void superblock_lock(uint64_t key); - void unlock(uint64_t key); - - bool is_locked(uint64_t key) const; - - private: - typedef std::map LockMap; - - bool found(LockMap::const_iterator it) const; - - bool valid_key(uint64_t key) const; - void check_key(uint64_t key) const; - - // Positive for read lock, negative for write lock - LockMap locks_; - boost::optional superblock_; - - uint64_t low_; - uint64_t high_; - }; -} - -//---------------------------------------------------------------- - -#endif diff --git a/persistent-data/space-maps/recursive.cc b/persistent-data/space-maps/recursive.cc index 6533c20..dff28dc 100644 --- a/persistent-data/space-maps/recursive.cc +++ b/persistent-data/space-maps/recursive.cc @@ -19,6 +19,8 @@ #include "persistent-data/space-maps/recursive.h" #include "persistent-data/space-maps/subtracting_span_iterator.h" +#include + using namespace persistent_data; //---------------------------------------------------------------- @@ -286,7 +288,7 @@ namespace { BOP_SET }; - typedef map > op_map; + typedef map > op_map; op_map ops_; subtracting_span_iterator::block_set allocated_blocks_; diff --git a/thin-provisioning/metadata.cc b/thin-provisioning/metadata.cc index 908d16b..6136722 100644 --- a/thin-provisioning/metadata.cc +++ b/thin-provisioning/metadata.cc @@ -65,7 +65,7 @@ metadata::metadata(std::string const &dev_path, open_type ot, { switch (ot) { case OPEN: - tm_ = open_tm(open_bm(dev_path, block_io<>::READ_ONLY)); + tm_ = open_tm(open_bm(dev_path, block_manager<>::READ_ONLY)); sb_ = read_superblock(tm_->get_bm()); if (sb_.version_ != 1) @@ -90,7 +90,7 @@ metadata::metadata(std::string const &dev_path, open_type ot, break; case CREATE: - tm_ = open_tm(open_bm(dev_path, block_io<>::READ_WRITE)); + tm_ = open_tm(open_bm(dev_path, block_manager<>::READ_WRITE)); space_map::ptr core = tm_->get_sm(); metadata_sm_ = create_metadata_sm(tm_, tm_->get_bm()->get_nr_blocks()); copy_space_maps(metadata_sm_, core); @@ -118,7 +118,7 @@ metadata::metadata(std::string const &dev_path, open_type ot, metadata::metadata(std::string const &dev_path, block_address metadata_snap) { - tm_ = open_tm(open_bm(dev_path, block_io<>::READ_ONLY)); + tm_ = open_tm(open_bm(dev_path, block_manager<>::READ_ONLY)); sb_ = read_superblock(tm_->get_bm(), metadata_snap); // We don't open the metadata sm for a held root diff --git a/thin-provisioning/metadata_checker.cc b/thin-provisioning/metadata_checker.cc index e8bd6d3..7f3124a 100644 --- a/thin-provisioning/metadata_checker.cc +++ b/thin-provisioning/metadata_checker.cc @@ -378,7 +378,7 @@ namespace { static block_manager<>::ptr open_bm(string const &dev_path) { block_address nr_blocks = thin_provisioning::get_nr_blocks(dev_path); - return block_manager<>::ptr(new block_manager<>(dev_path, nr_blocks, 1, block_io<>::READ_ONLY)); + return block_manager<>::ptr(new block_manager<>(dev_path, nr_blocks, 1, block_manager<>::READ_ONLY)); } // FIXME: common code with metadata.cc diff --git a/thin-provisioning/thin_check.cc b/thin-provisioning/thin_check.cc index e468a02..e4cae83 100644 --- a/thin-provisioning/thin_check.cc +++ b/thin-provisioning/thin_check.cc @@ -42,7 +42,7 @@ namespace { block_manager<>::ptr open_bm(string const &path) { block_address nr_blocks = get_nr_blocks(path); - block_io<>::mode m = block_io<>::READ_ONLY; + block_manager<>::mode m = block_manager<>::READ_ONLY; return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m)); } @@ -225,7 +225,7 @@ namespace { } void clear_needs_check(string const &path) { - block_manager<>::ptr bm = open_bm(path, block_io<>::READ_WRITE); + block_manager<>::ptr bm = open_bm(path, block_manager<>::READ_WRITE); superblock_detail::superblock sb = read_superblock(bm); sb.set_needs_check_flag(false); diff --git a/thin-provisioning/thin_delta.cc b/thin-provisioning/thin_delta.cc index 396422b..59fefd3 100644 --- a/thin-provisioning/thin_delta.cc +++ b/thin-provisioning/thin_delta.cc @@ -72,7 +72,7 @@ namespace { block_manager<>::ptr open_bm(string const &path) { block_address nr_blocks = get_nr_blocks(path); - block_io<>::mode m = block_io<>::READ_ONLY; + block_manager<>::mode m = block_manager<>::READ_ONLY; return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m)); } diff --git a/thin-provisioning/thin_rmap.cc b/thin-provisioning/thin_rmap.cc index 9211459..70c7b38 100644 --- a/thin-provisioning/thin_rmap.cc +++ b/thin-provisioning/thin_rmap.cc @@ -23,7 +23,7 @@ namespace { block_manager<>::ptr open_bm(string const &path) { block_address nr_blocks = get_nr_blocks(path); - block_io<>::mode m = block_io<>::READ_ONLY; + block_manager<>::mode m = block_manager<>::READ_ONLY; return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m)); } diff --git a/unit-tests/array_t.cc b/unit-tests/array_t.cc index 0c688b4..5d0a733 100644 --- a/unit-tests/array_t.cc +++ b/unit-tests/array_t.cc @@ -78,7 +78,7 @@ namespace { private: static transaction_manager::ptr create_tm() { - block_manager<>::ptr bm(new block_manager<>("./test.data", NR_BLOCKS, 4, block_io<>::READ_WRITE)); + block_manager<>::ptr bm(new block_manager<>("./test.data", NR_BLOCKS, 4, block_manager<>::READ_WRITE)); space_map::ptr sm(new core_map(NR_BLOCKS)); transaction_manager::ptr tm(new transaction_manager(bm, sm)); return tm; diff --git a/unit-tests/bitset_t.cc b/unit-tests/bitset_t.cc index e2dc4cd..20d1b1f 100644 --- a/unit-tests/bitset_t.cc +++ b/unit-tests/bitset_t.cc @@ -34,7 +34,7 @@ namespace { transaction_manager::ptr create_tm() { - block_manager<>::ptr bm(new block_manager<>("./test.data", NR_BLOCKS, 4, block_io<>::READ_WRITE)); + block_manager<>::ptr bm(new block_manager<>("./test.data", NR_BLOCKS, 4, block_manager<>::READ_WRITE)); space_map::ptr sm(new core_map(NR_BLOCKS)); transaction_manager::ptr tm(new transaction_manager(bm, sm)); return tm; diff --git a/unit-tests/block_t.cc b/unit-tests/block_t.cc index 75dfa68..c336f46 100644 --- a/unit-tests/block_t.cc +++ b/unit-tests/block_t.cc @@ -64,7 +64,7 @@ namespace { TEST(BlockTests, bad_path) { - ASSERT_THROW(bm4096("/bogus/bogus/bogus", 1234, 4, block_io<>::READ_WRITE), + ASSERT_THROW(bm4096("/bogus/bogus/bogus", 1234, 4, block_manager<>::READ_WRITE), runtime_error); } diff --git a/unit-tests/btree_t.cc b/unit-tests/btree_t.cc index 8fe3a71..0d68343 100644 --- a/unit-tests/btree_t.cc +++ b/unit-tests/btree_t.cc @@ -33,7 +33,7 @@ namespace { transaction_manager::ptr create_tm() { - block_manager<>::ptr bm(new block_manager<>("./test.data", NR_BLOCKS, 4, block_io<>::READ_WRITE)); + block_manager<>::ptr bm(new block_manager<>("./test.data", NR_BLOCKS, 4, block_manager<>::READ_WRITE)); space_map::ptr sm(new core_map(NR_BLOCKS)); transaction_manager::ptr tm(new transaction_manager(bm, sm)); return tm; diff --git a/unit-tests/space_map_t.cc b/unit-tests/space_map_t.cc index c505ffb..c87d6f4 100644 --- a/unit-tests/space_map_t.cc +++ b/unit-tests/space_map_t.cc @@ -36,7 +36,7 @@ namespace { transaction_manager::ptr create_tm() { block_manager<>::ptr bm( - new block_manager<>("./test.data", NR_BLOCKS, MAX_LOCKS, block_io<>::READ_WRITE)); + new block_manager<>("./test.data", NR_BLOCKS, MAX_LOCKS, block_manager<>::READ_WRITE)); space_map::ptr sm(new core_map(NR_BLOCKS)); transaction_manager::ptr tm( new transaction_manager(bm, sm)); @@ -297,7 +297,7 @@ TEST(SpaceMapTests, test_sm_metadata) TEST(SpaceMapTests, test_metadata_and_disk) { block_manager<>::ptr bm( - new block_manager<>("./test.data", NR_BLOCKS, MAX_LOCKS, block_io<>::READ_WRITE)); + new block_manager<>("./test.data", NR_BLOCKS, MAX_LOCKS, block_manager<>::READ_WRITE)); space_map::ptr core_sm(new core_map(NR_BLOCKS)); transaction_manager::ptr tm(new transaction_manager(bm, core_sm)); persistent_space_map::ptr metadata_sm = persistent_data::create_metadata_sm(tm, NR_BLOCKS); diff --git a/unit-tests/transaction_manager_t.cc b/unit-tests/transaction_manager_t.cc index 384d82a..1697685 100644 --- a/unit-tests/transaction_manager_t.cc +++ b/unit-tests/transaction_manager_t.cc @@ -33,7 +33,7 @@ namespace { transaction_manager::ptr create_tm() { block_manager<>::ptr bm( - new block_manager<>("./test.data", NR_BLOCKS, MAX_HELD_LOCKS, block_io<>::READ_WRITE)); + new block_manager<>("./test.data", NR_BLOCKS, MAX_HELD_LOCKS, block_manager<>::READ_WRITE)); space_map::ptr sm(new core_map(NR_BLOCKS)); transaction_manager::ptr tm(new transaction_manager(bm, sm)); tm->get_sm()->inc(0);