Rename blockstore::Key -> blockstore::BlockId

This commit is contained in:
Sebastian Messmer 2017-09-17 02:07:27 +01:00
parent 10e11f67e2
commit 5458af7c52
146 changed files with 2013 additions and 2014 deletions

View File

@ -15,7 +15,7 @@ using cpputils::unique_ref;
using cpputils::Data; using cpputils::Data;
using blobstore::onblocks::datanodestore::DataLeafNode; using blobstore::onblocks::datanodestore::DataLeafNode;
using blobstore::onblocks::datanodestore::DataNodeLayout; using blobstore::onblocks::datanodestore::DataNodeLayout;
using blockstore::Key; using blockstore::BlockId;
using blobstore::onblocks::datatreestore::LeafHandle; using blobstore::onblocks::datatreestore::LeafHandle;
namespace blobstore { namespace blobstore {
@ -131,7 +131,7 @@ void BlobOnBlocks::write(const void *source, uint64_t offset, uint64_t count) {
if (leafDataOffset == 0 && leafDataSize == leaf.nodeStore()->layout().maxBytesPerLeaf()) { if (leafDataOffset == 0 && leafDataSize == leaf.nodeStore()->layout().maxBytesPerLeaf()) {
Data leafData(leafDataSize); Data leafData(leafDataSize);
std::memcpy(leafData.data(), (uint8_t*)source + indexOfFirstLeafByte - offset, leafDataSize); std::memcpy(leafData.data(), (uint8_t*)source + indexOfFirstLeafByte - offset, leafDataSize);
leaf.nodeStore()->overwriteLeaf(leaf.key(), std::move(leafData)); leaf.nodeStore()->overwriteLeaf(leaf.blockId(), std::move(leafData));
} else { } else {
//TODO Simplify formula, make it easier to understand //TODO Simplify formula, make it easier to understand
leaf.node()->write((uint8_t *) source + indexOfFirstLeafByte - offset + leafDataOffset, leafDataOffset, leaf.node()->write((uint8_t *) source + indexOfFirstLeafByte - offset + leafDataOffset, leafDataOffset,
@ -152,8 +152,8 @@ void BlobOnBlocks::flush() {
_datatree->flush(); _datatree->flush();
} }
const Key &BlobOnBlocks::key() const { const BlockId &BlobOnBlocks::blockId() const {
return _datatree->key(); return _datatree->blockId();
} }
unique_ref<DataTreeRef> BlobOnBlocks::releaseTree() { unique_ref<DataTreeRef> BlobOnBlocks::releaseTree() {

View File

@ -22,7 +22,7 @@ public:
BlobOnBlocks(cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> datatree); BlobOnBlocks(cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> datatree);
~BlobOnBlocks(); ~BlobOnBlocks();
const blockstore::Key &key() const override; const blockstore::BlockId &blockId() const override;
uint64_t size() const override; uint64_t size() const override;
void resize(uint64_t numBytes) override; void resize(uint64_t numBytes) override;

View File

@ -15,7 +15,7 @@ using cpputils::make_unique_ref;
using blockstore::BlockStore; using blockstore::BlockStore;
using blockstore::parallelaccess::ParallelAccessBlockStore; using blockstore::parallelaccess::ParallelAccessBlockStore;
using blockstore::Key; using blockstore::BlockId;
using cpputils::dynamic_pointer_move; using cpputils::dynamic_pointer_move;
using boost::optional; using boost::optional;
using boost::none; using boost::none;
@ -38,8 +38,8 @@ unique_ref<Blob> BlobStoreOnBlocks::create() {
return make_unique_ref<BlobOnBlocks>(_dataTreeStore->createNewTree()); return make_unique_ref<BlobOnBlocks>(_dataTreeStore->createNewTree());
} }
optional<unique_ref<Blob>> BlobStoreOnBlocks::load(const Key &key) { optional<unique_ref<Blob>> BlobStoreOnBlocks::load(const BlockId &blockId) {
auto tree = _dataTreeStore->load(key); auto tree = _dataTreeStore->load(blockId);
if (tree == none) { if (tree == none) {
return none; return none;
} }
@ -52,8 +52,8 @@ void BlobStoreOnBlocks::remove(unique_ref<Blob> blob) {
_dataTreeStore->remove((*_blob)->releaseTree()); _dataTreeStore->remove((*_blob)->releaseTree());
} }
void BlobStoreOnBlocks::remove(const Key &key) { void BlobStoreOnBlocks::remove(const BlockId &blockId) {
_dataTreeStore->remove(key); _dataTreeStore->remove(blockId);
} }
uint64_t BlobStoreOnBlocks::virtualBlocksizeBytes() const { uint64_t BlobStoreOnBlocks::virtualBlocksizeBytes() const {

View File

@ -20,10 +20,10 @@ public:
~BlobStoreOnBlocks(); ~BlobStoreOnBlocks();
cpputils::unique_ref<Blob> create() override; cpputils::unique_ref<Blob> create() override;
boost::optional<cpputils::unique_ref<Blob>> load(const blockstore::Key &key) override; boost::optional<cpputils::unique_ref<Blob>> load(const blockstore::BlockId &blockId) override;
void remove(cpputils::unique_ref<Blob> blob) override; void remove(cpputils::unique_ref<Blob> blob) override;
void remove(const blockstore::Key &key) override; void remove(const blockstore::BlockId &blockId) override;
//TODO Test blocksizeBytes/numBlocks/estimateSpaceForNumBlocksLeft //TODO Test blocksizeBytes/numBlocks/estimateSpaceForNumBlocksLeft
//virtual means "space we can use" as opposed to "space it takes on the disk" (i.e. virtual is without headers, checksums, ...) //virtual means "space we can use" as opposed to "space it takes on the disk" (i.e. virtual is without headers, checksums, ...)

View File

@ -7,7 +7,7 @@ using blockstore::BlockStore;
using cpputils::Data; using cpputils::Data;
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
using blockstore::Key; using blockstore::BlockId;
using std::vector; using std::vector;
namespace blobstore { namespace blobstore {
@ -25,25 +25,25 @@ DataInnerNode::DataInnerNode(DataNodeView view)
DataInnerNode::~DataInnerNode() { DataInnerNode::~DataInnerNode() {
} }
unique_ref<DataInnerNode> DataInnerNode::InitializeNewNode(unique_ref<Block> block, const DataNodeLayout &layout, uint8_t depth, const vector<Key> &children) { unique_ref<DataInnerNode> DataInnerNode::InitializeNewNode(unique_ref<Block> block, const DataNodeLayout &layout, uint8_t depth, const vector<BlockId> &children) {
ASSERT(children.size() >= 1, "An inner node must have at least one child"); ASSERT(children.size() >= 1, "An inner node must have at least one child");
Data data = _serializeChildren(children); Data data = _serializeChildren(children);
return make_unique_ref<DataInnerNode>(DataNodeView::initialize(std::move(block), layout, DataNode::FORMAT_VERSION_HEADER, depth, children.size(), std::move(data))); return make_unique_ref<DataInnerNode>(DataNodeView::initialize(std::move(block), layout, DataNode::FORMAT_VERSION_HEADER, depth, children.size(), std::move(data)));
} }
unique_ref<DataInnerNode> DataInnerNode::CreateNewNode(BlockStore *blockStore, const DataNodeLayout &layout, uint8_t depth, const vector<Key> &children) { unique_ref<DataInnerNode> DataInnerNode::CreateNewNode(BlockStore *blockStore, const DataNodeLayout &layout, uint8_t depth, const vector<BlockId> &children) {
ASSERT(children.size() >= 1, "An inner node must have at least one child"); ASSERT(children.size() >= 1, "An inner node must have at least one child");
Data data = _serializeChildren(children); Data data = _serializeChildren(children);
return make_unique_ref<DataInnerNode>(DataNodeView::create(blockStore, layout, DataNode::FORMAT_VERSION_HEADER, depth, children.size(), std::move(data))); return make_unique_ref<DataInnerNode>(DataNodeView::create(blockStore, layout, DataNode::FORMAT_VERSION_HEADER, depth, children.size(), std::move(data)));
} }
Data DataInnerNode::_serializeChildren(const vector<Key> &children) { Data DataInnerNode::_serializeChildren(const vector<BlockId> &children) {
Data data(sizeof(ChildEntry) * children.size()); Data data(sizeof(ChildEntry) * children.size());
uint32_t i = 0; uint32_t i = 0;
for (const Key &child : children) { for (const BlockId &child : children) {
reinterpret_cast<ChildEntry*>(data.data())[i++].setKey(child); reinterpret_cast<ChildEntry*>(data.data())[i++].setBlockId(child);
} }
return data; return data;
} }
@ -89,12 +89,12 @@ void DataInnerNode::addChild(const DataNode &child) {
ASSERT(numChildren() < maxStoreableChildren(), "Adding more children than we can store"); ASSERT(numChildren() < maxStoreableChildren(), "Adding more children than we can store");
ASSERT(child.depth() == depth()-1, "The child that should be added has wrong depth"); ASSERT(child.depth() == depth()-1, "The child that should be added has wrong depth");
node().setSize(node().Size()+1); node().setSize(node().Size()+1);
LastChild()->setKey(child.key()); LastChild()->setBlockId(child.blockId());
} }
void DataInnerNode::removeLastChild() { void DataInnerNode::removeLastChild() {
ASSERT(node().Size() > 1, "There is no child to remove"); ASSERT(node().Size() > 1, "There is no child to remove");
LastChild()->setKey(Key::Null()); LastChild()->setBlockId(BlockId::Null());
node().setSize(node().Size()-1); node().setSize(node().Size()-1);
} }

View File

@ -11,8 +11,8 @@ namespace datanodestore {
class DataInnerNode final: public DataNode { class DataInnerNode final: public DataNode {
public: public:
static cpputils::unique_ref<DataInnerNode> InitializeNewNode(cpputils::unique_ref<blockstore::Block> block, const DataNodeLayout &layout, uint8_t depth, const std::vector<blockstore::Key> &children); static cpputils::unique_ref<DataInnerNode> InitializeNewNode(cpputils::unique_ref<blockstore::Block> block, const DataNodeLayout &layout, uint8_t depth, const std::vector<blockstore::BlockId> &children);
static cpputils::unique_ref<DataInnerNode> CreateNewNode(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, uint8_t depth, const std::vector<blockstore::Key> &children); static cpputils::unique_ref<DataInnerNode> CreateNewNode(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, uint8_t depth, const std::vector<blockstore::BlockId> &children);
DataInnerNode(DataNodeView block); DataInnerNode(DataNodeView block);
~DataInnerNode(); ~DataInnerNode();
@ -26,7 +26,7 @@ public:
uint32_t numChildren() const; uint32_t numChildren() const;
void addChild(const DataNode &child_key); void addChild(const DataNode &child_blockId);
void removeLastChild(); void removeLastChild();
@ -40,7 +40,7 @@ private:
const ChildEntry *ChildrenBegin() const; const ChildEntry *ChildrenBegin() const;
const ChildEntry *ChildrenEnd() const; const ChildEntry *ChildrenEnd() const;
static cpputils::Data _serializeChildren(const std::vector<blockstore::Key> &children); static cpputils::Data _serializeChildren(const std::vector<blockstore::BlockId> &children);
DISALLOW_COPY_AND_ASSIGN(DataInnerNode); DISALLOW_COPY_AND_ASSIGN(DataInnerNode);
}; };

View File

@ -10,15 +10,15 @@ namespace datanodestore{
struct DataInnerNode_ChildEntry final { struct DataInnerNode_ChildEntry final {
public: public:
blockstore::Key key() const { blockstore::BlockId blockId() const {
return blockstore::Key::FromBinary(_keydata); return blockstore::BlockId::FromBinary(_blockIdData);
} }
private: private:
void setKey(const blockstore::Key &key) { void setBlockId(const blockstore::BlockId &blockId) {
key.ToBinary(_keydata); blockId.ToBinary(_blockIdData);
} }
friend class DataInnerNode; friend class DataInnerNode;
uint8_t _keydata[blockstore::Key::BINARY_LENGTH]; uint8_t _blockIdData[blockstore::BlockId::BINARY_LENGTH];
DISALLOW_COPY_AND_ASSIGN(DataInnerNode_ChildEntry); DISALLOW_COPY_AND_ASSIGN(DataInnerNode_ChildEntry);
}; };

View File

@ -4,7 +4,7 @@
using blockstore::Block; using blockstore::Block;
using cpputils::Data; using cpputils::Data;
using blockstore::Key; using blockstore::BlockId;
using blockstore::BlockStore; using blockstore::BlockStore;
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
@ -31,10 +31,10 @@ unique_ref<DataLeafNode> DataLeafNode::CreateNewNode(BlockStore *blockStore, con
return make_unique_ref<DataLeafNode>(DataNodeView::create(blockStore, layout, DataNode::FORMAT_VERSION_HEADER, 0, size, std::move(data))); return make_unique_ref<DataLeafNode>(DataNodeView::create(blockStore, layout, DataNode::FORMAT_VERSION_HEADER, 0, size, std::move(data)));
} }
unique_ref<DataLeafNode> DataLeafNode::OverwriteNode(BlockStore *blockStore, const DataNodeLayout &layout, const Key &key, Data data) { unique_ref<DataLeafNode> DataLeafNode::OverwriteNode(BlockStore *blockStore, const DataNodeLayout &layout, const BlockId &blockId, Data data) {
ASSERT(data.size() == layout.maxBytesPerLeaf(), "Data passed in is too large for one leaf."); ASSERT(data.size() == layout.maxBytesPerLeaf(), "Data passed in is too large for one leaf.");
uint32_t size = data.size(); uint32_t size = data.size();
return make_unique_ref<DataLeafNode>(DataNodeView::overwrite(blockStore, layout, DataNode::FORMAT_VERSION_HEADER, 0, size, key, std::move(data))); return make_unique_ref<DataLeafNode>(DataNodeView::overwrite(blockStore, layout, DataNode::FORMAT_VERSION_HEADER, 0, size, blockId, std::move(data)));
} }
void DataLeafNode::read(void *target, uint64_t offset, uint64_t size) const { void DataLeafNode::read(void *target, uint64_t offset, uint64_t size) const {

View File

@ -12,7 +12,7 @@ class DataInnerNode;
class DataLeafNode final: public DataNode { class DataLeafNode final: public DataNode {
public: public:
static cpputils::unique_ref<DataLeafNode> CreateNewNode(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, cpputils::Data data); static cpputils::unique_ref<DataLeafNode> CreateNewNode(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, cpputils::Data data);
static cpputils::unique_ref<DataLeafNode> OverwriteNode(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, const blockstore::Key &key, cpputils::Data data); static cpputils::unique_ref<DataLeafNode> OverwriteNode(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, const blockstore::BlockId &blockId, cpputils::Data data);
DataLeafNode(DataNodeView block); DataLeafNode(DataNodeView block);
~DataLeafNode(); ~DataLeafNode();

View File

@ -5,7 +5,7 @@
#include <blockstore/utils/BlockStoreUtils.h> #include <blockstore/utils/BlockStoreUtils.h>
using blockstore::Block; using blockstore::Block;
using blockstore::Key; using blockstore::BlockId;
using std::runtime_error; using std::runtime_error;
using cpputils::unique_ref; using cpputils::unique_ref;
@ -31,8 +31,8 @@ const DataNodeView &DataNode::node() const {
return _node; return _node;
} }
const Key &DataNode::key() const { const BlockId &DataNode::blockId() const {
return _node.key(); return _node.blockId();
} }
uint8_t DataNode::depth() const { uint8_t DataNode::depth() const {
@ -43,7 +43,7 @@ unique_ref<DataInnerNode> DataNode::convertToNewInnerNode(unique_ref<DataNode> n
auto block = node->_node.releaseBlock(); auto block = node->_node.releaseBlock();
blockstore::utils::fillWithZeroes(block.get()); blockstore::utils::fillWithZeroes(block.get());
return DataInnerNode::InitializeNewNode(std::move(block), layout, first_child.depth()+1, {first_child.key()}); return DataInnerNode::InitializeNewNode(std::move(block), layout, first_child.depth()+1, {first_child.blockId()});
} }
void DataNode::flush() const { void DataNode::flush() const {

View File

@ -15,7 +15,7 @@ class DataNode {
public: public:
virtual ~DataNode(); virtual ~DataNode();
const blockstore::Key &key() const; const blockstore::BlockId &blockId() const;
uint8_t depth() const; uint8_t depth() const;

View File

@ -8,7 +8,7 @@
using blockstore::BlockStore; using blockstore::BlockStore;
using blockstore::Block; using blockstore::Block;
using blockstore::Key; using blockstore::BlockId;
using cpputils::Data; using cpputils::Data;
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
@ -41,7 +41,7 @@ unique_ref<DataNode> DataNodeStore::load(unique_ref<Block> block) {
} }
} }
unique_ref<DataInnerNode> DataNodeStore::createNewInnerNode(uint8_t depth, const vector<Key> &children) { unique_ref<DataInnerNode> DataNodeStore::createNewInnerNode(uint8_t depth, const vector<BlockId> &children) {
ASSERT(children.size() >= 1, "Inner node must have at least one child"); ASSERT(children.size() >= 1, "Inner node must have at least one child");
return DataInnerNode::CreateNewNode(_blockstore.get(), _layout, depth, children); return DataInnerNode::CreateNewNode(_blockstore.get(), _layout, depth, children);
} }
@ -50,12 +50,12 @@ unique_ref<DataLeafNode> DataNodeStore::createNewLeafNode(Data data) {
return DataLeafNode::CreateNewNode(_blockstore.get(), _layout, std::move(data)); return DataLeafNode::CreateNewNode(_blockstore.get(), _layout, std::move(data));
} }
unique_ref<DataLeafNode> DataNodeStore::overwriteLeaf(const Key &key, Data data) { unique_ref<DataLeafNode> DataNodeStore::overwriteLeaf(const BlockId &blockId, Data data) {
return DataLeafNode::OverwriteNode(_blockstore.get(), _layout, key, std::move(data)); return DataLeafNode::OverwriteNode(_blockstore.get(), _layout, blockId, std::move(data));
} }
optional<unique_ref<DataNode>> DataNodeStore::load(const Key &key) { optional<unique_ref<DataNode>> DataNodeStore::load(const BlockId &blockId) {
auto block = _blockstore->load(key); auto block = _blockstore->load(blockId);
if (block == none) { if (block == none) {
return none; return none;
} else { } else {
@ -80,13 +80,13 @@ unique_ref<DataNode> DataNodeStore::overwriteNodeWith(unique_ref<DataNode> targe
} }
void DataNodeStore::remove(unique_ref<DataNode> node) { void DataNodeStore::remove(unique_ref<DataNode> node) {
Key key = node->key(); BlockId blockId = node->blockId();
cpputils::destruct(std::move(node)); cpputils::destruct(std::move(node));
remove(key); remove(blockId);
} }
void DataNodeStore::remove(const Key &key) { void DataNodeStore::remove(const BlockId &blockId) {
_blockstore->remove(key); _blockstore->remove(blockId);
} }
void DataNodeStore::removeSubtree(unique_ref<DataNode> node) { void DataNodeStore::removeSubtree(unique_ref<DataNode> node) {
@ -99,23 +99,23 @@ void DataNodeStore::removeSubtree(unique_ref<DataNode> node) {
auto inner = dynamic_pointer_move<DataInnerNode>(node); auto inner = dynamic_pointer_move<DataInnerNode>(node);
ASSERT(inner != none, "Is neither a leaf nor an inner node"); ASSERT(inner != none, "Is neither a leaf nor an inner node");
for (uint32_t i = 0; i < (*inner)->numChildren(); ++i) { for (uint32_t i = 0; i < (*inner)->numChildren(); ++i) {
removeSubtree((*inner)->depth()-1, (*inner)->getChild(i)->key()); removeSubtree((*inner)->depth()-1, (*inner)->getChild(i)->blockId());
} }
remove(std::move(*inner)); remove(std::move(*inner));
} }
void DataNodeStore::removeSubtree(uint8_t depth, const Key &key) { void DataNodeStore::removeSubtree(uint8_t depth, const BlockId &blockId) {
if (depth == 0) { if (depth == 0) {
remove(key); remove(blockId);
} else { } else {
auto node = load(key); auto node = load(blockId);
ASSERT(node != none, "Node for removeSubtree not found"); ASSERT(node != none, "Node for removeSubtree not found");
auto inner = dynamic_pointer_move<DataInnerNode>(*node); auto inner = dynamic_pointer_move<DataInnerNode>(*node);
ASSERT(inner != none, "Is not an inner node, but depth was not zero"); ASSERT(inner != none, "Is not an inner node, but depth was not zero");
ASSERT((*inner)->depth() == depth, "Wrong depth given"); ASSERT((*inner)->depth() == depth, "Wrong depth given");
for (uint32_t i = 0; i < (*inner)->numChildren(); ++i) { for (uint32_t i = 0; i < (*inner)->numChildren(); ++i) {
removeSubtree(depth-1, (*inner)->getChild(i)->key()); removeSubtree(depth-1, (*inner)->getChild(i)->blockId());
} }
remove(std::move(*inner)); remove(std::move(*inner));
} }

View File

@ -5,7 +5,7 @@
#include <memory> #include <memory>
#include <cpp-utils/macros.h> #include <cpp-utils/macros.h>
#include "DataNodeView.h" #include "DataNodeView.h"
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
namespace blockstore{ namespace blockstore{
class Block; class Block;
@ -28,21 +28,21 @@ public:
DataNodeLayout layout() const; DataNodeLayout layout() const;
boost::optional<cpputils::unique_ref<DataNode>> load(const blockstore::Key &key); boost::optional<cpputils::unique_ref<DataNode>> load(const blockstore::BlockId &blockId);
static cpputils::unique_ref<DataNode> load(cpputils::unique_ref<blockstore::Block> block); static cpputils::unique_ref<DataNode> load(cpputils::unique_ref<blockstore::Block> block);
cpputils::unique_ref<DataLeafNode> createNewLeafNode(cpputils::Data data); cpputils::unique_ref<DataLeafNode> createNewLeafNode(cpputils::Data data);
cpputils::unique_ref<DataInnerNode> createNewInnerNode(uint8_t depth, const std::vector<blockstore::Key> &children); cpputils::unique_ref<DataInnerNode> createNewInnerNode(uint8_t depth, const std::vector<blockstore::BlockId> &children);
cpputils::unique_ref<DataNode> createNewNodeAsCopyFrom(const DataNode &source); cpputils::unique_ref<DataNode> createNewNodeAsCopyFrom(const DataNode &source);
cpputils::unique_ref<DataNode> overwriteNodeWith(cpputils::unique_ref<DataNode> target, const DataNode &source); cpputils::unique_ref<DataNode> overwriteNodeWith(cpputils::unique_ref<DataNode> target, const DataNode &source);
cpputils::unique_ref<DataLeafNode> overwriteLeaf(const blockstore::Key &key, cpputils::Data data); cpputils::unique_ref<DataLeafNode> overwriteLeaf(const blockstore::BlockId &blockId, cpputils::Data data);
void remove(cpputils::unique_ref<DataNode> node); void remove(cpputils::unique_ref<DataNode> node);
void remove(const blockstore::Key &key); void remove(const blockstore::BlockId &blockId);
void removeSubtree(uint8_t depth, const blockstore::Key &key); void removeSubtree(uint8_t depth, const blockstore::BlockId &blockId);
void removeSubtree(cpputils::unique_ref<DataNode> node); void removeSubtree(cpputils::unique_ref<DataNode> node);
//TODO Test blocksizeBytes/numBlocks/estimateSpaceForNumBlocksLeft //TODO Test blocksizeBytes/numBlocks/estimateSpaceForNumBlocksLeft

View File

@ -81,10 +81,10 @@ public:
return DataNodeView(std::move(block)); return DataNodeView(std::move(block));
} }
static DataNodeView overwrite(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, uint16_t formatVersion, uint8_t depth, uint32_t size, const blockstore::Key &key, cpputils::Data data) { static DataNodeView overwrite(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, uint16_t formatVersion, uint8_t depth, uint32_t size, const blockstore::BlockId &blockId, cpputils::Data data) {
ASSERT(data.size() <= layout.datasizeBytes(), "Data is too large for node"); ASSERT(data.size() <= layout.datasizeBytes(), "Data is too large for node");
cpputils::Data serialized = _serialize(layout, formatVersion, depth, size, std::move(data)); cpputils::Data serialized = _serialize(layout, formatVersion, depth, size, std::move(data));
auto block = blockStore->overwrite(key, std::move(serialized)); auto block = blockStore->overwrite(blockId, std::move(serialized));
return DataNodeView(std::move(block)); return DataNodeView(std::move(block));
} }
@ -145,8 +145,8 @@ public:
return *_block; return *_block;
} }
const blockstore::Key &key() const { const blockstore::BlockId &blockId() const {
return _block->key(); return _block->blockId();
} }
void flush() const { void flush() const {

View File

@ -13,7 +13,7 @@
#include <cpp-utils/assert/assert.h> #include <cpp-utils/assert/assert.h>
#include "impl/LeafTraverser.h" #include "impl/LeafTraverser.h"
using blockstore::Key; using blockstore::BlockId;
using blobstore::onblocks::datanodestore::DataNodeStore; using blobstore::onblocks::datanodestore::DataNodeStore;
using blobstore::onblocks::datanodestore::DataNode; using blobstore::onblocks::datanodestore::DataNode;
using blobstore::onblocks::datanodestore::DataInnerNode; using blobstore::onblocks::datanodestore::DataInnerNode;
@ -40,14 +40,14 @@ namespace onblocks {
namespace datatreestore { namespace datatreestore {
DataTree::DataTree(DataNodeStore *nodeStore, unique_ref<DataNode> rootNode) DataTree::DataTree(DataNodeStore *nodeStore, unique_ref<DataNode> rootNode)
: _mutex(), _nodeStore(nodeStore), _rootNode(std::move(rootNode)), _key(_rootNode->key()), _numLeavesCache(none) { : _mutex(), _nodeStore(nodeStore), _rootNode(std::move(rootNode)), _blockId(_rootNode->blockId()), _numLeavesCache(none) {
} }
DataTree::~DataTree() { DataTree::~DataTree() {
} }
const Key &DataTree::key() const { const BlockId &DataTree::blockId() const {
return _key; return _blockId;
} }
void DataTree::flush() const { void DataTree::flush() const {
@ -89,7 +89,7 @@ uint32_t DataTree::_computeNumLeaves(const DataNode &node) const {
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(node); const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(node);
uint64_t numLeavesInLeftChildren = (uint64_t)(inner.numChildren()-1) * leavesPerFullChild(inner); uint64_t numLeavesInLeftChildren = (uint64_t)(inner.numChildren()-1) * leavesPerFullChild(inner);
auto lastChild = _nodeStore->load(inner.LastChild()->key()); auto lastChild = _nodeStore->load(inner.LastChild()->blockId());
ASSERT(lastChild != none, "Couldn't load last child"); ASSERT(lastChild != none, "Couldn't load last child");
uint64_t numLeavesInRightChild = _computeNumLeaves(**lastChild); uint64_t numLeavesInRightChild = _computeNumLeaves(**lastChild);
@ -138,7 +138,7 @@ uint64_t DataTree::_numStoredBytes(const DataNode &root) const {
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(root); const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(root);
uint64_t numBytesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner) * _nodeStore->layout().maxBytesPerLeaf(); uint64_t numBytesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner) * _nodeStore->layout().maxBytesPerLeaf();
auto lastChild = _nodeStore->load(inner.LastChild()->key()); auto lastChild = _nodeStore->load(inner.LastChild()->blockId());
ASSERT(lastChild != none, "Couldn't load last child"); ASSERT(lastChild != none, "Couldn't load last child");
uint64_t numBytesInRightChild = _numStoredBytes(**lastChild); uint64_t numBytesInRightChild = _numStoredBytes(**lastChild);
@ -172,7 +172,7 @@ void DataTree::resizeNumBytes(uint64_t newNumBytes) {
ASSERT(neededChildrenForRightBorderNode <= node->numChildren(), "Node has too few children"); ASSERT(neededChildrenForRightBorderNode <= node->numChildren(), "Node has too few children");
// All children to the right of the new right-border-node are removed including their subtree. // All children to the right of the new right-border-node are removed including their subtree.
while(node->numChildren() > neededChildrenForRightBorderNode) { while(node->numChildren() > neededChildrenForRightBorderNode) {
_nodeStore->removeSubtree(node->depth()-1, node->LastChild()->key()); _nodeStore->removeSubtree(node->depth()-1, node->LastChild()->blockId());
node->removeLastChild(); node->removeLastChild();
} }
}; };

View File

@ -8,7 +8,7 @@
#include "../datanodestore/DataNodeView.h" #include "../datanodestore/DataNodeView.h"
//TODO Replace with C++14 once std::shared_mutex is supported //TODO Replace with C++14 once std::shared_mutex is supported
#include <boost/thread/shared_mutex.hpp> #include <boost/thread/shared_mutex.hpp>
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include "LeafHandle.h" #include "LeafHandle.h"
namespace blobstore { namespace blobstore {
@ -27,7 +27,7 @@ public:
DataTree(datanodestore::DataNodeStore *nodeStore, cpputils::unique_ref<datanodestore::DataNode> rootNode); DataTree(datanodestore::DataNodeStore *nodeStore, cpputils::unique_ref<datanodestore::DataNode> rootNode);
~DataTree(); ~DataTree();
const blockstore::Key &key() const; const blockstore::BlockId &blockId() const;
//Returning uint64_t, because calculations handling this probably need to be done in 64bit to support >4GB blobs. //Returning uint64_t, because calculations handling this probably need to be done in 64bit to support >4GB blobs.
uint64_t maxBytesPerLeaf() const; uint64_t maxBytesPerLeaf() const;
@ -48,7 +48,7 @@ private:
mutable boost::shared_mutex _mutex; mutable boost::shared_mutex _mutex;
datanodestore::DataNodeStore *_nodeStore; datanodestore::DataNodeStore *_nodeStore;
cpputils::unique_ref<datanodestore::DataNode> _rootNode; cpputils::unique_ref<datanodestore::DataNode> _rootNode;
blockstore::Key _key; // Key is stored in a member variable, since _rootNode is nullptr while traversing, but we still want to be able to return the key. blockstore::BlockId _blockId; // BlockId is stored in a member variable, since _rootNode is nullptr while traversing, but we still want to be able to return the blockId.
mutable boost::optional<uint32_t> _numLeavesCache; mutable boost::optional<uint32_t> _numLeavesCache;
cpputils::unique_ref<datanodestore::DataNode> releaseRootNode(); cpputils::unique_ref<datanodestore::DataNode> releaseRootNode();

View File

@ -22,8 +22,8 @@ DataTreeStore::DataTreeStore(unique_ref<DataNodeStore> nodeStore)
DataTreeStore::~DataTreeStore() { DataTreeStore::~DataTreeStore() {
} }
optional<unique_ref<DataTree>> DataTreeStore::load(const blockstore::Key &key) { optional<unique_ref<DataTree>> DataTreeStore::load(const blockstore::BlockId &blockId) {
auto node = _nodeStore->load(key); auto node = _nodeStore->load(blockId);
if (node == none) { if (node == none) {
return none; return none;
} }
@ -39,8 +39,8 @@ void DataTreeStore::remove(unique_ref<DataTree> tree) {
_nodeStore->removeSubtree(tree->releaseRootNode()); _nodeStore->removeSubtree(tree->releaseRootNode());
} }
void DataTreeStore::remove(const blockstore::Key &key) { void DataTreeStore::remove(const blockstore::BlockId &blockId) {
auto tree = load(key); auto tree = load(blockId);
ASSERT(tree != none, "Tree to remove not found"); ASSERT(tree != none, "Tree to remove not found");
remove(std::move(*tree)); remove(std::move(*tree));
} }

View File

@ -5,7 +5,7 @@
#include <memory> #include <memory>
#include <cpp-utils/macros.h> #include <cpp-utils/macros.h>
#include <cpp-utils/pointer/unique_ref.h> #include <cpp-utils/pointer/unique_ref.h>
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include "../datanodestore/DataNodeStore.h" #include "../datanodestore/DataNodeStore.h"
@ -19,12 +19,12 @@ public:
DataTreeStore(cpputils::unique_ref<datanodestore::DataNodeStore> nodeStore); DataTreeStore(cpputils::unique_ref<datanodestore::DataNodeStore> nodeStore);
~DataTreeStore(); ~DataTreeStore();
boost::optional<cpputils::unique_ref<DataTree>> load(const blockstore::Key &key); boost::optional<cpputils::unique_ref<DataTree>> load(const blockstore::BlockId &blockId);
cpputils::unique_ref<DataTree> createNewTree(); cpputils::unique_ref<DataTree> createNewTree();
void remove(cpputils::unique_ref<DataTree> tree); void remove(cpputils::unique_ref<DataTree> tree);
void remove(const blockstore::Key &key); void remove(const blockstore::BlockId &blockId);
//TODO Test blocksizeBytes/numBlocks/estimateSpaceForNumBlocksLeft //TODO Test blocksizeBytes/numBlocks/estimateSpaceForNumBlocksLeft
uint64_t virtualBlocksizeBytes() const; uint64_t virtualBlocksizeBytes() const;

View File

@ -8,24 +8,24 @@ using boost::none;
using cpputils::dynamic_pointer_move; using cpputils::dynamic_pointer_move;
using blobstore::onblocks::datanodestore::DataLeafNode; using blobstore::onblocks::datanodestore::DataLeafNode;
using blobstore::onblocks::datanodestore::DataNodeStore; using blobstore::onblocks::datanodestore::DataNodeStore;
using blockstore::Key; using blockstore::BlockId;
namespace blobstore { namespace blobstore {
namespace onblocks { namespace onblocks {
namespace datatreestore { namespace datatreestore {
LeafHandle::LeafHandle(DataNodeStore *nodeStore, const Key &key) LeafHandle::LeafHandle(DataNodeStore *nodeStore, const BlockId &blockId)
: _nodeStore(nodeStore), _key(key), _leaf(cpputils::null<DataLeafNode>()) { : _nodeStore(nodeStore), _blockId(blockId), _leaf(cpputils::null<DataLeafNode>()) {
} }
LeafHandle::LeafHandle(DataNodeStore *nodeStore, DataLeafNode *node) LeafHandle::LeafHandle(DataNodeStore *nodeStore, DataLeafNode *node)
: _nodeStore(nodeStore), _key(node->key()), : _nodeStore(nodeStore), _blockId(node->blockId()),
_leaf(WithoutOwnership<DataLeafNode>(node)) { _leaf(WithoutOwnership<DataLeafNode>(node)) {
} }
DataLeafNode *LeafHandle::node() { DataLeafNode *LeafHandle::node() {
if (_leaf.get() == nullptr) { if (_leaf.get() == nullptr) {
auto loaded = _nodeStore->load(_key); auto loaded = _nodeStore->load(_blockId);
ASSERT(loaded != none, "Leaf not found"); ASSERT(loaded != none, "Leaf not found");
auto leaf = dynamic_pointer_move<DataLeafNode>(*loaded); auto leaf = dynamic_pointer_move<DataLeafNode>(*loaded);
ASSERT(leaf != none, "Loaded leaf is not leaf node"); ASSERT(leaf != none, "Loaded leaf is not leaf node");

View File

@ -4,7 +4,7 @@
#include <cpp-utils/macros.h> #include <cpp-utils/macros.h>
#include <cpp-utils/pointer/optional_ownership_ptr.h> #include <cpp-utils/pointer/optional_ownership_ptr.h>
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
namespace blobstore { namespace blobstore {
namespace onblocks { namespace onblocks {
@ -16,12 +16,12 @@ namespace blobstore {
class LeafHandle final { class LeafHandle final {
public: public:
LeafHandle(datanodestore::DataNodeStore *nodeStore, const blockstore::Key &key); LeafHandle(datanodestore::DataNodeStore *nodeStore, const blockstore::BlockId &blockId);
LeafHandle(datanodestore::DataNodeStore *nodeStore, datanodestore::DataLeafNode *node); LeafHandle(datanodestore::DataNodeStore *nodeStore, datanodestore::DataLeafNode *node);
LeafHandle(LeafHandle &&rhs) = default; LeafHandle(LeafHandle &&rhs) = default;
const blockstore::Key &key() { const blockstore::BlockId &blockId() {
return _key; return _blockId;
} }
datanodestore::DataLeafNode *node(); datanodestore::DataLeafNode *node();
@ -32,7 +32,7 @@ namespace blobstore {
private: private:
datanodestore::DataNodeStore *_nodeStore; datanodestore::DataNodeStore *_nodeStore;
blockstore::Key _key; blockstore::BlockId _blockId;
cpputils::optional_ownership_ptr<datanodestore::DataLeafNode> _leaf; cpputils::optional_ownership_ptr<datanodestore::DataLeafNode> _leaf;
DISALLOW_COPY_AND_ASSIGN(LeafHandle); DISALLOW_COPY_AND_ASSIGN(LeafHandle);

View File

@ -78,11 +78,11 @@ namespace blobstore {
return DataNode::convertToNewInnerNode(std::move(root), _nodeStore->layout(), *copyOfOldRoot); return DataNode::convertToNewInnerNode(std::move(root), _nodeStore->layout(), *copyOfOldRoot);
} }
void LeafTraverser::_traverseExistingSubtree(const blockstore::Key &key, uint8_t depth, uint32_t beginIndex, uint32_t endIndex, uint32_t leafOffset, bool isLeftBorderOfTraversal, bool isRightBorderNode, bool growLastLeaf, function<void (uint32_t index, bool isRightBorderLeaf, LeafHandle leaf)> onExistingLeaf, function<Data (uint32_t index)> onCreateLeaf, function<void (DataInnerNode *node)> onBacktrackFromSubtree) { void LeafTraverser::_traverseExistingSubtree(const blockstore::BlockId &blockId, uint8_t depth, uint32_t beginIndex, uint32_t endIndex, uint32_t leafOffset, bool isLeftBorderOfTraversal, bool isRightBorderNode, bool growLastLeaf, function<void (uint32_t index, bool isRightBorderLeaf, LeafHandle leaf)> onExistingLeaf, function<Data (uint32_t index)> onCreateLeaf, function<void (DataInnerNode *node)> onBacktrackFromSubtree) {
if (depth == 0) { if (depth == 0) {
ASSERT(beginIndex <= 1 && endIndex <= 1, ASSERT(beginIndex <= 1 && endIndex <= 1,
"If root node is a leaf, the (sub)tree has only one leaf - access indices must be 0 or 1."); "If root node is a leaf, the (sub)tree has only one leaf - access indices must be 0 or 1.");
LeafHandle leafHandle(_nodeStore, key); LeafHandle leafHandle(_nodeStore, blockId);
if (growLastLeaf) { if (growLastLeaf) {
if (leafHandle.node()->numBytes() != _nodeStore->layout().maxBytesPerLeaf()) { if (leafHandle.node()->numBytes() != _nodeStore->layout().maxBytesPerLeaf()) {
leafHandle.node()->resize(_nodeStore->layout().maxBytesPerLeaf()); leafHandle.node()->resize(_nodeStore->layout().maxBytesPerLeaf());
@ -92,9 +92,9 @@ namespace blobstore {
onExistingLeaf(leafOffset, isRightBorderNode, std::move(leafHandle)); onExistingLeaf(leafOffset, isRightBorderNode, std::move(leafHandle));
} }
} else { } else {
auto node = _nodeStore->load(key); auto node = _nodeStore->load(blockId);
if (node == none) { if (node == none) {
throw std::runtime_error("Couldn't find child node " + key.ToString()); throw std::runtime_error("Couldn't find child node " + blockId.ToString());
} }
auto inner = dynamic_pointer_move<DataInnerNode>(*node); auto inner = dynamic_pointer_move<DataInnerNode>(*node);
@ -122,9 +122,9 @@ namespace blobstore {
// we still have to descend to the last old child to fill it with leaves and grow the last old leaf. // we still have to descend to the last old child to fill it with leaves and grow the last old leaf.
if (isLeftBorderOfTraversal && beginChild >= numChildren) { if (isLeftBorderOfTraversal && beginChild >= numChildren) {
ASSERT(numChildren > 0, "Node doesn't have children."); ASSERT(numChildren > 0, "Node doesn't have children.");
auto childKey = root->getChild(numChildren-1)->key(); auto childBlockId = root->getChild(numChildren-1)->blockId();
uint32_t childOffset = (numChildren-1) * leavesPerChild; uint32_t childOffset = (numChildren-1) * leavesPerChild;
_traverseExistingSubtree(childKey, root->depth()-1, leavesPerChild, leavesPerChild, childOffset, true, false, true, _traverseExistingSubtree(childBlockId, root->depth()-1, leavesPerChild, leavesPerChild, childOffset, true, false, true,
[] (uint32_t /*index*/, bool /*isRightBorderNode*/, LeafHandle /*leaf*/) {ASSERT(false, "We don't actually traverse any leaves.");}, [] (uint32_t /*index*/, bool /*isRightBorderNode*/, LeafHandle /*leaf*/) {ASSERT(false, "We don't actually traverse any leaves.");},
[] (uint32_t /*index*/) -> Data {ASSERT(false, "We don't actually traverse any leaves.");}, [] (uint32_t /*index*/) -> Data {ASSERT(false, "We don't actually traverse any leaves.");},
[] (DataInnerNode* /*node*/) {ASSERT(false, "We don't actually traverse any leaves.");}); [] (DataInnerNode* /*node*/) {ASSERT(false, "We don't actually traverse any leaves.");});
@ -132,7 +132,7 @@ namespace blobstore {
// Traverse existing children // Traverse existing children
for (uint32_t childIndex = beginChild; childIndex < std::min(endChild, numChildren); ++childIndex) { for (uint32_t childIndex = beginChild; childIndex < std::min(endChild, numChildren); ++childIndex) {
auto childKey = root->getChild(childIndex)->key(); auto childBlockId = root->getChild(childIndex)->blockId();
uint32_t childOffset = childIndex * leavesPerChild; uint32_t childOffset = childIndex * leavesPerChild;
uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset); uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset);
uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset); uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
@ -140,7 +140,7 @@ namespace blobstore {
bool isLastExistingChild = (childIndex == numChildren - 1); bool isLastExistingChild = (childIndex == numChildren - 1);
bool isLastChild = isLastExistingChild && (numChildren == endChild); bool isLastChild = isLastExistingChild && (numChildren == endChild);
ASSERT(localEndIndex <= leavesPerChild, "We don't want the child to add a tree level because it doesn't have enough space for the traversal."); ASSERT(localEndIndex <= leavesPerChild, "We don't want the child to add a tree level because it doesn't have enough space for the traversal.");
_traverseExistingSubtree(childKey, root->depth()-1, localBeginIndex, localEndIndex, leafOffset + childOffset, isLeftBorderOfTraversal && isFirstChild, _traverseExistingSubtree(childBlockId, root->depth()-1, localBeginIndex, localEndIndex, leafOffset + childOffset, isLeftBorderOfTraversal && isFirstChild,
isRightBorderNode && isLastChild, shouldGrowLastExistingLeaf && isLastExistingChild, onExistingLeaf, onCreateLeaf, onBacktrackFromSubtree); isRightBorderNode && isLastChild, shouldGrowLastExistingLeaf && isLastExistingChild, onExistingLeaf, onCreateLeaf, onBacktrackFromSubtree);
} }
@ -175,7 +175,7 @@ namespace blobstore {
uint32_t beginChild = beginIndex/leavesPerChild; uint32_t beginChild = beginIndex/leavesPerChild;
uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild); uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild);
vector<blockstore::Key> children; vector<blockstore::BlockId> children;
children.reserve(endChild); children.reserve(endChild);
// TODO Remove redundancy of following two for loops by using min/max for calculating the parameters of the recursive call. // TODO Remove redundancy of following two for loops by using min/max for calculating the parameters of the recursive call.
// Create gap children (i.e. children before the traversal but after the current size) // Create gap children (i.e. children before the traversal but after the current size)
@ -185,7 +185,7 @@ namespace blobstore {
[] (uint32_t /*index*/)->Data {ASSERT(false, "We're only creating gap leaves here, not traversing any.");}, [] (uint32_t /*index*/)->Data {ASSERT(false, "We're only creating gap leaves here, not traversing any.");},
[] (DataInnerNode* /*node*/) {}); [] (DataInnerNode* /*node*/) {});
ASSERT(child->depth() == depth-1, "Created child node has wrong depth"); ASSERT(child->depth() == depth-1, "Created child node has wrong depth");
children.push_back(child->key()); children.push_back(child->blockId());
} }
// Create new children that are traversed // Create new children that are traversed
for(uint32_t childIndex = beginChild; childIndex < endChild; ++childIndex) { for(uint32_t childIndex = beginChild; childIndex < endChild; ++childIndex) {
@ -194,7 +194,7 @@ namespace blobstore {
uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset); uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
auto child = _createNewSubtree(localBeginIndex, localEndIndex, leafOffset + childOffset, depth - 1, onCreateLeaf, onBacktrackFromSubtree); auto child = _createNewSubtree(localBeginIndex, localEndIndex, leafOffset + childOffset, depth - 1, onCreateLeaf, onBacktrackFromSubtree);
ASSERT(child->depth() == depth-1, "Created child node has wrong depth"); ASSERT(child->depth() == depth-1, "Created child node has wrong depth");
children.push_back(child->key()); children.push_back(child->blockId());
} }
ASSERT(children.size() > 0, "No children created"); ASSERT(children.size() > 0, "No children created");
@ -221,7 +221,7 @@ namespace blobstore {
unique_ref<DataNode> LeafTraverser::_whileRootHasOnlyOneChildReplaceRootWithItsChild(unique_ref<DataNode> root) { unique_ref<DataNode> LeafTraverser::_whileRootHasOnlyOneChildReplaceRootWithItsChild(unique_ref<DataNode> root) {
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get()); DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
if (inner != nullptr && inner->numChildren() == 1) { if (inner != nullptr && inner->numChildren() == 1) {
auto newRoot = _whileRootHasOnlyOneChildRemoveRootReturnChild(inner->getChild(0)->key()); auto newRoot = _whileRootHasOnlyOneChildRemoveRootReturnChild(inner->getChild(0)->blockId());
auto result = _nodeStore->overwriteNodeWith(std::move(root), *newRoot); auto result = _nodeStore->overwriteNodeWith(std::move(root), *newRoot);
_nodeStore->remove(std::move(newRoot)); _nodeStore->remove(std::move(newRoot));
return result; return result;
@ -230,14 +230,14 @@ namespace blobstore {
} }
} }
unique_ref<DataNode> LeafTraverser::_whileRootHasOnlyOneChildRemoveRootReturnChild(const blockstore::Key &key) { unique_ref<DataNode> LeafTraverser::_whileRootHasOnlyOneChildRemoveRootReturnChild(const blockstore::BlockId &blockId) {
auto current = _nodeStore->load(key); auto current = _nodeStore->load(blockId);
ASSERT(current != none, "Node not found"); ASSERT(current != none, "Node not found");
auto inner = dynamic_pointer_move<DataInnerNode>(*current); auto inner = dynamic_pointer_move<DataInnerNode>(*current);
if (inner == none) { if (inner == none) {
return std::move(*current); return std::move(*current);
} else if ((*inner)->numChildren() == 1) { } else if ((*inner)->numChildren() == 1) {
auto result = _whileRootHasOnlyOneChildRemoveRootReturnChild((*inner)->getChild(0)->key()); auto result = _whileRootHasOnlyOneChildRemoveRootReturnChild((*inner)->getChild(0)->blockId());
_nodeStore->remove(std::move(*inner)); _nodeStore->remove(std::move(*inner));
return result; return result;
} else { } else {

View File

@ -5,7 +5,7 @@
#include <cpp-utils/macros.h> #include <cpp-utils/macros.h>
#include <cpp-utils/pointer/unique_ref.h> #include <cpp-utils/pointer/unique_ref.h>
#include <cpp-utils/data/Data.h> #include <cpp-utils/data/Data.h>
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include "blobstore/implementations/onblocks/datatreestore/LeafHandle.h" #include "blobstore/implementations/onblocks/datatreestore/LeafHandle.h"
namespace blobstore { namespace blobstore {
@ -45,7 +45,7 @@ namespace blobstore {
std::function<void (uint32_t index, bool isRightBorderLeaf, LeafHandle leaf)> onExistingLeaf, std::function<void (uint32_t index, bool isRightBorderLeaf, LeafHandle leaf)> onExistingLeaf,
std::function<cpputils::Data (uint32_t index)> onCreateLeaf, std::function<cpputils::Data (uint32_t index)> onCreateLeaf,
std::function<void (datanodestore::DataInnerNode *node)> onBacktrackFromSubtree); std::function<void (datanodestore::DataInnerNode *node)> onBacktrackFromSubtree);
void _traverseExistingSubtree(const blockstore::Key &key, uint8_t depth, uint32_t beginIndex, uint32_t endIndex, uint32_t leafOffset, bool isLeftBorderOfTraversal, bool isRightBorderNode, bool growLastLeaf, void _traverseExistingSubtree(const blockstore::BlockId &blockId, uint8_t depth, uint32_t beginIndex, uint32_t endIndex, uint32_t leafOffset, bool isLeftBorderOfTraversal, bool isRightBorderNode, bool growLastLeaf,
std::function<void (uint32_t index, bool isRightBorderLeaf, LeafHandle leaf)> onExistingLeaf, std::function<void (uint32_t index, bool isRightBorderLeaf, LeafHandle leaf)> onExistingLeaf,
std::function<cpputils::Data (uint32_t index)> onCreateLeaf, std::function<cpputils::Data (uint32_t index)> onCreateLeaf,
std::function<void (datanodestore::DataInnerNode *node)> onBacktrackFromSubtree); std::function<void (datanodestore::DataInnerNode *node)> onBacktrackFromSubtree);
@ -56,7 +56,7 @@ namespace blobstore {
uint32_t _maxLeavesForTreeDepth(uint8_t depth) const; uint32_t _maxLeavesForTreeDepth(uint8_t depth) const;
std::function<cpputils::Data (uint32_t index)> _createMaxSizeLeaf() const; std::function<cpputils::Data (uint32_t index)> _createMaxSizeLeaf() const;
cpputils::unique_ref<datanodestore::DataNode> _whileRootHasOnlyOneChildReplaceRootWithItsChild(cpputils::unique_ref<datanodestore::DataNode> root); cpputils::unique_ref<datanodestore::DataNode> _whileRootHasOnlyOneChildReplaceRootWithItsChild(cpputils::unique_ref<datanodestore::DataNode> root);
cpputils::unique_ref<datanodestore::DataNode> _whileRootHasOnlyOneChildRemoveRootReturnChild(const blockstore::Key &key); cpputils::unique_ref<datanodestore::DataNode> _whileRootHasOnlyOneChildRemoveRootReturnChild(const blockstore::BlockId &blockId);
DISALLOW_COPY_AND_ASSIGN(LeafTraverser); DISALLOW_COPY_AND_ASSIGN(LeafTraverser);
}; };

View File

@ -1,6 +1,6 @@
#include "algorithms.h" #include "algorithms.h"
#include <cpp-utils/pointer/cast.h> #include <cpp-utils/pointer/cast.h>
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include "../../datanodestore/DataInnerNode.h" #include "../../datanodestore/DataInnerNode.h"
#include "../../datanodestore/DataNodeStore.h" #include "../../datanodestore/DataNodeStore.h"
@ -13,7 +13,7 @@ using cpputils::unique_ref;
using blobstore::onblocks::datanodestore::DataInnerNode; using blobstore::onblocks::datanodestore::DataInnerNode;
using blobstore::onblocks::datanodestore::DataNode; using blobstore::onblocks::datanodestore::DataNode;
using blobstore::onblocks::datanodestore::DataNodeStore; using blobstore::onblocks::datanodestore::DataNodeStore;
using blockstore::Key; using blockstore::BlockId;
using boost::optional; using boost::optional;
using boost::none; using boost::none;
@ -23,8 +23,8 @@ namespace datatreestore {
namespace algorithms { namespace algorithms {
optional<unique_ref<DataInnerNode>> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) { optional<unique_ref<DataInnerNode>> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) {
Key key = node.LastChild()->key(); BlockId blockId = node.LastChild()->blockId();
auto lastChild = nodeStore->load(key); auto lastChild = nodeStore->load(blockId);
ASSERT(lastChild != none, "Couldn't load last child"); ASSERT(lastChild != none, "Couldn't load last child");
return dynamic_pointer_move<DataInnerNode>(*lastChild); return dynamic_pointer_move<DataInnerNode>(*lastChild);
} }

View File

@ -10,12 +10,12 @@ namespace blobstore {
namespace onblocks { namespace onblocks {
namespace parallelaccessdatatreestore { namespace parallelaccessdatatreestore {
class DataTreeRef final: public parallelaccessstore::ParallelAccessStore<datatreestore::DataTree, DataTreeRef, blockstore::Key>::ResourceRefBase { class DataTreeRef final: public parallelaccessstore::ParallelAccessStore<datatreestore::DataTree, DataTreeRef, blockstore::BlockId>::ResourceRefBase {
public: public:
DataTreeRef(datatreestore::DataTree *baseTree): _baseTree(baseTree) {} DataTreeRef(datatreestore::DataTree *baseTree): _baseTree(baseTree) {}
const blockstore::Key &key() const { const blockstore::BlockId &blockId() const {
return _baseTree->key(); return _baseTree->blockId();
} }
uint64_t maxBytesPerLeaf() const { uint64_t maxBytesPerLeaf() const {

View File

@ -9,7 +9,7 @@ using cpputils::make_unique_ref;
using boost::optional; using boost::optional;
using blobstore::onblocks::datatreestore::DataTreeStore; using blobstore::onblocks::datatreestore::DataTreeStore;
using blockstore::Key; using blockstore::BlockId;
namespace blobstore { namespace blobstore {
namespace onblocks { namespace onblocks {
@ -26,23 +26,23 @@ ParallelAccessDataTreeStore::ParallelAccessDataTreeStore(unique_ref<DataTreeStor
ParallelAccessDataTreeStore::~ParallelAccessDataTreeStore() { ParallelAccessDataTreeStore::~ParallelAccessDataTreeStore() {
} }
optional<unique_ref<DataTreeRef>> ParallelAccessDataTreeStore::load(const blockstore::Key &key) { optional<unique_ref<DataTreeRef>> ParallelAccessDataTreeStore::load(const blockstore::BlockId &blockId) {
return _parallelAccessStore.load(key); return _parallelAccessStore.load(blockId);
} }
unique_ref<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() { unique_ref<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() {
auto dataTree = _dataTreeStore->createNewTree(); auto dataTree = _dataTreeStore->createNewTree();
Key key = dataTree->key(); BlockId blockId = dataTree->blockId();
return _parallelAccessStore.add(key, std::move(dataTree)); return _parallelAccessStore.add(blockId, std::move(dataTree));
} }
void ParallelAccessDataTreeStore::remove(unique_ref<DataTreeRef> tree) { void ParallelAccessDataTreeStore::remove(unique_ref<DataTreeRef> tree) {
Key key = tree->key(); BlockId blockId = tree->blockId();
return _parallelAccessStore.remove(key, std::move(tree)); return _parallelAccessStore.remove(blockId, std::move(tree));
} }
void ParallelAccessDataTreeStore::remove(const Key &key) { void ParallelAccessDataTreeStore::remove(const BlockId &blockId) {
return _parallelAccessStore.remove(key); return _parallelAccessStore.remove(blockId);
} }

View File

@ -4,7 +4,7 @@
#include <memory> #include <memory>
#include <cpp-utils/macros.h> #include <cpp-utils/macros.h>
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include <parallelaccessstore/ParallelAccessStore.h> #include <parallelaccessstore/ParallelAccessStore.h>
#include "../datatreestore/DataTreeStore.h" #include "../datatreestore/DataTreeStore.h"
@ -20,12 +20,12 @@ public:
ParallelAccessDataTreeStore(cpputils::unique_ref<datatreestore::DataTreeStore> dataTreeStore); ParallelAccessDataTreeStore(cpputils::unique_ref<datatreestore::DataTreeStore> dataTreeStore);
~ParallelAccessDataTreeStore(); ~ParallelAccessDataTreeStore();
boost::optional<cpputils::unique_ref<DataTreeRef>> load(const blockstore::Key &key); boost::optional<cpputils::unique_ref<DataTreeRef>> load(const blockstore::BlockId &blockId);
cpputils::unique_ref<DataTreeRef> createNewTree(); cpputils::unique_ref<DataTreeRef> createNewTree();
void remove(cpputils::unique_ref<DataTreeRef> tree); void remove(cpputils::unique_ref<DataTreeRef> tree);
void remove(const blockstore::Key &key); void remove(const blockstore::BlockId &blockId);
//TODO Test blocksizeBytes/numBlocks/estimateSpaceForNumBlocksLeft //TODO Test blocksizeBytes/numBlocks/estimateSpaceForNumBlocksLeft
uint64_t virtualBlocksizeBytes() const; uint64_t virtualBlocksizeBytes() const;
@ -34,7 +34,7 @@ public:
private: private:
cpputils::unique_ref<datatreestore::DataTreeStore> _dataTreeStore; cpputils::unique_ref<datatreestore::DataTreeStore> _dataTreeStore;
parallelaccessstore::ParallelAccessStore<datatreestore::DataTree, DataTreeRef, blockstore::Key> _parallelAccessStore; parallelaccessstore::ParallelAccessStore<datatreestore::DataTree, DataTreeRef, blockstore::BlockId> _parallelAccessStore;
DISALLOW_COPY_AND_ASSIGN(ParallelAccessDataTreeStore); DISALLOW_COPY_AND_ASSIGN(ParallelAccessDataTreeStore);
}; };

View File

@ -11,22 +11,22 @@ namespace blobstore {
namespace onblocks { namespace onblocks {
namespace parallelaccessdatatreestore { namespace parallelaccessdatatreestore {
class ParallelAccessDataTreeStoreAdapter final: public parallelaccessstore::ParallelAccessBaseStore<datatreestore::DataTree, blockstore::Key> { class ParallelAccessDataTreeStoreAdapter final: public parallelaccessstore::ParallelAccessBaseStore<datatreestore::DataTree, blockstore::BlockId> {
public: public:
ParallelAccessDataTreeStoreAdapter(datatreestore::DataTreeStore *baseDataTreeStore) ParallelAccessDataTreeStoreAdapter(datatreestore::DataTreeStore *baseDataTreeStore)
:_baseDataTreeStore(std::move(baseDataTreeStore)) { :_baseDataTreeStore(std::move(baseDataTreeStore)) {
} }
boost::optional<cpputils::unique_ref<datatreestore::DataTree>> loadFromBaseStore(const blockstore::Key &key) override { boost::optional<cpputils::unique_ref<datatreestore::DataTree>> loadFromBaseStore(const blockstore::BlockId &blockId) override {
return _baseDataTreeStore->load(key); return _baseDataTreeStore->load(blockId);
} }
void removeFromBaseStore(cpputils::unique_ref<datatreestore::DataTree> dataTree) override { void removeFromBaseStore(cpputils::unique_ref<datatreestore::DataTree> dataTree) override {
return _baseDataTreeStore->remove(std::move(dataTree)); return _baseDataTreeStore->remove(std::move(dataTree));
} }
void removeFromBaseStore(const blockstore::Key &key) override { void removeFromBaseStore(const blockstore::BlockId &blockId) override {
return _baseDataTreeStore->remove(key); return _baseDataTreeStore->remove(blockId);
} }
private: private:

View File

@ -4,7 +4,7 @@
#include <cstring> #include <cstring>
#include <cstdint> #include <cstdint>
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include <cpp-utils/data/Data.h> #include <cpp-utils/data/Data.h>
namespace blobstore { namespace blobstore {
@ -13,8 +13,8 @@ class Blob {
public: public:
virtual ~Blob() {} virtual ~Blob() {}
//TODO Use own Key class for blobstore //TODO Use own Id class for blobstore
virtual const blockstore::Key &key() const = 0; virtual const blockstore::BlockId &blockId() const = 0;
virtual uint64_t size() const = 0; virtual uint64_t size() const = 0;
virtual void resize(uint64_t numBytes) = 0; virtual void resize(uint64_t numBytes) = 0;

View File

@ -6,7 +6,7 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include <cpp-utils/pointer/unique_ref.h> #include <cpp-utils/pointer/unique_ref.h>
namespace blobstore { namespace blobstore {
@ -17,9 +17,9 @@ public:
virtual ~BlobStore() {} virtual ~BlobStore() {}
virtual cpputils::unique_ref<Blob> create() = 0; virtual cpputils::unique_ref<Blob> create() = 0;
virtual boost::optional<cpputils::unique_ref<Blob>> load(const blockstore::Key &key) = 0; virtual boost::optional<cpputils::unique_ref<Blob>> load(const blockstore::BlockId &blockId) = 0;
virtual void remove(cpputils::unique_ref<Blob> blob) = 0; virtual void remove(cpputils::unique_ref<Blob> blob) = 0;
virtual void remove(const blockstore::Key &key) = 0; virtual void remove(const blockstore::BlockId &blockId) = 0;
virtual uint64_t numBlocks() const = 0; virtual uint64_t numBlocks() const = 0;
virtual uint64_t estimateSpaceForNumBlocksLeft() const = 0; virtual uint64_t estimateSpaceForNumBlocksLeft() const = 0;

View File

@ -1,7 +1,7 @@
project (blockstore) project (blockstore)
set(SOURCES set(SOURCES
utils/Key.cpp utils/BlockId.cpp
utils/IdWrapper.cpp utils/IdWrapper.cpp
utils/BlockStoreUtils.cpp utils/BlockStoreUtils.cpp
utils/FileDoesntExistException.cpp utils/FileDoesntExistException.cpp
@ -27,7 +27,7 @@ set(SOURCES
implementations/low2highlevel/LowToHighLevelBlockStore.cpp implementations/low2highlevel/LowToHighLevelBlockStore.cpp
implementations/integrity/IntegrityBlockStore2.cpp implementations/integrity/IntegrityBlockStore2.cpp
implementations/integrity/KnownBlockVersions.cpp implementations/integrity/KnownBlockVersions.cpp
implementations/integrity/ClientIdAndBlockKey.cpp implementations/integrity/ClientIdAndBlockId.cpp
implementations/integrity/IntegrityViolationError.cpp implementations/integrity/IntegrityViolationError.cpp
implementations/mock/MockBlockStore.cpp implementations/mock/MockBlockStore.cpp
implementations/mock/MockBlock.cpp implementations/mock/MockBlock.cpp

View File

@ -22,17 +22,17 @@ using std::mutex;
namespace blockstore { namespace blockstore {
namespace caching { namespace caching {
CachingBlockStore2::CachedBlock::CachedBlock(const CachingBlockStore2* blockStore, const Key& key, cpputils::Data data, bool isDirty) CachingBlockStore2::CachedBlock::CachedBlock(const CachingBlockStore2* blockStore, const BlockId &blockId, cpputils::Data data, bool isDirty)
: _blockStore(blockStore), _key(key), _data(std::move(data)), _dirty(isDirty) { : _blockStore(blockStore), _blockId(blockId), _data(std::move(data)), _dirty(isDirty) {
} }
CachingBlockStore2::CachedBlock::~CachedBlock() { CachingBlockStore2::CachedBlock::~CachedBlock() {
if (_dirty) { if (_dirty) {
_blockStore->_baseBlockStore->store(_key, _data); _blockStore->_baseBlockStore->store(_blockId, _data);
} }
// remove it from the list of blocks not in the base store, if it's on it // remove it from the list of blocks not in the base store, if it's on it
unique_lock<mutex> lock(_blockStore->_cachedBlocksNotInBaseStoreMutex); unique_lock<mutex> lock(_blockStore->_cachedBlocksNotInBaseStoreMutex);
_blockStore->_cachedBlocksNotInBaseStore.erase(_key); _blockStore->_cachedBlocksNotInBaseStore.erase(_blockId);
} }
const Data& CachingBlockStore2::CachedBlock::read() const { const Data& CachingBlockStore2::CachedBlock::read() const {
@ -52,30 +52,30 @@ CachingBlockStore2::CachingBlockStore2(cpputils::unique_ref<BlockStore2> baseBlo
: _baseBlockStore(std::move(baseBlockStore)), _cachedBlocksNotInBaseStoreMutex(), _cachedBlocksNotInBaseStore(), _cache() { : _baseBlockStore(std::move(baseBlockStore)), _cachedBlocksNotInBaseStoreMutex(), _cachedBlocksNotInBaseStore(), _cache() {
} }
bool CachingBlockStore2::tryCreate(const Key &key, const Data &data) { bool CachingBlockStore2::tryCreate(const BlockId &blockId, const Data &data) {
//TODO Check if block exists in base store? Performance hit? It's very unlikely it exists. //TODO Check if block exists in base store? Performance hit? It's very unlikely it exists.
auto popped = _cache.pop(key); auto popped = _cache.pop(blockId);
if (popped != boost::none) { if (popped != boost::none) {
// entry already exists in cache // entry already exists in cache
_cache.push(key, std::move(*popped)); // push the just popped element back to the cache _cache.push(blockId, std::move(*popped)); // push the just popped element back to the cache
return false; return false;
} else { } else {
_cache.push(key, make_unique_ref<CachingBlockStore2::CachedBlock>(this, key, data.copy(), true)); _cache.push(blockId, make_unique_ref<CachingBlockStore2::CachedBlock>(this, blockId, data.copy(), true));
unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex); unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
_cachedBlocksNotInBaseStore.insert(key); _cachedBlocksNotInBaseStore.insert(blockId);
return true; return true;
} }
} }
bool CachingBlockStore2::remove(const Key &key) { bool CachingBlockStore2::remove(const BlockId &blockId) {
// TODO Don't write-through but cache remove operations // TODO Don't write-through but cache remove operations
auto popped = _cache.pop(key); auto popped = _cache.pop(blockId);
if (popped != boost::none) { if (popped != boost::none) {
// Remove from base store if it exists in the base store // Remove from base store if it exists in the base store
{ {
unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex); unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
if (_cachedBlocksNotInBaseStore.count(key) == 0) { if (_cachedBlocksNotInBaseStore.count(blockId) == 0) {
const bool existedInBaseStore = _baseBlockStore->remove(key); const bool existedInBaseStore = _baseBlockStore->remove(blockId);
if (!existedInBaseStore) { if (!existedInBaseStore) {
throw std::runtime_error("Tried to remove block. Block existed in cache and stated it exists in base store, but wasn't found there."); throw std::runtime_error("Tried to remove block. Block existed in cache and stated it exists in base store, but wasn't found there.");
} }
@ -85,45 +85,45 @@ bool CachingBlockStore2::remove(const Key &key) {
std::move(**popped).markNotDirty(); std::move(**popped).markNotDirty();
return true; return true;
} else { } else {
return _baseBlockStore->remove(key); return _baseBlockStore->remove(blockId);
} }
} }
optional<unique_ref<CachingBlockStore2::CachedBlock>> CachingBlockStore2::_loadFromCacheOrBaseStore(const Key &key) const { optional<unique_ref<CachingBlockStore2::CachedBlock>> CachingBlockStore2::_loadFromCacheOrBaseStore(const BlockId &blockId) const {
auto popped = _cache.pop(key); auto popped = _cache.pop(blockId);
if (popped != boost::none) { if (popped != boost::none) {
return std::move(*popped); return std::move(*popped);
} else { } else {
auto loaded = _baseBlockStore->load(key); auto loaded = _baseBlockStore->load(blockId);
if (loaded == boost::none) { if (loaded == boost::none) {
return boost::none; return boost::none;
} }
return make_unique_ref<CachingBlockStore2::CachedBlock>(this, key, std::move(*loaded), false); return make_unique_ref<CachingBlockStore2::CachedBlock>(this, blockId, std::move(*loaded), false);
} }
} }
optional<Data> CachingBlockStore2::load(const Key &key) const { optional<Data> CachingBlockStore2::load(const BlockId &blockId) const {
auto loaded = _loadFromCacheOrBaseStore(key); auto loaded = _loadFromCacheOrBaseStore(blockId);
if (loaded == boost::none) { if (loaded == boost::none) {
// TODO Cache non-existence? // TODO Cache non-existence?
return boost::none; return boost::none;
} }
optional<Data> result = (*loaded)->read().copy(); optional<Data> result = (*loaded)->read().copy();
_cache.push(key, std::move(*loaded)); _cache.push(blockId, std::move(*loaded));
return result; return result;
} }
void CachingBlockStore2::store(const Key &key, const Data &data) { void CachingBlockStore2::store(const BlockId &blockId, const Data &data) {
auto popped = _cache.pop(key); auto popped = _cache.pop(blockId);
if (popped != boost::none) { if (popped != boost::none) {
(*popped)->write(data.copy()); (*popped)->write(data.copy());
} else { } else {
popped = make_unique_ref<CachingBlockStore2::CachedBlock>(this, key, data.copy(), false); popped = make_unique_ref<CachingBlockStore2::CachedBlock>(this, blockId, data.copy(), false);
// TODO Instead of storing it to the base store, we could just keep it dirty in the cache // TODO Instead of storing it to the base store, we could just keep it dirty in the cache
// and (if it doesn't exist in base store yet) add it to _cachedBlocksNotInBaseStore // and (if it doesn't exist in base store yet) add it to _cachedBlocksNotInBaseStore
_baseBlockStore->store(key, data); _baseBlockStore->store(blockId, data);
} }
_cache.push(key, std::move(*popped)); _cache.push(blockId, std::move(*popped));
} }
uint64_t CachingBlockStore2::numBlocks() const { uint64_t CachingBlockStore2::numBlocks() const {
@ -143,11 +143,11 @@ uint64_t CachingBlockStore2::blockSizeFromPhysicalBlockSize(uint64_t blockSize)
return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize); return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize);
} }
void CachingBlockStore2::forEachBlock(std::function<void (const Key &)> callback) const { void CachingBlockStore2::forEachBlock(std::function<void (const BlockId &)> callback) const {
{ {
unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex); unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
for (const Key &key : _cachedBlocksNotInBaseStore) { for (const BlockId &blockId : _cachedBlocksNotInBaseStore) {
callback(key); callback(blockId);
} }
} }
_baseBlockStore->forEachBlock(std::move(callback)); _baseBlockStore->forEachBlock(std::move(callback));

View File

@ -14,14 +14,14 @@ class CachingBlockStore2 final: public BlockStore2 {
public: public:
CachingBlockStore2(cpputils::unique_ref<BlockStore2> baseBlockStore); CachingBlockStore2(cpputils::unique_ref<BlockStore2> baseBlockStore);
bool tryCreate(const Key &key, const cpputils::Data &data) override; bool tryCreate(const BlockId &blockId, const cpputils::Data &data) override;
bool remove(const Key &key) override; bool remove(const BlockId &blockId) override;
boost::optional<cpputils::Data> load(const Key &key) const override; boost::optional<cpputils::Data> load(const BlockId &blockId) const override;
void store(const Key &key, const cpputils::Data &data) override; void store(const BlockId &blockId, const cpputils::Data &data) override;
uint64_t numBlocks() const override; uint64_t numBlocks() const override;
uint64_t estimateNumFreeBytes() const override; uint64_t estimateNumFreeBytes() const override;
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
void forEachBlock(std::function<void (const Key &)> callback) const override; void forEachBlock(std::function<void (const BlockId &)> callback) const override;
void flush(); void flush();
@ -29,7 +29,7 @@ private:
// TODO Is a cache implementation with onEvict callback instead of destructor simpler? // TODO Is a cache implementation with onEvict callback instead of destructor simpler?
class CachedBlock final { class CachedBlock final {
public: public:
CachedBlock(const CachingBlockStore2* blockStore, const Key& key, cpputils::Data data, bool isDirty); CachedBlock(const CachingBlockStore2* blockStore, const BlockId &blockId, cpputils::Data data, bool isDirty);
~CachedBlock(); ~CachedBlock();
const cpputils::Data& read() const; const cpputils::Data& read() const;
@ -37,22 +37,22 @@ private:
void markNotDirty() &&; // only on rvalue because the destructor should be called after calling markNotDirty(). It shouldn't be put back into the cache. void markNotDirty() &&; // only on rvalue because the destructor should be called after calling markNotDirty(). It shouldn't be put back into the cache.
private: private:
const CachingBlockStore2* _blockStore; const CachingBlockStore2* _blockStore;
Key _key; BlockId _blockId;
cpputils::Data _data; cpputils::Data _data;
bool _dirty; bool _dirty;
DISALLOW_COPY_AND_ASSIGN(CachedBlock); DISALLOW_COPY_AND_ASSIGN(CachedBlock);
}; };
boost::optional<cpputils::unique_ref<CachedBlock>> _loadFromCacheOrBaseStore(const Key &key) const; boost::optional<cpputils::unique_ref<CachedBlock>> _loadFromCacheOrBaseStore(const BlockId &blockId) const;
cpputils::unique_ref<BlockStore2> _baseBlockStore; cpputils::unique_ref<BlockStore2> _baseBlockStore;
friend class CachedBlock; friend class CachedBlock;
// TODO Store CachedBlock directly, without unique_ref // TODO Store CachedBlock directly, without unique_ref
mutable std::mutex _cachedBlocksNotInBaseStoreMutex; mutable std::mutex _cachedBlocksNotInBaseStoreMutex;
mutable std::unordered_set<Key> _cachedBlocksNotInBaseStore; mutable std::unordered_set<BlockId> _cachedBlocksNotInBaseStore;
mutable Cache<Key, cpputils::unique_ref<CachedBlock>, 1000> _cache; mutable Cache<BlockId, cpputils::unique_ref<CachedBlock>, 1000> _cache;
DISALLOW_COPY_AND_ASSIGN(CachingBlockStore2); DISALLOW_COPY_AND_ASSIGN(CachingBlockStore2);
}; };

View File

@ -18,8 +18,8 @@ template<class Compressor> class CompressingBlockStore;
template<class Compressor> template<class Compressor>
class CompressedBlock final: public Block { class CompressedBlock final: public Block {
public: public:
static boost::optional<cpputils::unique_ref<CompressedBlock>> TryCreateNew(BlockStore *baseBlockStore, const Key &key, cpputils::Data decompressedData); static boost::optional<cpputils::unique_ref<CompressedBlock>> TryCreateNew(BlockStore *baseBlockStore, const BlockId &blockId, cpputils::Data decompressedData);
static cpputils::unique_ref<CompressedBlock> Overwrite(BlockStore *baseBlockStore, const Key &key, cpputils::Data decompressedData); static cpputils::unique_ref<CompressedBlock> Overwrite(BlockStore *baseBlockStore, const BlockId &blockId, cpputils::Data decompressedData);
static cpputils::unique_ref<CompressedBlock> Decompress(cpputils::unique_ref<Block> baseBlock); static cpputils::unique_ref<CompressedBlock> Decompress(cpputils::unique_ref<Block> baseBlock);
CompressedBlock(cpputils::unique_ref<Block> baseBlock, cpputils::Data decompressedData); CompressedBlock(cpputils::unique_ref<Block> baseBlock, cpputils::Data decompressedData);
@ -47,9 +47,9 @@ private:
}; };
template<class Compressor> template<class Compressor>
boost::optional<cpputils::unique_ref<CompressedBlock<Compressor>>> CompressedBlock<Compressor>::TryCreateNew(BlockStore *baseBlockStore, const Key &key, cpputils::Data decompressedData) { boost::optional<cpputils::unique_ref<CompressedBlock<Compressor>>> CompressedBlock<Compressor>::TryCreateNew(BlockStore *baseBlockStore, const BlockId &blockId, cpputils::Data decompressedData) {
cpputils::Data compressed = Compressor::Compress(decompressedData); cpputils::Data compressed = Compressor::Compress(decompressedData);
auto baseBlock = baseBlockStore->tryCreate(key, std::move(compressed)); auto baseBlock = baseBlockStore->tryCreate(blockId, std::move(compressed));
if (baseBlock == boost::none) { if (baseBlock == boost::none) {
//TODO Test this code branch //TODO Test this code branch
return boost::none; return boost::none;
@ -59,9 +59,9 @@ boost::optional<cpputils::unique_ref<CompressedBlock<Compressor>>> CompressedBlo
} }
template<class Compressor> template<class Compressor>
cpputils::unique_ref<CompressedBlock<Compressor>> CompressedBlock<Compressor>::Overwrite(BlockStore *baseBlockStore, const Key &key, cpputils::Data decompressedData) { cpputils::unique_ref<CompressedBlock<Compressor>> CompressedBlock<Compressor>::Overwrite(BlockStore *baseBlockStore, const BlockId &blockId, cpputils::Data decompressedData) {
cpputils::Data compressed = Compressor::Compress(decompressedData); cpputils::Data compressed = Compressor::Compress(decompressedData);
auto baseBlock = baseBlockStore->overwrite(key, std::move(compressed)); auto baseBlock = baseBlockStore->overwrite(blockId, std::move(compressed));
return cpputils::make_unique_ref<CompressedBlock<Compressor>>(std::move(baseBlock), std::move(decompressedData)); return cpputils::make_unique_ref<CompressedBlock<Compressor>>(std::move(baseBlock), std::move(decompressedData));
} }
@ -74,7 +74,7 @@ cpputils::unique_ref<CompressedBlock<Compressor>> CompressedBlock<Compressor>::D
template<class Compressor> template<class Compressor>
CompressedBlock<Compressor>::CompressedBlock(cpputils::unique_ref<Block> baseBlock, cpputils::Data decompressedData) CompressedBlock<Compressor>::CompressedBlock(cpputils::unique_ref<Block> baseBlock, cpputils::Data decompressedData)
: Block(baseBlock->key()), : Block(baseBlock->blockId()),
_baseBlock(std::move(baseBlock)), _baseBlock(std::move(baseBlock)),
_decompressedData(std::move(decompressedData)), _decompressedData(std::move(decompressedData)),
_dataChanged(false) { _dataChanged(false) {

View File

@ -14,15 +14,15 @@ public:
CompressingBlockStore(cpputils::unique_ref<BlockStore> baseBlockStore); CompressingBlockStore(cpputils::unique_ref<BlockStore> baseBlockStore);
~CompressingBlockStore(); ~CompressingBlockStore();
Key createKey() override; BlockId createBlockId() override;
boost::optional<cpputils::unique_ref<Block>> tryCreate(const Key &key, cpputils::Data data) override; boost::optional<cpputils::unique_ref<Block>> tryCreate(const BlockId &blockId, cpputils::Data data) override;
boost::optional<cpputils::unique_ref<Block>> load(const Key &key) override; boost::optional<cpputils::unique_ref<Block>> load(const BlockId &blockId) override;
cpputils::unique_ref<Block> overwrite(const blockstore::Key &key, cpputils::Data data) override; cpputils::unique_ref<Block> overwrite(const blockstore::BlockId &blockId, cpputils::Data data) override;
void remove(const Key &key) override; void remove(const BlockId &blockId) override;
uint64_t numBlocks() const override; uint64_t numBlocks() const override;
uint64_t estimateNumFreeBytes() const override; uint64_t estimateNumFreeBytes() const override;
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
void forEachBlock(std::function<void (const Key &)> callback) const override; void forEachBlock(std::function<void (const BlockId &)> callback) const override;
private: private:
cpputils::unique_ref<BlockStore> _baseBlockStore; cpputils::unique_ref<BlockStore> _baseBlockStore;
@ -40,13 +40,13 @@ CompressingBlockStore<Compressor>::~CompressingBlockStore() {
} }
template<class Compressor> template<class Compressor>
Key CompressingBlockStore<Compressor>::createKey() { BlockId CompressingBlockStore<Compressor>::createBlockId() {
return _baseBlockStore->createKey(); return _baseBlockStore->createBlockId();
} }
template<class Compressor> template<class Compressor>
boost::optional<cpputils::unique_ref<Block>> CompressingBlockStore<Compressor>::tryCreate(const Key &key, cpputils::Data data) { boost::optional<cpputils::unique_ref<Block>> CompressingBlockStore<Compressor>::tryCreate(const BlockId &blockId, cpputils::Data data) {
auto result = CompressedBlock<Compressor>::TryCreateNew(_baseBlockStore.get(), key, std::move(data)); auto result = CompressedBlock<Compressor>::TryCreateNew(_baseBlockStore.get(), blockId, std::move(data));
if (result == boost::none) { if (result == boost::none) {
return boost::none; return boost::none;
} }
@ -54,13 +54,13 @@ boost::optional<cpputils::unique_ref<Block>> CompressingBlockStore<Compressor>::
} }
template<class Compressor> template<class Compressor>
cpputils::unique_ref<Block> CompressingBlockStore<Compressor>::overwrite(const blockstore::Key &key, cpputils::Data data) { cpputils::unique_ref<Block> CompressingBlockStore<Compressor>::overwrite(const blockstore::BlockId &blockId, cpputils::Data data) {
return CompressedBlock<Compressor>::Overwrite(_baseBlockStore.get(), key, std::move(data)); return CompressedBlock<Compressor>::Overwrite(_baseBlockStore.get(), blockId, std::move(data));
} }
template<class Compressor> template<class Compressor>
boost::optional<cpputils::unique_ref<Block>> CompressingBlockStore<Compressor>::load(const Key &key) { boost::optional<cpputils::unique_ref<Block>> CompressingBlockStore<Compressor>::load(const BlockId &blockId) {
auto loaded = _baseBlockStore->load(key); auto loaded = _baseBlockStore->load(blockId);
if (loaded == boost::none) { if (loaded == boost::none) {
return boost::none; return boost::none;
} }
@ -68,8 +68,8 @@ boost::optional<cpputils::unique_ref<Block>> CompressingBlockStore<Compressor>::
} }
template<class Compressor> template<class Compressor>
void CompressingBlockStore<Compressor>::remove(const Key &key) { void CompressingBlockStore<Compressor>::remove(const BlockId &blockId) {
return _baseBlockStore->remove(key); return _baseBlockStore->remove(blockId);
} }
template<class Compressor> template<class Compressor>
@ -83,7 +83,7 @@ uint64_t CompressingBlockStore<Compressor>::estimateNumFreeBytes() const {
} }
template<class Compressor> template<class Compressor>
void CompressingBlockStore<Compressor>::forEachBlock(std::function<void (const Key &)> callback) const { void CompressingBlockStore<Compressor>::forEachBlock(std::function<void (const BlockId &)> callback) const {
return _baseBlockStore->forEachBlock(callback); return _baseBlockStore->forEachBlock(callback);
} }

View File

@ -19,14 +19,14 @@ public:
EncryptedBlockStore2(cpputils::unique_ref<BlockStore2> baseBlockStore, const typename Cipher::EncryptionKey &encKey); EncryptedBlockStore2(cpputils::unique_ref<BlockStore2> baseBlockStore, const typename Cipher::EncryptionKey &encKey);
bool tryCreate(const Key &key, const cpputils::Data &data) override; bool tryCreate(const BlockId &blockId, const cpputils::Data &data) override;
bool remove(const Key &key) override; bool remove(const BlockId &blockId) override;
boost::optional<cpputils::Data> load(const Key &key) const override; boost::optional<cpputils::Data> load(const BlockId &blockId) const override;
void store(const Key &key, const cpputils::Data &data) override; void store(const BlockId &blockId, const cpputils::Data &data) override;
uint64_t numBlocks() const override; uint64_t numBlocks() const override;
uint64_t estimateNumFreeBytes() const override; uint64_t estimateNumFreeBytes() const override;
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
void forEachBlock(std::function<void (const Key &)> callback) const override; void forEachBlock(std::function<void (const BlockId &)> callback) const override;
//This function should only be used by test cases //This function should only be used by test cases
void __setKey(const typename Cipher::EncryptionKey &encKey); void __setKey(const typename Cipher::EncryptionKey &encKey);
@ -40,11 +40,11 @@ private:
static constexpr uint16_t FORMAT_VERSION_HEADER = 1; static constexpr uint16_t FORMAT_VERSION_HEADER = 1;
cpputils::Data _encrypt(const cpputils::Data &data) const; cpputils::Data _encrypt(const cpputils::Data &data) const;
boost::optional<cpputils::Data> _tryDecrypt(const Key &key, const cpputils::Data &data) const; boost::optional<cpputils::Data> _tryDecrypt(const BlockId &blockId, const cpputils::Data &data) const;
static cpputils::Data _prependFormatHeaderToData(const cpputils::Data &data); static cpputils::Data _prependFormatHeaderToData(const cpputils::Data &data);
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
static bool _keyHeaderIsCorrect(const Key &key, const cpputils::Data &data); static bool _blockIdHeaderIsCorrect(const BlockId &blockId, const cpputils::Data &data);
static cpputils::Data _migrateBlock(const cpputils::Data &data); static cpputils::Data _migrateBlock(const cpputils::Data &data);
#endif #endif
static void _checkFormatHeader(const cpputils::Data &data); static void _checkFormatHeader(const cpputils::Data &data);
@ -70,30 +70,30 @@ inline EncryptedBlockStore2<Cipher>::EncryptedBlockStore2(cpputils::unique_ref<B
} }
template<class Cipher> template<class Cipher>
inline bool EncryptedBlockStore2<Cipher>::tryCreate(const Key &key, const cpputils::Data &data) { inline bool EncryptedBlockStore2<Cipher>::tryCreate(const BlockId &blockId, const cpputils::Data &data) {
cpputils::Data encrypted = _encrypt(data); cpputils::Data encrypted = _encrypt(data);
return _baseBlockStore->tryCreate(key, encrypted); return _baseBlockStore->tryCreate(blockId, encrypted);
} }
template<class Cipher> template<class Cipher>
inline bool EncryptedBlockStore2<Cipher>::remove(const Key &key) { inline bool EncryptedBlockStore2<Cipher>::remove(const BlockId &blockId) {
return _baseBlockStore->remove(key); return _baseBlockStore->remove(blockId);
} }
template<class Cipher> template<class Cipher>
inline boost::optional<cpputils::Data> EncryptedBlockStore2<Cipher>::load(const Key &key) const { inline boost::optional<cpputils::Data> EncryptedBlockStore2<Cipher>::load(const BlockId &blockId) const {
auto loaded = _baseBlockStore->load(key); auto loaded = _baseBlockStore->load(blockId);
if (boost::none == loaded) { if (boost::none == loaded) {
return boost::optional<cpputils::Data>(boost::none); return boost::optional<cpputils::Data>(boost::none);
} }
return _tryDecrypt(key, *loaded); return _tryDecrypt(blockId, *loaded);
} }
template<class Cipher> template<class Cipher>
inline void EncryptedBlockStore2<Cipher>::store(const Key &key, const cpputils::Data &data) { inline void EncryptedBlockStore2<Cipher>::store(const BlockId &blockId, const cpputils::Data &data) {
cpputils::Data encrypted = _encrypt(data); cpputils::Data encrypted = _encrypt(data);
return _baseBlockStore->store(key, encrypted); return _baseBlockStore->store(blockId, encrypted);
} }
template<class Cipher> template<class Cipher>
@ -116,7 +116,7 @@ inline uint64_t EncryptedBlockStore2<Cipher>::blockSizeFromPhysicalBlockSize(uin
} }
template<class Cipher> template<class Cipher>
inline void EncryptedBlockStore2<Cipher>::forEachBlock(std::function<void (const Key &)> callback) const { inline void EncryptedBlockStore2<Cipher>::forEachBlock(std::function<void (const BlockId &)> callback) const {
return _baseBlockStore->forEachBlock(std::move(callback)); return _baseBlockStore->forEachBlock(std::move(callback));
} }
@ -127,7 +127,7 @@ inline cpputils::Data EncryptedBlockStore2<Cipher>::_encrypt(const cpputils::Dat
} }
template<class Cipher> template<class Cipher>
inline boost::optional<cpputils::Data> EncryptedBlockStore2<Cipher>::_tryDecrypt(const Key &key, const cpputils::Data &data) const { inline boost::optional<cpputils::Data> EncryptedBlockStore2<Cipher>::_tryDecrypt(const BlockId &blockId, const cpputils::Data &data) const {
_checkFormatHeader(data); _checkFormatHeader(data);
boost::optional<cpputils::Data> decrypted = Cipher::decrypt((CryptoPP::byte*)data.dataOffset(sizeof(FORMAT_VERSION_HEADER)), data.size() - sizeof(FORMAT_VERSION_HEADER), _encKey); boost::optional<cpputils::Data> decrypted = Cipher::decrypt((CryptoPP::byte*)data.dataOffset(sizeof(FORMAT_VERSION_HEADER)), data.size() - sizeof(FORMAT_VERSION_HEADER), _encKey);
if (decrypted == boost::none) { if (decrypted == boost::none) {
@ -137,7 +137,7 @@ inline boost::optional<cpputils::Data> EncryptedBlockStore2<Cipher>::_tryDecrypt
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
if (FORMAT_VERSION_HEADER_OLD == _readFormatHeader(data)) { if (FORMAT_VERSION_HEADER_OLD == _readFormatHeader(data)) {
if (!_keyHeaderIsCorrect(key, *decrypted)) { if (!_blockIdHeaderIsCorrect(blockId, *decrypted)) {
return boost::none; return boost::none;
} }
*decrypted = _migrateBlock(*decrypted); *decrypted = _migrateBlock(*decrypted);
@ -152,12 +152,12 @@ inline boost::optional<cpputils::Data> EncryptedBlockStore2<Cipher>::_tryDecrypt
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
template<class Cipher> template<class Cipher>
inline cpputils::Data EncryptedBlockStore2<Cipher>::_migrateBlock(const cpputils::Data &data) { inline cpputils::Data EncryptedBlockStore2<Cipher>::_migrateBlock(const cpputils::Data &data) {
return data.copyAndRemovePrefix(Key::BINARY_LENGTH); return data.copyAndRemovePrefix(BlockId::BINARY_LENGTH);
} }
template<class Cipher> template<class Cipher>
inline bool EncryptedBlockStore2<Cipher>::_keyHeaderIsCorrect(const Key &key, const cpputils::Data &data) { inline bool EncryptedBlockStore2<Cipher>::_blockIdHeaderIsCorrect(const BlockId &blockId, const cpputils::Data &data) {
return key == Key::FromBinary(data.data()); return blockId == BlockId::FromBinary(data.data());
} }
#endif #endif

View File

@ -23,21 +23,21 @@ namespace inmemory {
InMemoryBlockStore2::InMemoryBlockStore2() InMemoryBlockStore2::InMemoryBlockStore2()
: _blocks() {} : _blocks() {}
bool InMemoryBlockStore2::tryCreate(const Key &key, const Data &data) { bool InMemoryBlockStore2::tryCreate(const BlockId &blockId, const Data &data) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
return _tryCreate(key, data); return _tryCreate(blockId, data);
} }
bool InMemoryBlockStore2::_tryCreate(const Key &key, const Data &data) { bool InMemoryBlockStore2::_tryCreate(const BlockId &blockId, const Data &data) {
auto result = _blocks.insert(make_pair(key, data.copy())); auto result = _blocks.insert(make_pair(blockId, data.copy()));
return result.second; // Return if insertion was successful (i.e. key didn't exist yet) return result.second; // Return if insertion was successful (i.e. blockId didn't exist yet)
} }
bool InMemoryBlockStore2::remove(const Key &key) { bool InMemoryBlockStore2::remove(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
auto found = _blocks.find(key); auto found = _blocks.find(blockId);
if (found == _blocks.end()) { if (found == _blocks.end()) {
// Key not found // BlockId not found
return false; return false;
} }
@ -45,20 +45,20 @@ bool InMemoryBlockStore2::remove(const Key &key) {
return true; return true;
} }
optional<Data> InMemoryBlockStore2::load(const Key &key) const { optional<Data> InMemoryBlockStore2::load(const BlockId &blockId) const {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
auto found = _blocks.find(key); auto found = _blocks.find(blockId);
if (found == _blocks.end()) { if (found == _blocks.end()) {
return boost::none; return boost::none;
} }
return found->second.copy(); return found->second.copy();
} }
void InMemoryBlockStore2::store(const Key &key, const Data &data) { void InMemoryBlockStore2::store(const BlockId &blockId, const Data &data) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
auto found = _blocks.find(key); auto found = _blocks.find(blockId);
if (found == _blocks.end()) { if (found == _blocks.end()) {
bool success = _tryCreate(key, data); bool success = _tryCreate(blockId, data);
if (!success) { if (!success) {
throw std::runtime_error("Could neither save nor create the block in InMemoryBlockStore::store()"); throw std::runtime_error("Could neither save nor create the block in InMemoryBlockStore::store()");
} }
@ -81,9 +81,9 @@ uint64_t InMemoryBlockStore2::blockSizeFromPhysicalBlockSize(uint64_t blockSize)
return blockSize; return blockSize;
} }
vector<Key> InMemoryBlockStore2::_allBlockKeys() const { vector<BlockId> InMemoryBlockStore2::_allBlockIds() const {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
vector<Key> result; vector<BlockId> result;
result.reserve(_blocks.size()); result.reserve(_blocks.size());
for (const auto &entry : _blocks) { for (const auto &entry : _blocks) {
result.push_back(entry.first); result.push_back(entry.first);
@ -91,10 +91,10 @@ vector<Key> InMemoryBlockStore2::_allBlockKeys() const {
return result; return result;
} }
void InMemoryBlockStore2::forEachBlock(std::function<void (const Key &)> callback) const { void InMemoryBlockStore2::forEachBlock(std::function<void (const BlockId &)> callback) const {
auto keys = _allBlockKeys(); auto blockIds = _allBlockIds();
for (const auto &key : keys) { for (const auto &blockId : blockIds) {
callback(key); callback(blockId);
} }
} }

View File

@ -13,20 +13,20 @@ class InMemoryBlockStore2 final: public BlockStore2 {
public: public:
InMemoryBlockStore2(); InMemoryBlockStore2();
bool tryCreate(const Key &key, const cpputils::Data &data) override; bool tryCreate(const BlockId &blockId, const cpputils::Data &data) override;
bool remove(const Key &key) override; bool remove(const BlockId &blockId) override;
boost::optional<cpputils::Data> load(const Key &key) const override; boost::optional<cpputils::Data> load(const BlockId &blockId) const override;
void store(const Key &key, const cpputils::Data &data) override; void store(const BlockId &blockId, const cpputils::Data &data) override;
uint64_t numBlocks() const override; uint64_t numBlocks() const override;
uint64_t estimateNumFreeBytes() const override; uint64_t estimateNumFreeBytes() const override;
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
void forEachBlock(std::function<void (const Key &)> callback) const override; void forEachBlock(std::function<void (const BlockId &)> callback) const override;
private: private:
std::vector<Key> _allBlockKeys() const; std::vector<BlockId> _allBlockIds() const;
bool _tryCreate(const Key &key, const cpputils::Data &data); bool _tryCreate(const BlockId &blockId, const cpputils::Data &data);
std::unordered_map<Key, cpputils::Data> _blocks; std::unordered_map<BlockId, cpputils::Data> _blocks;
mutable std::mutex _mutex; mutable std::mutex _mutex;
DISALLOW_COPY_AND_ASSIGN(InMemoryBlockStore2); DISALLOW_COPY_AND_ASSIGN(InMemoryBlockStore2);

View File

@ -0,0 +1 @@
#include "ClientIdAndBlockId.h"

View File

@ -1,16 +1,16 @@
#pragma once #pragma once
#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_INTEGRITY_CLIENTIDANDBLOCKKEY_H_ #ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_INTEGRITY_CLIENTIDANDBLOCKID_H_
#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_INTEGRITY_CLIENTIDANDBLOCKKEY_H_ #define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_INTEGRITY_CLIENTIDANDBLOCKID_H_
#include <utility> #include <utility>
#include "../../utils/Key.h" #include "blockstore/utils/BlockId.h"
namespace blockstore { namespace blockstore {
namespace integrity { namespace integrity {
struct ClientIdAndBlockKey { struct ClientIdAndBlockId {
uint32_t clientId; uint32_t clientId;
Key blockKey; BlockId blockId;
}; };
} }
@ -18,15 +18,15 @@ namespace blockstore {
// Allow using it in std::unordered_set / std::unordered_map // Allow using it in std::unordered_set / std::unordered_map
namespace std { namespace std {
template<> struct hash<blockstore::integrity::ClientIdAndBlockKey> { template<> struct hash<blockstore::integrity::ClientIdAndBlockId> {
size_t operator()(const blockstore::integrity::ClientIdAndBlockKey &ref) const { size_t operator()(const blockstore::integrity::ClientIdAndBlockId &ref) const {
return std::hash<uint32_t>()(ref.clientId) ^ std::hash<blockstore::Key>()(ref.blockKey); return std::hash<uint32_t>()(ref.clientId) ^ std::hash<blockstore::BlockId>()(ref.blockId);
} }
}; };
template<> struct equal_to<blockstore::integrity::ClientIdAndBlockKey> { template<> struct equal_to<blockstore::integrity::ClientIdAndBlockId> {
size_t operator()(const blockstore::integrity::ClientIdAndBlockKey &lhs, const blockstore::integrity::ClientIdAndBlockKey &rhs) const { size_t operator()(const blockstore::integrity::ClientIdAndBlockId &lhs, const blockstore::integrity::ClientIdAndBlockId &rhs) const {
return lhs.clientId == rhs.clientId && lhs.blockKey == rhs.blockKey; return lhs.clientId == rhs.clientId && lhs.blockId == rhs.blockId;
} }
}; };
} }

View File

@ -1 +0,0 @@
#include "ClientIdAndBlockKey.h"

View File

@ -22,21 +22,21 @@ constexpr unsigned int IntegrityBlockStore2::CLIENTID_HEADER_OFFSET;
constexpr unsigned int IntegrityBlockStore2::VERSION_HEADER_OFFSET; constexpr unsigned int IntegrityBlockStore2::VERSION_HEADER_OFFSET;
constexpr unsigned int IntegrityBlockStore2::HEADER_LENGTH; constexpr unsigned int IntegrityBlockStore2::HEADER_LENGTH;
Data IntegrityBlockStore2::_prependHeaderToData(const Key& key, uint32_t myClientId, uint64_t version, const Data &data) { Data IntegrityBlockStore2::_prependHeaderToData(const BlockId& blockId, uint32_t myClientId, uint64_t version, const Data &data) {
static_assert(HEADER_LENGTH == sizeof(FORMAT_VERSION_HEADER) + Key::BINARY_LENGTH + sizeof(myClientId) + sizeof(version), "Wrong header length"); static_assert(HEADER_LENGTH == sizeof(FORMAT_VERSION_HEADER) + BlockId::BINARY_LENGTH + sizeof(myClientId) + sizeof(version), "Wrong header length");
Data result(data.size() + HEADER_LENGTH); Data result(data.size() + HEADER_LENGTH);
std::memcpy(result.dataOffset(0), &FORMAT_VERSION_HEADER, sizeof(FORMAT_VERSION_HEADER)); std::memcpy(result.dataOffset(0), &FORMAT_VERSION_HEADER, sizeof(FORMAT_VERSION_HEADER));
std::memcpy(result.dataOffset(ID_HEADER_OFFSET), key.data().data(), Key::BINARY_LENGTH); std::memcpy(result.dataOffset(ID_HEADER_OFFSET), blockId.data().data(), BlockId::BINARY_LENGTH);
std::memcpy(result.dataOffset(CLIENTID_HEADER_OFFSET), &myClientId, sizeof(myClientId)); std::memcpy(result.dataOffset(CLIENTID_HEADER_OFFSET), &myClientId, sizeof(myClientId));
std::memcpy(result.dataOffset(VERSION_HEADER_OFFSET), &version, sizeof(version)); std::memcpy(result.dataOffset(VERSION_HEADER_OFFSET), &version, sizeof(version));
std::memcpy((uint8_t*)result.dataOffset(HEADER_LENGTH), data.data(), data.size()); std::memcpy((uint8_t*)result.dataOffset(HEADER_LENGTH), data.data(), data.size());
return result; return result;
} }
void IntegrityBlockStore2::_checkHeader(const Key &key, const Data &data) const { void IntegrityBlockStore2::_checkHeader(const BlockId &blockId, const Data &data) const {
_checkFormatHeader(data); _checkFormatHeader(data);
_checkIdHeader(key, data); _checkIdHeader(blockId, data);
_checkVersionHeader(key, data); _checkVersionHeader(blockId, data);
} }
void IntegrityBlockStore2::_checkFormatHeader(const Data &data) const { void IntegrityBlockStore2::_checkFormatHeader(const Data &data) const {
@ -45,19 +45,19 @@ void IntegrityBlockStore2::_checkFormatHeader(const Data &data) const {
} }
} }
void IntegrityBlockStore2::_checkVersionHeader(const Key &key, const Data &data) const { void IntegrityBlockStore2::_checkVersionHeader(const BlockId &blockId, const Data &data) const {
uint32_t clientId = _readClientId(data); uint32_t clientId = _readClientId(data);
uint64_t version = _readVersion(data); uint64_t version = _readVersion(data);
if(!_knownBlockVersions.checkAndUpdateVersion(clientId, key, version)) { if(!_knownBlockVersions.checkAndUpdateVersion(clientId, blockId, version)) {
integrityViolationDetected("The block version number is too low. Did an attacker try to roll back the block or to re-introduce a deleted block?"); integrityViolationDetected("The block version number is too low. Did an attacker try to roll back the block or to re-introduce a deleted block?");
} }
} }
void IntegrityBlockStore2::_checkIdHeader(const Key &expectedKey, const Data &data) const { void IntegrityBlockStore2::_checkIdHeader(const BlockId &expectedBlockId, const Data &data) const {
Key actualKey = _readBlockId(data); BlockId actualBlockId = _readBlockId(data);
if (expectedKey != actualKey) { if (expectedBlockId != actualBlockId) {
integrityViolationDetected("The block key is wrong. Did an attacker try to rename some blocks?"); integrityViolationDetected("The block id is wrong. Did an attacker try to rename some blocks?");
} }
} }
@ -71,8 +71,8 @@ uint32_t IntegrityBlockStore2::_readClientId(const Data &data) {
return clientId; return clientId;
} }
Key IntegrityBlockStore2::_readBlockId(const Data &data) { BlockId IntegrityBlockStore2::_readBlockId(const Data &data) {
return Key::FromBinary(data.dataOffset(ID_HEADER_OFFSET)); return BlockId::FromBinary(data.dataOffset(ID_HEADER_OFFSET));
} }
uint64_t IntegrityBlockStore2::_readVersion(const Data &data) { uint64_t IntegrityBlockStore2::_readVersion(const Data &data) {
@ -108,57 +108,57 @@ IntegrityBlockStore2::IntegrityBlockStore2(unique_ref<BlockStore2> baseBlockStor
: _baseBlockStore(std::move(baseBlockStore)), _knownBlockVersions(integrityFilePath, myClientId), _noIntegrityChecks(noIntegrityChecks), _missingBlockIsIntegrityViolation(missingBlockIsIntegrityViolation), _integrityViolationDetected(false) { : _baseBlockStore(std::move(baseBlockStore)), _knownBlockVersions(integrityFilePath, myClientId), _noIntegrityChecks(noIntegrityChecks), _missingBlockIsIntegrityViolation(missingBlockIsIntegrityViolation), _integrityViolationDetected(false) {
} }
bool IntegrityBlockStore2::tryCreate(const Key &key, const Data &data) { bool IntegrityBlockStore2::tryCreate(const BlockId &blockId, const Data &data) {
_checkNoPastIntegrityViolations(); _checkNoPastIntegrityViolations();
uint64_t version = _knownBlockVersions.incrementVersion(key); uint64_t version = _knownBlockVersions.incrementVersion(blockId);
Data dataWithHeader = _prependHeaderToData(key, _knownBlockVersions.myClientId(), version, data); Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data);
return _baseBlockStore->tryCreate(key, dataWithHeader); return _baseBlockStore->tryCreate(blockId, dataWithHeader);
} }
bool IntegrityBlockStore2::remove(const Key &key) { bool IntegrityBlockStore2::remove(const BlockId &blockId) {
_checkNoPastIntegrityViolations(); _checkNoPastIntegrityViolations();
_knownBlockVersions.markBlockAsDeleted(key); _knownBlockVersions.markBlockAsDeleted(blockId);
return _baseBlockStore->remove(key); return _baseBlockStore->remove(blockId);
} }
optional<Data> IntegrityBlockStore2::load(const Key &key) const { optional<Data> IntegrityBlockStore2::load(const BlockId &blockId) const {
_checkNoPastIntegrityViolations(); _checkNoPastIntegrityViolations();
auto loaded = _baseBlockStore->load(key); auto loaded = _baseBlockStore->load(blockId);
if (none == loaded) { if (none == loaded) {
if (_missingBlockIsIntegrityViolation && _knownBlockVersions.blockShouldExist(key)) { if (_missingBlockIsIntegrityViolation && _knownBlockVersions.blockShouldExist(blockId)) {
integrityViolationDetected("A block that should exist wasn't found. Did an attacker delete it?"); integrityViolationDetected("A block that should exist wasn't found. Did an attacker delete it?");
} }
return optional<Data>(none); return optional<Data>(none);
} }
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
if (FORMAT_VERSION_HEADER_OLD == _readFormatHeader(*loaded)) { if (FORMAT_VERSION_HEADER_OLD == _readFormatHeader(*loaded)) {
Data migrated = _migrateBlock(key, *loaded); Data migrated = _migrateBlock(blockId, *loaded);
_checkHeader(key, migrated); _checkHeader(blockId, migrated);
Data content = _removeHeader(migrated); Data content = _removeHeader(migrated);
const_cast<IntegrityBlockStore2*>(this)->store(key, content); const_cast<IntegrityBlockStore2*>(this)->store(blockId, content);
return optional<Data>(_removeHeader(migrated)); return optional<Data>(_removeHeader(migrated));
} }
#endif #endif
_checkHeader(key, *loaded); _checkHeader(blockId, *loaded);
return optional<Data>(_removeHeader(*loaded)); return optional<Data>(_removeHeader(*loaded));
} }
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
Data IntegrityBlockStore2::_migrateBlock(const Key &key, const Data &data) { Data IntegrityBlockStore2::_migrateBlock(const BlockId &blockId, const Data &data) {
Data migrated(data.size() + Key::BINARY_LENGTH); Data migrated(data.size() + BlockId::BINARY_LENGTH);
std::memcpy(migrated.dataOffset(0), &FORMAT_VERSION_HEADER, sizeof(FORMAT_VERSION_HEADER)); std::memcpy(migrated.dataOffset(0), &FORMAT_VERSION_HEADER, sizeof(FORMAT_VERSION_HEADER));
std::memcpy(migrated.dataOffset(ID_HEADER_OFFSET), key.data().data(), Key::BINARY_LENGTH); std::memcpy(migrated.dataOffset(ID_HEADER_OFFSET), blockId.data().data(), BlockId::BINARY_LENGTH);
std::memcpy(migrated.dataOffset(ID_HEADER_OFFSET + Key::BINARY_LENGTH), data.dataOffset(sizeof(FORMAT_VERSION_HEADER)), data.size() - sizeof(FORMAT_VERSION_HEADER)); std::memcpy(migrated.dataOffset(ID_HEADER_OFFSET + BlockId::BINARY_LENGTH), data.dataOffset(sizeof(FORMAT_VERSION_HEADER)), data.size() - sizeof(FORMAT_VERSION_HEADER));
ASSERT(migrated.size() == sizeof(FORMAT_VERSION_HEADER) + Key::BINARY_LENGTH + (data.size() - sizeof(FORMAT_VERSION_HEADER)), "Wrong offset computation"); ASSERT(migrated.size() == sizeof(FORMAT_VERSION_HEADER) + BlockId::BINARY_LENGTH + (data.size() - sizeof(FORMAT_VERSION_HEADER)), "Wrong offset computation");
return migrated; return migrated;
} }
#endif #endif
void IntegrityBlockStore2::store(const Key &key, const Data &data) { void IntegrityBlockStore2::store(const BlockId &blockId, const Data &data) {
_checkNoPastIntegrityViolations(); _checkNoPastIntegrityViolations();
uint64_t version = _knownBlockVersions.incrementVersion(key); uint64_t version = _knownBlockVersions.incrementVersion(blockId);
Data dataWithHeader = _prependHeaderToData(key, _knownBlockVersions.myClientId(), version, data); Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data);
return _baseBlockStore->store(key, dataWithHeader); return _baseBlockStore->store(blockId, dataWithHeader);
} }
uint64_t IntegrityBlockStore2::numBlocks() const { uint64_t IntegrityBlockStore2::numBlocks() const {
@ -177,16 +177,16 @@ uint64_t IntegrityBlockStore2::blockSizeFromPhysicalBlockSize(uint64_t blockSize
return baseBlockSize - HEADER_LENGTH; return baseBlockSize - HEADER_LENGTH;
} }
void IntegrityBlockStore2::forEachBlock(std::function<void (const Key &)> callback) const { void IntegrityBlockStore2::forEachBlock(std::function<void (const BlockId &)> callback) const {
if (!_missingBlockIsIntegrityViolation) { if (!_missingBlockIsIntegrityViolation) {
return _baseBlockStore->forEachBlock(std::move(callback)); return _baseBlockStore->forEachBlock(std::move(callback));
} }
std::unordered_set<blockstore::Key> existingBlocks = _knownBlockVersions.existingBlocks(); std::unordered_set<blockstore::BlockId> existingBlocks = _knownBlockVersions.existingBlocks();
_baseBlockStore->forEachBlock([&existingBlocks, callback] (const Key &key) { _baseBlockStore->forEachBlock([&existingBlocks, callback] (const BlockId &blockId) {
callback(key); callback(blockId);
auto found = existingBlocks.find(key); auto found = existingBlocks.find(blockId);
if (found != existingBlocks.end()) { if (found != existingBlocks.end()) {
existingBlocks.erase(found); existingBlocks.erase(found);
} }
@ -200,23 +200,23 @@ void IntegrityBlockStore2::forEachBlock(std::function<void (const Key &)> callba
void IntegrityBlockStore2::migrateFromBlockstoreWithoutVersionNumbers(BlockStore2 *baseBlockStore, const boost::filesystem::path &integrityFilePath, uint32_t myClientId) { void IntegrityBlockStore2::migrateFromBlockstoreWithoutVersionNumbers(BlockStore2 *baseBlockStore, const boost::filesystem::path &integrityFilePath, uint32_t myClientId) {
std::cout << "Migrating file system for integrity features. Please don't interrupt this process. This can take a while..." << std::flush; std::cout << "Migrating file system for integrity features. Please don't interrupt this process. This can take a while..." << std::flush;
KnownBlockVersions knownBlockVersions(integrityFilePath, myClientId); KnownBlockVersions knownBlockVersions(integrityFilePath, myClientId);
baseBlockStore->forEachBlock([&baseBlockStore, &knownBlockVersions] (const Key &key) { baseBlockStore->forEachBlock([&baseBlockStore, &knownBlockVersions] (const BlockId &blockId) {
migrateBlockFromBlockstoreWithoutVersionNumbers(baseBlockStore, key, &knownBlockVersions); migrateBlockFromBlockstoreWithoutVersionNumbers(baseBlockStore, blockId, &knownBlockVersions);
}); });
std::cout << "done" << std::endl; std::cout << "done" << std::endl;
} }
void IntegrityBlockStore2::migrateBlockFromBlockstoreWithoutVersionNumbers(blockstore::BlockStore2* baseBlockStore, const blockstore::Key& key, KnownBlockVersions *knownBlockVersions) { void IntegrityBlockStore2::migrateBlockFromBlockstoreWithoutVersionNumbers(blockstore::BlockStore2* baseBlockStore, const blockstore::BlockId& blockId, KnownBlockVersions *knownBlockVersions) {
uint64_t version = knownBlockVersions->incrementVersion(key); uint64_t version = knownBlockVersions->incrementVersion(blockId);
auto data_ = baseBlockStore->load(key); auto data_ = baseBlockStore->load(blockId);
if (data_ == boost::none) { if (data_ == boost::none) {
LOG(WARN, "Block not found, but was returned from forEachBlock before"); LOG(WARN, "Block not found, but was returned from forEachBlock before");
return; return;
} }
cpputils::Data data = std::move(*data_); cpputils::Data data = std::move(*data_);
cpputils::Data dataWithHeader = _prependHeaderToData(key, knownBlockVersions->myClientId(), version, std::move(data)); cpputils::Data dataWithHeader = _prependHeaderToData(blockId, knownBlockVersions->myClientId(), version, std::move(data));
baseBlockStore->store(key, std::move(dataWithHeader)); baseBlockStore->store(blockId, std::move(dataWithHeader));
} }
#endif #endif

View File

@ -18,14 +18,14 @@ class IntegrityBlockStore2 final: public BlockStore2 {
public: public:
IntegrityBlockStore2(cpputils::unique_ref<BlockStore2> baseBlockStore, const boost::filesystem::path &integrityFilePath, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation); IntegrityBlockStore2(cpputils::unique_ref<BlockStore2> baseBlockStore, const boost::filesystem::path &integrityFilePath, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
bool tryCreate(const Key &key, const cpputils::Data &data) override; bool tryCreate(const BlockId &blockId, const cpputils::Data &data) override;
bool remove(const Key &key) override; bool remove(const BlockId &blockId) override;
boost::optional<cpputils::Data> load(const Key &key) const override; boost::optional<cpputils::Data> load(const BlockId &blockId) const override;
void store(const Key &key, const cpputils::Data &data) override; void store(const BlockId &blockId, const cpputils::Data &data) override;
uint64_t numBlocks() const override; uint64_t numBlocks() const override;
uint64_t estimateNumFreeBytes() const override; uint64_t estimateNumFreeBytes() const override;
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
void forEachBlock(std::function<void (const Key &)> callback) const override; void forEachBlock(std::function<void (const BlockId &)> callback) const override;
private: private:
// This format version is prepended to blocks to allow future versions to have compatibility. // This format version is prepended to blocks to allow future versions to have compatibility.
@ -37,28 +37,28 @@ private:
public: public:
static constexpr uint64_t VERSION_ZERO = 0; static constexpr uint64_t VERSION_ZERO = 0;
static constexpr unsigned int ID_HEADER_OFFSET = sizeof(FORMAT_VERSION_HEADER); static constexpr unsigned int ID_HEADER_OFFSET = sizeof(FORMAT_VERSION_HEADER);
static constexpr unsigned int CLIENTID_HEADER_OFFSET = ID_HEADER_OFFSET + Key::BINARY_LENGTH; static constexpr unsigned int CLIENTID_HEADER_OFFSET = ID_HEADER_OFFSET + BlockId::BINARY_LENGTH;
static constexpr unsigned int VERSION_HEADER_OFFSET = CLIENTID_HEADER_OFFSET + sizeof(uint32_t); static constexpr unsigned int VERSION_HEADER_OFFSET = CLIENTID_HEADER_OFFSET + sizeof(uint32_t);
static constexpr unsigned int HEADER_LENGTH = VERSION_HEADER_OFFSET + sizeof(VERSION_ZERO); static constexpr unsigned int HEADER_LENGTH = VERSION_HEADER_OFFSET + sizeof(VERSION_ZERO);
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
static void migrateFromBlockstoreWithoutVersionNumbers(BlockStore2 *baseBlockStore, const boost::filesystem::path &integrityFilePath, uint32_t myClientId); static void migrateFromBlockstoreWithoutVersionNumbers(BlockStore2 *baseBlockStore, const boost::filesystem::path &integrityFilePath, uint32_t myClientId);
static void migrateBlockFromBlockstoreWithoutVersionNumbers(BlockStore2* baseBlockStore, const blockstore::Key& key, KnownBlockVersions *knownBlockVersions); static void migrateBlockFromBlockstoreWithoutVersionNumbers(BlockStore2* baseBlockStore, const blockstore::BlockId &blockId, KnownBlockVersions *knownBlockVersions);
#endif #endif
private: private:
static cpputils::Data _prependHeaderToData(const Key& key, uint32_t myClientId, uint64_t version, const cpputils::Data &data); static cpputils::Data _prependHeaderToData(const BlockId &blockId, uint32_t myClientId, uint64_t version, const cpputils::Data &data);
void _checkHeader(const Key &key, const cpputils::Data &data) const; void _checkHeader(const BlockId &blockId, const cpputils::Data &data) const;
void _checkFormatHeader(const cpputils::Data &data) const; void _checkFormatHeader(const cpputils::Data &data) const;
void _checkIdHeader(const Key &expectedKey, const cpputils::Data &data) const; void _checkIdHeader(const BlockId &expectedBlockId, const cpputils::Data &data) const;
void _checkVersionHeader(const Key &key, const cpputils::Data &data) const; void _checkVersionHeader(const BlockId &blockId, const cpputils::Data &data) const;
static uint16_t _readFormatHeader(const cpputils::Data &data); static uint16_t _readFormatHeader(const cpputils::Data &data);
static uint32_t _readClientId(const cpputils::Data &data); static uint32_t _readClientId(const cpputils::Data &data);
static Key _readBlockId(const cpputils::Data &data); static BlockId _readBlockId(const cpputils::Data &data);
static uint64_t _readVersion(const cpputils::Data &data); static uint64_t _readVersion(const cpputils::Data &data);
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
static cpputils::Data _migrateBlock(const Key &key, const cpputils::Data &data); static cpputils::Data _migrateBlock(const BlockId &blockId, const cpputils::Data &data);
#endif #endif
static cpputils::Data _removeHeader(const cpputils::Data &data); static cpputils::Data _removeHeader(const cpputils::Data &data);
void _checkNoPastIntegrityViolations() const; void _checkNoPastIntegrityViolations() const;

View File

@ -47,22 +47,22 @@ KnownBlockVersions::~KnownBlockVersions() {
} }
} }
bool KnownBlockVersions::checkAndUpdateVersion(uint32_t clientId, const Key &key, uint64_t version) { bool KnownBlockVersions::checkAndUpdateVersion(uint32_t clientId, const BlockId &blockId, uint64_t version) {
unique_lock<mutex> lock(_mutex); unique_lock<mutex> lock(_mutex);
ASSERT(clientId != CLIENT_ID_FOR_DELETED_BLOCK, "This is not a valid client id"); ASSERT(clientId != CLIENT_ID_FOR_DELETED_BLOCK, "This is not a valid client id");
ASSERT(version > 0, "Version has to be >0"); // Otherwise we wouldn't handle notexisting entries correctly. ASSERT(version > 0, "Version has to be >0"); // Otherwise we wouldn't handle notexisting entries correctly.
ASSERT(_valid, "Object not valid due to a std::move"); ASSERT(_valid, "Object not valid due to a std::move");
uint64_t &found = _knownVersions[{clientId, key}]; // If the entry doesn't exist, this creates it with value 0. uint64_t &found = _knownVersions[{clientId, blockId}]; // If the entry doesn't exist, this creates it with value 0.
if (found > version) { if (found > version) {
// This client already published a newer block version. Rollbacks are not allowed. // This client already published a newer block version. Rollbacks are not allowed.
return false; return false;
} }
uint32_t &lastUpdateClientId = _lastUpdateClientId[key]; // If entry doesn't exist, this creates it with value 0. However, in this case, found == 0 (and version > 0), which means found != version. uint32_t &lastUpdateClientId = _lastUpdateClientId[blockId]; // If entry doesn't exist, this creates it with value 0. However, in this case, found == 0 (and version > 0), which means found != version.
if (found == version && lastUpdateClientId != clientId) { if (found == version && lastUpdateClientId != clientId) {
// This is a roll back to the "newest" block of client [clientId], which was since then superseded by a version from client _lastUpdateClientId[key]. // This is a roll back to the "newest" block of client [clientId], which was since then superseded by a version from client _lastUpdateClientId[blockId].
// This is not allowed. // This is not allowed.
return false; return false;
} }
@ -72,16 +72,16 @@ bool KnownBlockVersions::checkAndUpdateVersion(uint32_t clientId, const Key &key
return true; return true;
} }
uint64_t KnownBlockVersions::incrementVersion(const Key &key) { uint64_t KnownBlockVersions::incrementVersion(const BlockId &blockId) {
unique_lock<mutex> lock(_mutex); unique_lock<mutex> lock(_mutex);
uint64_t &found = _knownVersions[{_myClientId, key}]; // If the entry doesn't exist, this creates it with value 0. uint64_t &found = _knownVersions[{_myClientId, blockId}]; // If the entry doesn't exist, this creates it with value 0.
uint64_t newVersion = found + 1; uint64_t newVersion = found + 1;
if (newVersion == std::numeric_limits<uint64_t>::max()) { if (newVersion == std::numeric_limits<uint64_t>::max()) {
// It's *very* unlikely we ever run out of version numbers in 64bit...but just to be sure... // It's *very* unlikely we ever run out of version numbers in 64bit...but just to be sure...
throw std::runtime_error("Version overflow"); throw std::runtime_error("Version overflow");
} }
found = newVersion; found = newVersion;
_lastUpdateClientId[key] = _myClientId; _lastUpdateClientId[blockId] = _myClientId;
return found; return found;
} }
@ -106,8 +106,8 @@ void KnownBlockVersions::_loadStateFile() {
void KnownBlockVersions::_saveStateFile() const { void KnownBlockVersions::_saveStateFile() const {
Serializer serializer( Serializer serializer(
Serializer::StringSize(HEADER) + Serializer::StringSize(HEADER) +
sizeof(uint64_t) + _knownVersions.size() * (sizeof(uint32_t) + Key::BINARY_LENGTH + sizeof(uint64_t)) + sizeof(uint64_t) + _knownVersions.size() * (sizeof(uint32_t) + BlockId::BINARY_LENGTH + sizeof(uint64_t)) +
sizeof(uint64_t) + _lastUpdateClientId.size() * (Key::BINARY_LENGTH + sizeof(uint32_t))); sizeof(uint64_t) + _lastUpdateClientId.size() * (BlockId::BINARY_LENGTH + sizeof(uint32_t)));
serializer.writeString(HEADER); serializer.writeString(HEADER);
_serializeKnownVersions(&serializer); _serializeKnownVersions(&serializer);
_serializeLastUpdateClientIds(&serializer); _serializeLastUpdateClientIds(&serializer);
@ -134,17 +134,17 @@ void KnownBlockVersions::_serializeKnownVersions(Serializer *serializer) const {
} }
} }
pair<ClientIdAndBlockKey, uint64_t> KnownBlockVersions::_deserializeKnownVersionsEntry(Deserializer *deserializer) { pair<ClientIdAndBlockId, uint64_t> KnownBlockVersions::_deserializeKnownVersionsEntry(Deserializer *deserializer) {
uint32_t clientId = deserializer->readUint32(); uint32_t clientId = deserializer->readUint32();
Key blockKey(deserializer->readFixedSizeData<Key::BINARY_LENGTH>()); BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>());
uint64_t version = deserializer->readUint64(); uint64_t version = deserializer->readUint64();
return {{clientId, blockKey}, version}; return {{clientId, blockId}, version};
}; };
void KnownBlockVersions::_serializeKnownVersionsEntry(Serializer *serializer, const pair<ClientIdAndBlockKey, uint64_t> &entry) { void KnownBlockVersions::_serializeKnownVersionsEntry(Serializer *serializer, const pair<ClientIdAndBlockId, uint64_t> &entry) {
serializer->writeUint32(entry.first.clientId); serializer->writeUint32(entry.first.clientId);
serializer->writeFixedSizeData<Key::BINARY_LENGTH>(entry.first.blockKey.data()); serializer->writeFixedSizeData<BlockId::BINARY_LENGTH>(entry.first.blockId.data());
serializer->writeUint64(entry.second); serializer->writeUint64(entry.second);
} }
@ -167,15 +167,15 @@ void KnownBlockVersions::_serializeLastUpdateClientIds(Serializer *serializer) c
} }
} }
pair<Key, uint32_t> KnownBlockVersions::_deserializeLastUpdateClientIdEntry(Deserializer *deserializer) { pair<BlockId, uint32_t> KnownBlockVersions::_deserializeLastUpdateClientIdEntry(Deserializer *deserializer) {
Key blockKey(deserializer->readFixedSizeData<Key::BINARY_LENGTH>()); BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>());
uint32_t clientId = deserializer->readUint32(); uint32_t clientId = deserializer->readUint32();
return {blockKey, clientId}; return {blockId, clientId};
}; };
void KnownBlockVersions::_serializeLastUpdateClientIdEntry(Serializer *serializer, const pair<Key, uint32_t> &entry) { void KnownBlockVersions::_serializeLastUpdateClientIdEntry(Serializer *serializer, const pair<BlockId, uint32_t> &entry) {
serializer->writeFixedSizeData<Key::BINARY_LENGTH>(entry.first.data()); serializer->writeFixedSizeData<BlockId::BINARY_LENGTH>(entry.first.data());
serializer->writeUint32(entry.second); serializer->writeUint32(entry.second);
} }
@ -183,17 +183,17 @@ uint32_t KnownBlockVersions::myClientId() const {
return _myClientId; return _myClientId;
} }
uint64_t KnownBlockVersions::getBlockVersion(uint32_t clientId, const Key &key) const { uint64_t KnownBlockVersions::getBlockVersion(uint32_t clientId, const BlockId &blockId) const {
unique_lock<mutex> lock(_mutex); unique_lock<mutex> lock(_mutex);
return _knownVersions.at({clientId, key}); return _knownVersions.at({clientId, blockId});
} }
void KnownBlockVersions::markBlockAsDeleted(const Key &key) { void KnownBlockVersions::markBlockAsDeleted(const BlockId &blockId) {
_lastUpdateClientId[key] = CLIENT_ID_FOR_DELETED_BLOCK; _lastUpdateClientId[blockId] = CLIENT_ID_FOR_DELETED_BLOCK;
} }
bool KnownBlockVersions::blockShouldExist(const Key &key) const { bool KnownBlockVersions::blockShouldExist(const BlockId &blockId) const {
auto found = _lastUpdateClientId.find(key); auto found = _lastUpdateClientId.find(blockId);
if (found == _lastUpdateClientId.end()) { if (found == _lastUpdateClientId.end()) {
// We've never seen (i.e. loaded) this block. So we can't say it has to exist. // We've never seen (i.e. loaded) this block. So we can't say it has to exist.
return false; return false;
@ -202,8 +202,8 @@ bool KnownBlockVersions::blockShouldExist(const Key &key) const {
return found->second != CLIENT_ID_FOR_DELETED_BLOCK; return found->second != CLIENT_ID_FOR_DELETED_BLOCK;
} }
std::unordered_set<Key> KnownBlockVersions::existingBlocks() const { std::unordered_set<BlockId> KnownBlockVersions::existingBlocks() const {
std::unordered_set<Key> result; std::unordered_set<BlockId> result;
for (const auto &entry : _lastUpdateClientId) { for (const auto &entry : _lastUpdateClientId) {
if (entry.second != CLIENT_ID_FOR_DELETED_BLOCK) { if (entry.second != CLIENT_ID_FOR_DELETED_BLOCK) {
result.insert(entry.first); result.insert(entry.first);

View File

@ -3,10 +3,10 @@
#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_INTEGRITY_KNOWNBLOCKVERSIONS_H_ #define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_INTEGRITY_KNOWNBLOCKVERSIONS_H_
#include <cpp-utils/macros.h> #include <cpp-utils/macros.h>
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include "ClientIdAndBlockKey.h" #include "ClientIdAndBlockId.h"
#include <cpp-utils/data/Deserializer.h> #include <cpp-utils/data/Deserializer.h>
#include <cpp-utils/data/Serializer.h> #include <cpp-utils/data/Serializer.h>
#include <mutex> #include <mutex>
@ -22,16 +22,16 @@ namespace blockstore {
~KnownBlockVersions(); ~KnownBlockVersions();
__attribute__((warn_unused_result)) __attribute__((warn_unused_result))
bool checkAndUpdateVersion(uint32_t clientId, const Key &key, uint64_t version); bool checkAndUpdateVersion(uint32_t clientId, const BlockId &blockId, uint64_t version);
uint64_t incrementVersion(const Key &key); uint64_t incrementVersion(const BlockId &blockId);
void markBlockAsDeleted(const Key &key); void markBlockAsDeleted(const BlockId &blockId);
bool blockShouldExist(const Key &key) const; bool blockShouldExist(const BlockId &blockId) const;
std::unordered_set<Key> existingBlocks() const; std::unordered_set<BlockId> existingBlocks() const;
uint64_t getBlockVersion(uint32_t clientId, const Key &key) const; uint64_t getBlockVersion(uint32_t clientId, const BlockId &blockId) const;
uint32_t myClientId() const; uint32_t myClientId() const;
const boost::filesystem::path &path() const; const boost::filesystem::path &path() const;
@ -39,8 +39,8 @@ namespace blockstore {
static constexpr uint32_t CLIENT_ID_FOR_DELETED_BLOCK = 0; static constexpr uint32_t CLIENT_ID_FOR_DELETED_BLOCK = 0;
private: private:
std::unordered_map<ClientIdAndBlockKey, uint64_t> _knownVersions; std::unordered_map<ClientIdAndBlockId, uint64_t> _knownVersions;
std::unordered_map<Key, uint32_t> _lastUpdateClientId; // The client who last updated the block std::unordered_map<BlockId, uint32_t> _lastUpdateClientId; // The client who last updated the block
boost::filesystem::path _stateFilePath; boost::filesystem::path _stateFilePath;
uint32_t _myClientId; uint32_t _myClientId;
@ -55,14 +55,14 @@ namespace blockstore {
void _deserializeKnownVersions(cpputils::Deserializer *deserializer); void _deserializeKnownVersions(cpputils::Deserializer *deserializer);
void _serializeKnownVersions(cpputils::Serializer *serializer) const; void _serializeKnownVersions(cpputils::Serializer *serializer) const;
static std::pair<ClientIdAndBlockKey, uint64_t> _deserializeKnownVersionsEntry(cpputils::Deserializer *deserializer); static std::pair<ClientIdAndBlockId, uint64_t> _deserializeKnownVersionsEntry(cpputils::Deserializer *deserializer);
static void _serializeKnownVersionsEntry(cpputils::Serializer *serializer, const std::pair<ClientIdAndBlockKey, uint64_t> &entry); static void _serializeKnownVersionsEntry(cpputils::Serializer *serializer, const std::pair<ClientIdAndBlockId, uint64_t> &entry);
void _deserializeLastUpdateClientIds(cpputils::Deserializer *deserializer); void _deserializeLastUpdateClientIds(cpputils::Deserializer *deserializer);
void _serializeLastUpdateClientIds(cpputils::Serializer *serializer) const; void _serializeLastUpdateClientIds(cpputils::Serializer *serializer) const;
static std::pair<Key, uint32_t> _deserializeLastUpdateClientIdEntry(cpputils::Deserializer *deserializer); static std::pair<BlockId, uint32_t> _deserializeLastUpdateClientIdEntry(cpputils::Deserializer *deserializer);
static void _serializeLastUpdateClientIdEntry(cpputils::Serializer *serializer, const std::pair<Key, uint32_t> &entry); static void _serializeLastUpdateClientIdEntry(cpputils::Serializer *serializer, const std::pair<BlockId, uint32_t> &entry);
DISALLOW_COPY_AND_ASSIGN(KnownBlockVersions); DISALLOW_COPY_AND_ASSIGN(KnownBlockVersions);
}; };

View File

@ -12,30 +12,30 @@ using std::mutex;
namespace blockstore { namespace blockstore {
namespace lowtohighlevel { namespace lowtohighlevel {
optional<unique_ref<LowToHighLevelBlock>> LowToHighLevelBlock::TryCreateNew(BlockStore2 *baseBlockStore, const Key &key, Data data) { optional<unique_ref<LowToHighLevelBlock>> LowToHighLevelBlock::TryCreateNew(BlockStore2 *baseBlockStore, const BlockId &blockId, Data data) {
bool success = baseBlockStore->tryCreate(key, data); bool success = baseBlockStore->tryCreate(blockId, data);
if (!success) { if (!success) {
return none; return none;
} }
return make_unique_ref<LowToHighLevelBlock>(key, std::move(data), baseBlockStore); return make_unique_ref<LowToHighLevelBlock>(blockId, std::move(data), baseBlockStore);
} }
unique_ref<LowToHighLevelBlock> LowToHighLevelBlock::Overwrite(BlockStore2 *baseBlockStore, const Key &key, Data data) { unique_ref<LowToHighLevelBlock> LowToHighLevelBlock::Overwrite(BlockStore2 *baseBlockStore, const BlockId &blockId, Data data) {
baseBlockStore->store(key, data); // TODO Does it make sense to not store here, but only write back in the destructor of LowToHighLevelBlock? Also: What about tryCreate? baseBlockStore->store(blockId, data); // TODO Does it make sense to not store here, but only write back in the destructor of LowToHighLevelBlock? Also: What about tryCreate?
return make_unique_ref<LowToHighLevelBlock>(key, std::move(data), baseBlockStore); return make_unique_ref<LowToHighLevelBlock>(blockId, std::move(data), baseBlockStore);
} }
optional<unique_ref<LowToHighLevelBlock>> LowToHighLevelBlock::Load(BlockStore2 *baseBlockStore, const Key &key) { optional<unique_ref<LowToHighLevelBlock>> LowToHighLevelBlock::Load(BlockStore2 *baseBlockStore, const BlockId &blockId) {
optional<Data> loadedData = baseBlockStore->load(key); optional<Data> loadedData = baseBlockStore->load(blockId);
if (loadedData == none) { if (loadedData == none) {
return none; return none;
} }
return make_unique_ref<LowToHighLevelBlock>(key, std::move(*loadedData), baseBlockStore); return make_unique_ref<LowToHighLevelBlock>(blockId, std::move(*loadedData), baseBlockStore);
} }
LowToHighLevelBlock::LowToHighLevelBlock(const Key& key, Data data, BlockStore2 *baseBlockStore) LowToHighLevelBlock::LowToHighLevelBlock(const BlockId &blockId, Data data, BlockStore2 *baseBlockStore)
:Block(key), :Block(blockId),
_baseBlockStore(baseBlockStore), _baseBlockStore(baseBlockStore),
_data(std::move(data)), _data(std::move(data)),
_dataChanged(false), _dataChanged(false),
@ -73,7 +73,7 @@ void LowToHighLevelBlock::resize(size_t newSize) {
void LowToHighLevelBlock::_storeToBaseBlock() { void LowToHighLevelBlock::_storeToBaseBlock() {
if (_dataChanged) { if (_dataChanged) {
_baseBlockStore->store(key(), _data); _baseBlockStore->store(blockId(), _data);
_dataChanged = false; _dataChanged = false;
} }
} }

View File

@ -23,11 +23,11 @@ namespace lowtohighlevel {
class LowToHighLevelBlock final: public Block { class LowToHighLevelBlock final: public Block {
public: public:
static boost::optional<cpputils::unique_ref<LowToHighLevelBlock>> TryCreateNew(BlockStore2 *baseBlockStore, const Key &key, cpputils::Data data); static boost::optional<cpputils::unique_ref<LowToHighLevelBlock>> TryCreateNew(BlockStore2 *baseBlockStore, const BlockId &blockId, cpputils::Data data);
static cpputils::unique_ref<LowToHighLevelBlock> Overwrite(BlockStore2 *baseBlockStore, const Key &key, cpputils::Data data); static cpputils::unique_ref<LowToHighLevelBlock> Overwrite(BlockStore2 *baseBlockStore, const BlockId &blockId, cpputils::Data data);
static boost::optional<cpputils::unique_ref<LowToHighLevelBlock>> Load(BlockStore2 *baseBlockStore, const Key &key); static boost::optional<cpputils::unique_ref<LowToHighLevelBlock>> Load(BlockStore2 *baseBlockStore, const BlockId &blockId);
LowToHighLevelBlock(const Key& key, cpputils::Data data, BlockStore2 *baseBlockStore); LowToHighLevelBlock(const BlockId &blockId, cpputils::Data data, BlockStore2 *baseBlockStore);
~LowToHighLevelBlock(); ~LowToHighLevelBlock();
const void *data() const override; const void *data() const override;

View File

@ -17,38 +17,38 @@ LowToHighLevelBlockStore::LowToHighLevelBlockStore(unique_ref<BlockStore2> baseB
: _baseBlockStore(std::move(baseBlockStore)) { : _baseBlockStore(std::move(baseBlockStore)) {
} }
Key LowToHighLevelBlockStore::createKey() { BlockId LowToHighLevelBlockStore::createBlockId() {
// TODO Is this the right way? // TODO Is this the right way?
return Key::Random(); return BlockId::Random();
} }
optional<unique_ref<Block>> LowToHighLevelBlockStore::tryCreate(const Key &key, Data data) { optional<unique_ref<Block>> LowToHighLevelBlockStore::tryCreate(const BlockId &blockId, Data data) {
//TODO Easier implementation? This is only so complicated because of the cast LowToHighLevelBlock -> Block //TODO Easier implementation? This is only so complicated because of the cast LowToHighLevelBlock -> Block
auto result = LowToHighLevelBlock::TryCreateNew(_baseBlockStore.get(), key, std::move(data)); auto result = LowToHighLevelBlock::TryCreateNew(_baseBlockStore.get(), blockId, std::move(data));
if (result == none) { if (result == none) {
return none; return none;
} }
return unique_ref<Block>(std::move(*result)); return unique_ref<Block>(std::move(*result));
} }
unique_ref<Block> LowToHighLevelBlockStore::overwrite(const Key &key, Data data) { unique_ref<Block> LowToHighLevelBlockStore::overwrite(const BlockId &blockId, Data data) {
return unique_ref<Block>( return unique_ref<Block>(
LowToHighLevelBlock::Overwrite(_baseBlockStore.get(), key, std::move(data)) LowToHighLevelBlock::Overwrite(_baseBlockStore.get(), blockId, std::move(data))
); );
} }
optional<unique_ref<Block>> LowToHighLevelBlockStore::load(const Key &key) { optional<unique_ref<Block>> LowToHighLevelBlockStore::load(const BlockId &blockId) {
auto result = optional<unique_ref<Block>>(LowToHighLevelBlock::Load(_baseBlockStore.get(), key)); auto result = optional<unique_ref<Block>>(LowToHighLevelBlock::Load(_baseBlockStore.get(), blockId));
if (result == none) { if (result == none) {
return none; return none;
} }
return unique_ref<Block>(std::move(*result)); return unique_ref<Block>(std::move(*result));
} }
void LowToHighLevelBlockStore::remove(const Key &key) { void LowToHighLevelBlockStore::remove(const BlockId &blockId) {
bool success = _baseBlockStore->remove(key); bool success = _baseBlockStore->remove(blockId);
if (!success) { if (!success) {
throw std::runtime_error("Couldn't delete block with id " + key.ToString()); throw std::runtime_error("Couldn't delete block with id " + blockId.ToString());
} }
} }
@ -64,7 +64,7 @@ uint64_t LowToHighLevelBlockStore::blockSizeFromPhysicalBlockSize(uint64_t block
return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize); return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize);
} }
void LowToHighLevelBlockStore::forEachBlock(std::function<void (const Key &)> callback) const { void LowToHighLevelBlockStore::forEachBlock(std::function<void (const BlockId &)> callback) const {
_baseBlockStore->forEachBlock(std::move(callback)); _baseBlockStore->forEachBlock(std::move(callback));
} }

View File

@ -20,15 +20,15 @@ class LowToHighLevelBlockStore final: public BlockStore {
public: public:
LowToHighLevelBlockStore(cpputils::unique_ref<BlockStore2> baseBlockStore); LowToHighLevelBlockStore(cpputils::unique_ref<BlockStore2> baseBlockStore);
Key createKey() override; BlockId createBlockId() override;
boost::optional<cpputils::unique_ref<Block>> tryCreate(const Key &key, cpputils::Data data) override; boost::optional<cpputils::unique_ref<Block>> tryCreate(const BlockId &blockId, cpputils::Data data) override;
cpputils::unique_ref<Block> overwrite(const blockstore::Key &key, cpputils::Data data) override; cpputils::unique_ref<Block> overwrite(const blockstore::BlockId &blockId, cpputils::Data data) override;
boost::optional<cpputils::unique_ref<Block>> load(const Key &key) override; boost::optional<cpputils::unique_ref<Block>> load(const BlockId &blockId) override;
void remove(const Key &key) override; void remove(const BlockId &blockId) override;
uint64_t numBlocks() const override; uint64_t numBlocks() const override;
uint64_t estimateNumFreeBytes() const override; uint64_t estimateNumFreeBytes() const override;
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
void forEachBlock(std::function<void (const Key &)> callback) const override; void forEachBlock(std::function<void (const BlockId &)> callback) const override;
private: private:
cpputils::unique_ref<BlockStore2> _baseBlockStore; cpputils::unique_ref<BlockStore2> _baseBlockStore;

View File

@ -5,12 +5,12 @@ namespace blockstore {
namespace mock { namespace mock {
void MockBlock::write(const void *source, uint64_t offset, uint64_t size) { void MockBlock::write(const void *source, uint64_t offset, uint64_t size) {
_blockStore->_increaseNumWrittenBlocks(key()); _blockStore->_increaseNumWrittenBlocks(blockId());
return _baseBlock->write(source, offset, size); return _baseBlock->write(source, offset, size);
} }
void MockBlock::resize(size_t newSize) { void MockBlock::resize(size_t newSize) {
_blockStore->_increaseNumResizedBlocks(key()); _blockStore->_increaseNumResizedBlocks(blockId());
return _baseBlock->resize(newSize); return _baseBlock->resize(newSize);
} }

View File

@ -13,7 +13,7 @@ namespace blockstore {
class MockBlock final : public blockstore::Block { class MockBlock final : public blockstore::Block {
public: public:
MockBlock(cpputils::unique_ref<blockstore::Block> baseBlock, MockBlockStore *blockStore) MockBlock(cpputils::unique_ref<blockstore::Block> baseBlock, MockBlockStore *blockStore)
:Block(baseBlock->key()), _baseBlock(std::move(baseBlock)), _blockStore(blockStore) { :Block(baseBlock->blockId()), _baseBlock(std::move(baseBlock)), _blockStore(blockStore) {
} }
const void *data() const override { const void *data() const override {

View File

@ -19,36 +19,36 @@ namespace blockstore {
: _mutex(), _baseBlockStore(std::move(baseBlockStore)), _loadedBlocks(), _createdBlocks(0), _writtenBlocks(), _resizedBlocks(), _removedBlocks() { : _mutex(), _baseBlockStore(std::move(baseBlockStore)), _loadedBlocks(), _createdBlocks(0), _writtenBlocks(), _resizedBlocks(), _removedBlocks() {
} }
Key createKey() override { BlockId createBlockId() override {
return _baseBlockStore->createKey(); return _baseBlockStore->createBlockId();
} }
boost::optional<cpputils::unique_ref<Block>> tryCreate(const Key &key, cpputils::Data data) override { boost::optional<cpputils::unique_ref<Block>> tryCreate(const BlockId &blockId, cpputils::Data data) override {
_increaseNumCreatedBlocks(); _increaseNumCreatedBlocks();
auto base = _baseBlockStore->tryCreate(key, std::move(data)); auto base = _baseBlockStore->tryCreate(blockId, std::move(data));
if (base == boost::none) { if (base == boost::none) {
return boost::none; return boost::none;
} }
return boost::optional<cpputils::unique_ref<Block>>(cpputils::make_unique_ref<MockBlock>(std::move(*base), this)); return boost::optional<cpputils::unique_ref<Block>>(cpputils::make_unique_ref<MockBlock>(std::move(*base), this));
} }
boost::optional<cpputils::unique_ref<Block>> load(const Key &key) override { boost::optional<cpputils::unique_ref<Block>> load(const BlockId &blockId) override {
_increaseNumLoadedBlocks(key); _increaseNumLoadedBlocks(blockId);
auto base = _baseBlockStore->load(key); auto base = _baseBlockStore->load(blockId);
if (base == boost::none) { if (base == boost::none) {
return boost::none; return boost::none;
} }
return boost::optional<cpputils::unique_ref<Block>>(cpputils::make_unique_ref<MockBlock>(std::move(*base), this)); return boost::optional<cpputils::unique_ref<Block>>(cpputils::make_unique_ref<MockBlock>(std::move(*base), this));
} }
cpputils::unique_ref<Block> overwrite(const Key &key, cpputils::Data data) override { cpputils::unique_ref<Block> overwrite(const BlockId &blockId, cpputils::Data data) override {
_increaseNumWrittenBlocks(key); _increaseNumWrittenBlocks(blockId);
return _baseBlockStore->overwrite(key, std::move(data)); return _baseBlockStore->overwrite(blockId, std::move(data));
} }
void remove(const Key &key) override { void remove(const BlockId &blockId) override {
_increaseNumRemovedBlocks(key); _increaseNumRemovedBlocks(blockId);
return _baseBlockStore->remove(key); return _baseBlockStore->remove(blockId);
} }
uint64_t numBlocks() const override { uint64_t numBlocks() const override {
@ -63,12 +63,12 @@ namespace blockstore {
return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize); return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize);
} }
void forEachBlock(std::function<void(const Key &)> callback) const override { void forEachBlock(std::function<void(const BlockId &)> callback) const override {
return _baseBlockStore->forEachBlock(callback); return _baseBlockStore->forEachBlock(callback);
} }
void remove(cpputils::unique_ref<Block> block) override { void remove(cpputils::unique_ref<Block> block) override {
_increaseNumRemovedBlocks(block->key()); _increaseNumRemovedBlocks(block->blockId());
auto mockBlock = cpputils::dynamic_pointer_move<MockBlock>(block); auto mockBlock = cpputils::dynamic_pointer_move<MockBlock>(block);
ASSERT(mockBlock != boost::none, "Wrong block type"); ASSERT(mockBlock != boost::none, "Wrong block type");
return _baseBlockStore->remove((*mockBlock)->releaseBaseBlock()); return _baseBlockStore->remove((*mockBlock)->releaseBaseBlock());
@ -86,25 +86,25 @@ namespace blockstore {
return _createdBlocks; return _createdBlocks;
} }
const std::vector<Key> &loadedBlocks() const { const std::vector<BlockId> &loadedBlocks() const {
return _loadedBlocks; return _loadedBlocks;
} }
const std::vector<Key> &removedBlocks() const { const std::vector<BlockId> &removedBlocks() const {
return _removedBlocks; return _removedBlocks;
} }
const std::vector<Key> &resizedBlocks() const { const std::vector<BlockId> &resizedBlocks() const {
return _resizedBlocks; return _resizedBlocks;
} }
const std::vector<Key> &writtenBlocks() const { const std::vector<BlockId> &writtenBlocks() const {
return _writtenBlocks; return _writtenBlocks;
} }
std::vector<Key> distinctWrittenBlocks() const { std::vector<BlockId> distinctWrittenBlocks() const {
std::vector<Key> result(_writtenBlocks); std::vector<BlockId> result(_writtenBlocks);
std::sort(result.begin(), result.end(), [](const Key &lhs, const Key &rhs) { std::sort(result.begin(), result.end(), [](const BlockId &lhs, const BlockId &rhs) {
return std::memcmp(lhs.data().data(), rhs.data().data(), lhs.BINARY_LENGTH) < 0; return std::memcmp(lhs.data().data(), rhs.data().data(), lhs.BINARY_LENGTH) < 0;
}); });
result.erase(std::unique(result.begin(), result.end() ), result.end()); result.erase(std::unique(result.begin(), result.end() ), result.end());
@ -117,24 +117,24 @@ namespace blockstore {
_createdBlocks += 1; _createdBlocks += 1;
} }
void _increaseNumLoadedBlocks(const Key &key) { void _increaseNumLoadedBlocks(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_loadedBlocks.push_back(key); _loadedBlocks.push_back(blockId);
} }
void _increaseNumRemovedBlocks(const Key &key) { void _increaseNumRemovedBlocks(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_removedBlocks.push_back(key); _removedBlocks.push_back(blockId);
} }
void _increaseNumResizedBlocks(const Key &key) { void _increaseNumResizedBlocks(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_resizedBlocks.push_back(key); _resizedBlocks.push_back(blockId);
} }
void _increaseNumWrittenBlocks(const Key &key) { void _increaseNumWrittenBlocks(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_writtenBlocks.push_back(key); _writtenBlocks.push_back(blockId);
} }
friend class MockBlock; friend class MockBlock;
@ -142,11 +142,11 @@ namespace blockstore {
std::mutex _mutex; std::mutex _mutex;
cpputils::unique_ref<BlockStore> _baseBlockStore; cpputils::unique_ref<BlockStore> _baseBlockStore;
std::vector<Key> _loadedBlocks; std::vector<BlockId> _loadedBlocks;
uint64_t _createdBlocks; uint64_t _createdBlocks;
std::vector<Key> _writtenBlocks; std::vector<BlockId> _writtenBlocks;
std::vector<Key> _resizedBlocks; std::vector<BlockId> _resizedBlocks;
std::vector<Key> _removedBlocks; std::vector<BlockId> _removedBlocks;
DISALLOW_COPY_AND_ASSIGN(MockBlockStore); DISALLOW_COPY_AND_ASSIGN(MockBlockStore);
}; };

View File

@ -12,9 +12,9 @@ namespace ondisk {
const string OnDiskBlockStore2::FORMAT_VERSION_HEADER_PREFIX = "cryfs;block;"; const string OnDiskBlockStore2::FORMAT_VERSION_HEADER_PREFIX = "cryfs;block;";
const string OnDiskBlockStore2::FORMAT_VERSION_HEADER = OnDiskBlockStore2::FORMAT_VERSION_HEADER_PREFIX + "0"; const string OnDiskBlockStore2::FORMAT_VERSION_HEADER = OnDiskBlockStore2::FORMAT_VERSION_HEADER_PREFIX + "0";
boost::filesystem::path OnDiskBlockStore2::_getFilepath(const Key &key) const { boost::filesystem::path OnDiskBlockStore2::_getFilepath(const BlockId &blockId) const {
std::string keyStr = key.ToString(); std::string blockIdStr = blockId.ToString();
return _rootDir / keyStr.substr(0,3) / keyStr.substr(3); return _rootDir / blockIdStr.substr(0,3) / blockIdStr.substr(3);
} }
Data OnDiskBlockStore2::_checkAndRemoveHeader(const Data &data) { Data OnDiskBlockStore2::_checkAndRemoveHeader(const Data &data) {
@ -45,24 +45,24 @@ unsigned int OnDiskBlockStore2::formatVersionHeaderSize() {
OnDiskBlockStore2::OnDiskBlockStore2(const boost::filesystem::path& path) OnDiskBlockStore2::OnDiskBlockStore2(const boost::filesystem::path& path)
: _rootDir(path) {} : _rootDir(path) {}
bool OnDiskBlockStore2::tryCreate(const Key &key, const Data &data) { bool OnDiskBlockStore2::tryCreate(const BlockId &blockId, const Data &data) {
auto filepath = _getFilepath(key); auto filepath = _getFilepath(blockId);
if (boost::filesystem::exists(filepath)) { if (boost::filesystem::exists(filepath)) {
return false; return false;
} }
store(key, data); store(blockId, data);
return true; return true;
} }
bool OnDiskBlockStore2::remove(const Key &key) { bool OnDiskBlockStore2::remove(const BlockId &blockId) {
auto filepath = _getFilepath(key); auto filepath = _getFilepath(blockId);
if (!boost::filesystem::is_regular_file(filepath)) { // TODO Is this branch necessary? if (!boost::filesystem::is_regular_file(filepath)) { // TODO Is this branch necessary?
return false; return false;
} }
bool retval = boost::filesystem::remove(filepath); bool retval = boost::filesystem::remove(filepath);
if (!retval) { if (!retval) {
cpputils::logging::LOG(cpputils::logging::ERROR, "Couldn't find block {} to remove", key.ToString()); cpputils::logging::LOG(cpputils::logging::ERROR, "Couldn't find block {} to remove", blockId.ToString());
return false; return false;
} }
if (boost::filesystem::is_empty(filepath.parent_path())) { if (boost::filesystem::is_empty(filepath.parent_path())) {
@ -71,19 +71,19 @@ bool OnDiskBlockStore2::remove(const Key &key) {
return true; return true;
} }
optional<Data> OnDiskBlockStore2::load(const Key &key) const { optional<Data> OnDiskBlockStore2::load(const BlockId &blockId) const {
auto fileContent = Data::LoadFromFile(_getFilepath(key)); auto fileContent = Data::LoadFromFile(_getFilepath(blockId));
if (fileContent == none) { if (fileContent == none) {
return boost::none; return boost::none;
} }
return _checkAndRemoveHeader(std::move(*fileContent)); return _checkAndRemoveHeader(std::move(*fileContent));
} }
void OnDiskBlockStore2::store(const Key &key, const Data &data) { void OnDiskBlockStore2::store(const BlockId &blockId, const Data &data) {
Data fileContent(formatVersionHeaderSize() + data.size()); Data fileContent(formatVersionHeaderSize() + data.size());
std::memcpy(fileContent.data(), FORMAT_VERSION_HEADER.c_str(), formatVersionHeaderSize()); std::memcpy(fileContent.data(), FORMAT_VERSION_HEADER.c_str(), formatVersionHeaderSize());
std::memcpy(fileContent.dataOffset(formatVersionHeaderSize()), data.data(), data.size()); std::memcpy(fileContent.dataOffset(formatVersionHeaderSize()), data.data(), data.size());
auto filepath = _getFilepath(key); auto filepath = _getFilepath(blockId);
boost::filesystem::create_directory(filepath.parent_path()); // TODO Instead create all of them once at fs creation time? boost::filesystem::create_directory(filepath.parent_path()); // TODO Instead create all of them once at fs creation time?
fileContent.StoreToFile(filepath); fileContent.StoreToFile(filepath);
} }
@ -114,13 +114,13 @@ uint64_t OnDiskBlockStore2::blockSizeFromPhysicalBlockSize(uint64_t blockSize) c
return blockSize - formatVersionHeaderSize(); return blockSize - formatVersionHeaderSize();
} }
void OnDiskBlockStore2::forEachBlock(std::function<void (const Key &)> callback) const { void OnDiskBlockStore2::forEachBlock(std::function<void (const BlockId &)> callback) const {
for (auto prefixDir = boost::filesystem::directory_iterator(_rootDir); prefixDir != boost::filesystem::directory_iterator(); ++prefixDir) { for (auto prefixDir = boost::filesystem::directory_iterator(_rootDir); prefixDir != boost::filesystem::directory_iterator(); ++prefixDir) {
if (boost::filesystem::is_directory(prefixDir->path())) { if (boost::filesystem::is_directory(prefixDir->path())) {
std::string blockKeyPrefix = prefixDir->path().filename().native(); std::string blockIdPrefix = prefixDir->path().filename().native();
for (auto block = boost::filesystem::directory_iterator(prefixDir->path()); block != boost::filesystem::directory_iterator(); ++block) { for (auto block = boost::filesystem::directory_iterator(prefixDir->path()); block != boost::filesystem::directory_iterator(); ++block) {
std::string blockKeyPostfix = block->path().filename().native(); std::string blockIdPostfix = block->path().filename().native();
callback(Key::FromString(blockKeyPrefix + blockKeyPostfix)); callback(BlockId::FromString(blockIdPrefix + blockIdPostfix));
} }
} }
} }

View File

@ -16,14 +16,14 @@ class OnDiskBlockStore2 final: public BlockStore2 {
public: public:
explicit OnDiskBlockStore2(const boost::filesystem::path& path); explicit OnDiskBlockStore2(const boost::filesystem::path& path);
bool tryCreate(const Key &key, const cpputils::Data &data) override; bool tryCreate(const BlockId &blockId, const cpputils::Data &data) override;
bool remove(const Key &key) override; bool remove(const BlockId &blockId) override;
boost::optional<cpputils::Data> load(const Key &key) const override; boost::optional<cpputils::Data> load(const BlockId &blockId) const override;
void store(const Key &key, const cpputils::Data &data) override; void store(const BlockId &blockId, const cpputils::Data &data) override;
uint64_t numBlocks() const override; uint64_t numBlocks() const override;
uint64_t estimateNumFreeBytes() const override; uint64_t estimateNumFreeBytes() const override;
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
void forEachBlock(std::function<void (const Key &)> callback) const override; void forEachBlock(std::function<void (const BlockId &)> callback) const override;
private: private:
boost::filesystem::path _rootDir; boost::filesystem::path _rootDir;
@ -31,7 +31,7 @@ private:
static const std::string FORMAT_VERSION_HEADER_PREFIX; static const std::string FORMAT_VERSION_HEADER_PREFIX;
static const std::string FORMAT_VERSION_HEADER; static const std::string FORMAT_VERSION_HEADER;
boost::filesystem::path _getFilepath(const Key &key) const; boost::filesystem::path _getFilepath(const BlockId &blockId) const;
static cpputils::Data _checkAndRemoveHeader(const cpputils::Data &data); static cpputils::Data _checkAndRemoveHeader(const cpputils::Data &data);
static bool _isAcceptedCryfsHeader(const cpputils::Data &data); static bool _isAcceptedCryfsHeader(const cpputils::Data &data);
static bool _isOtherCryfsHeader(const cpputils::Data &data); static bool _isOtherCryfsHeader(const cpputils::Data &data);

View File

@ -11,10 +11,10 @@ namespace blockstore {
namespace parallelaccess { namespace parallelaccess {
class ParallelAccessBlockStore; class ParallelAccessBlockStore;
class BlockRef final: public Block, public parallelaccessstore::ParallelAccessStore<Block, BlockRef, Key>::ResourceRefBase { class BlockRef final: public Block, public parallelaccessstore::ParallelAccessStore<Block, BlockRef, BlockId>::ResourceRefBase {
public: public:
//TODO Unneccessarily storing Key twice here (in parent class and in _baseBlock). //TODO Unneccessarily storing BlockId twice here (in parent class and in _baseBlock).
explicit BlockRef(Block *baseBlock): Block(baseBlock->key()), _baseBlock(baseBlock) {} explicit BlockRef(Block *baseBlock): Block(baseBlock->blockId()), _baseBlock(baseBlock) {}
const void *data() const override { const void *data() const override {
return _baseBlock->data(); return _baseBlock->data();

View File

@ -23,50 +23,50 @@ ParallelAccessBlockStore::ParallelAccessBlockStore(unique_ref<BlockStore> baseBl
: _baseBlockStore(std::move(baseBlockStore)), _parallelAccessStore(make_unique_ref<ParallelAccessBlockStoreAdapter>(_baseBlockStore.get())) { : _baseBlockStore(std::move(baseBlockStore)), _parallelAccessStore(make_unique_ref<ParallelAccessBlockStoreAdapter>(_baseBlockStore.get())) {
} }
Key ParallelAccessBlockStore::createKey() { BlockId ParallelAccessBlockStore::createBlockId() {
return _baseBlockStore->createKey(); return _baseBlockStore->createBlockId();
} }
optional<unique_ref<Block>> ParallelAccessBlockStore::tryCreate(const Key &key, Data data) { optional<unique_ref<Block>> ParallelAccessBlockStore::tryCreate(const BlockId &blockId, Data data) {
ASSERT(!_parallelAccessStore.isOpened(key), ("Key "+key.ToString()+"already exists").c_str()); ASSERT(!_parallelAccessStore.isOpened(blockId), ("BlockId "+blockId.ToString()+"already exists").c_str());
auto block = _baseBlockStore->tryCreate(key, std::move(data)); auto block = _baseBlockStore->tryCreate(blockId, std::move(data));
if (block == none) { if (block == none) {
//TODO Test this code branch //TODO Test this code branch
return none; return none;
} }
return unique_ref<Block>(_parallelAccessStore.add(key, std::move(*block))); return unique_ref<Block>(_parallelAccessStore.add(blockId, std::move(*block)));
} }
optional<unique_ref<Block>> ParallelAccessBlockStore::load(const Key &key) { optional<unique_ref<Block>> ParallelAccessBlockStore::load(const BlockId &blockId) {
auto block = _parallelAccessStore.load(key); auto block = _parallelAccessStore.load(blockId);
if (block == none) { if (block == none) {
return none; return none;
} }
return unique_ref<Block>(std::move(*block)); return unique_ref<Block>(std::move(*block));
} }
unique_ref<Block> ParallelAccessBlockStore::overwrite(const Key &key, Data data) { unique_ref<Block> ParallelAccessBlockStore::overwrite(const BlockId &blockId, Data data) {
auto onExists = [&data] (BlockRef *block) { auto onExists = [&data] (BlockRef *block) {
if (block->size() != data.size()) { if (block->size() != data.size()) {
block->resize(data.size()); block->resize(data.size());
} }
block->write(data.data(), 0, data.size()); block->write(data.data(), 0, data.size());
}; };
auto onAdd = [this, key, &data] { auto onAdd = [this, blockId, &data] {
return _baseBlockStore->overwrite(key, data.copy()); // TODO Without copy? return _baseBlockStore->overwrite(blockId, data.copy()); // TODO Without copy?
}; };
return _parallelAccessStore.loadOrAdd(key, onExists, onAdd); return _parallelAccessStore.loadOrAdd(blockId, onExists, onAdd);
} }
void ParallelAccessBlockStore::remove(unique_ref<Block> block) { void ParallelAccessBlockStore::remove(unique_ref<Block> block) {
Key key = block->key(); BlockId blockId = block->blockId();
auto block_ref = dynamic_pointer_move<BlockRef>(block); auto block_ref = dynamic_pointer_move<BlockRef>(block);
ASSERT(block_ref != none, "Block is not a BlockRef"); ASSERT(block_ref != none, "Block is not a BlockRef");
return _parallelAccessStore.remove(key, std::move(*block_ref)); return _parallelAccessStore.remove(blockId, std::move(*block_ref));
} }
void ParallelAccessBlockStore::remove(const Key &key) { void ParallelAccessBlockStore::remove(const BlockId &blockId) {
return _parallelAccessStore.remove(key); return _parallelAccessStore.remove(blockId);
} }
uint64_t ParallelAccessBlockStore::numBlocks() const { uint64_t ParallelAccessBlockStore::numBlocks() const {
@ -81,7 +81,7 @@ uint64_t ParallelAccessBlockStore::blockSizeFromPhysicalBlockSize(uint64_t block
return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize); return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize);
} }
void ParallelAccessBlockStore::forEachBlock(std::function<void (const Key &)> callback) const { void ParallelAccessBlockStore::forEachBlock(std::function<void (const BlockId &)> callback) const {
return _baseBlockStore->forEachBlock(callback); return _baseBlockStore->forEachBlock(callback);
} }

View File

@ -15,20 +15,20 @@ class ParallelAccessBlockStore final: public BlockStore {
public: public:
explicit ParallelAccessBlockStore(cpputils::unique_ref<BlockStore> baseBlockStore); explicit ParallelAccessBlockStore(cpputils::unique_ref<BlockStore> baseBlockStore);
Key createKey() override; BlockId createBlockId() override;
boost::optional<cpputils::unique_ref<Block>> tryCreate(const Key &key, cpputils::Data data) override; boost::optional<cpputils::unique_ref<Block>> tryCreate(const BlockId &blockId, cpputils::Data data) override;
boost::optional<cpputils::unique_ref<Block>> load(const Key &key) override; boost::optional<cpputils::unique_ref<Block>> load(const BlockId &blockId) override;
cpputils::unique_ref<Block> overwrite(const Key &key, cpputils::Data data) override; cpputils::unique_ref<Block> overwrite(const BlockId &blockId, cpputils::Data data) override;
void remove(const Key &key) override; void remove(const BlockId &blockId) override;
void remove(cpputils::unique_ref<Block> node) override; void remove(cpputils::unique_ref<Block> node) override;
uint64_t numBlocks() const override; uint64_t numBlocks() const override;
uint64_t estimateNumFreeBytes() const override; uint64_t estimateNumFreeBytes() const override;
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
void forEachBlock(std::function<void (const Key &)> callback) const override; void forEachBlock(std::function<void (const BlockId &)> callback) const override;
private: private:
cpputils::unique_ref<BlockStore> _baseBlockStore; cpputils::unique_ref<BlockStore> _baseBlockStore;
parallelaccessstore::ParallelAccessStore<Block, BlockRef, Key> _parallelAccessStore; parallelaccessstore::ParallelAccessStore<Block, BlockRef, BlockId> _parallelAccessStore;
DISALLOW_COPY_AND_ASSIGN(ParallelAccessBlockStore); DISALLOW_COPY_AND_ASSIGN(ParallelAccessBlockStore);
}; };

View File

@ -9,22 +9,22 @@
namespace blockstore { namespace blockstore {
namespace parallelaccess { namespace parallelaccess {
class ParallelAccessBlockStoreAdapter final: public parallelaccessstore::ParallelAccessBaseStore<Block, Key> { class ParallelAccessBlockStoreAdapter final: public parallelaccessstore::ParallelAccessBaseStore<Block, BlockId> {
public: public:
explicit ParallelAccessBlockStoreAdapter(BlockStore *baseBlockStore) explicit ParallelAccessBlockStoreAdapter(BlockStore *baseBlockStore)
:_baseBlockStore(std::move(baseBlockStore)) { :_baseBlockStore(std::move(baseBlockStore)) {
} }
boost::optional<cpputils::unique_ref<Block>> loadFromBaseStore(const Key &key) override { boost::optional<cpputils::unique_ref<Block>> loadFromBaseStore(const BlockId &blockId) override {
return _baseBlockStore->load(key); return _baseBlockStore->load(blockId);
} }
void removeFromBaseStore(cpputils::unique_ref<Block> block) override { void removeFromBaseStore(cpputils::unique_ref<Block> block) override {
return _baseBlockStore->remove(std::move(block)); return _baseBlockStore->remove(std::move(block));
} }
void removeFromBaseStore(const Key &key) override { void removeFromBaseStore(const BlockId &blockId) override {
return _baseBlockStore->remove(key); return _baseBlockStore->remove(blockId);
} }
private: private:

View File

@ -16,8 +16,8 @@ using cpputils::Data;
namespace blockstore { namespace blockstore {
namespace testfake { namespace testfake {
FakeBlock::FakeBlock(FakeBlockStore *store, const Key &key, shared_ptr<Data> data, bool dirty) FakeBlock::FakeBlock(FakeBlockStore *store, const BlockId &blockId, shared_ptr<Data> data, bool dirty)
: Block(key), _store(store), _data(data), _dataChanged(dirty) { : Block(blockId), _store(store), _data(data), _dataChanged(dirty) {
} }
FakeBlock::~FakeBlock() { FakeBlock::~FakeBlock() {
@ -45,7 +45,7 @@ void FakeBlock::resize(size_t newSize) {
void FakeBlock::flush() { void FakeBlock::flush() {
if(_dataChanged) { if(_dataChanged) {
_store->updateData(key(), *_data); _store->updateData(blockId(), *_data);
_dataChanged = false; _dataChanged = false;
} }
} }

View File

@ -13,7 +13,7 @@ class FakeBlockStore;
class FakeBlock final: public Block { class FakeBlock final: public Block {
public: public:
FakeBlock(FakeBlockStore *store, const Key &key, std::shared_ptr<cpputils::Data> data, bool dirty); FakeBlock(FakeBlockStore *store, const BlockId &blockId, std::shared_ptr<cpputils::Data> data, bool dirty);
~FakeBlock(); ~FakeBlock();
const void *data() const override; const void *data() const override;

View File

@ -19,21 +19,21 @@ namespace testfake {
FakeBlockStore::FakeBlockStore() FakeBlockStore::FakeBlockStore()
: _blocks(), _used_dataregions_for_blocks(), _mutex() {} : _blocks(), _used_dataregions_for_blocks(), _mutex() {}
optional<unique_ref<Block>> FakeBlockStore::tryCreate(const Key &key, Data data) { optional<unique_ref<Block>> FakeBlockStore::tryCreate(const BlockId &blockId, Data data) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
auto insert_result = _blocks.emplace(key, std::move(data)); auto insert_result = _blocks.emplace(blockId, std::move(data));
if (!insert_result.second) { if (!insert_result.second) {
return none; return none;
} }
//Return a copy of the stored data //Return a copy of the stored data
return _load(key); return _load(blockId);
} }
unique_ref<Block> FakeBlockStore::overwrite(const Key &key, Data data) { unique_ref<Block> FakeBlockStore::overwrite(const BlockId &blockId, Data data) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
auto insert_result = _blocks.emplace(key, data.copy()); auto insert_result = _blocks.emplace(blockId, data.copy());
if (!insert_result.second) { if (!insert_result.second) {
// If block already exists, overwrite it. // If block already exists, overwrite it.
@ -41,42 +41,42 @@ unique_ref<Block> FakeBlockStore::overwrite(const Key &key, Data data) {
} }
//Return a pointer to the stored FakeBlock //Return a pointer to the stored FakeBlock
auto loaded = _load(key); auto loaded = _load(blockId);
ASSERT(loaded != none, "Block was just created or written. Should exist."); ASSERT(loaded != none, "Block was just created or written. Should exist.");
return std::move(*loaded); return std::move(*loaded);
} }
optional<unique_ref<Block>> FakeBlockStore::load(const Key &key) { optional<unique_ref<Block>> FakeBlockStore::load(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
return _load(key); return _load(blockId);
} }
optional<unique_ref<Block>> FakeBlockStore::_load(const Key &key) { optional<unique_ref<Block>> FakeBlockStore::_load(const BlockId &blockId) {
//Return a copy of the stored data //Return a copy of the stored data
try { try {
return makeFakeBlockFromData(key, _blocks.at(key), false); return makeFakeBlockFromData(blockId, _blocks.at(blockId), false);
} catch (const std::out_of_range &e) { } catch (const std::out_of_range &e) {
return none; return none;
} }
} }
void FakeBlockStore::remove(const Key &key) { void FakeBlockStore::remove(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
int numRemoved = _blocks.erase(key); int numRemoved = _blocks.erase(blockId);
ASSERT(numRemoved == 1, "Block not found"); ASSERT(numRemoved == 1, "Block not found");
} }
unique_ref<Block> FakeBlockStore::makeFakeBlockFromData(const Key &key, const Data &data, bool dirty) { unique_ref<Block> FakeBlockStore::makeFakeBlockFromData(const BlockId &blockId, const Data &data, bool dirty) {
auto newdata = make_shared<Data>(data.copy()); auto newdata = make_shared<Data>(data.copy());
_used_dataregions_for_blocks.push_back(newdata); _used_dataregions_for_blocks.push_back(newdata);
return make_unique_ref<FakeBlock>(this, key, newdata, dirty); return make_unique_ref<FakeBlock>(this, blockId, newdata, dirty);
} }
void FakeBlockStore::updateData(const Key &key, const Data &data) { void FakeBlockStore::updateData(const BlockId &blockId, const Data &data) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
auto found = _blocks.find(key); auto found = _blocks.find(blockId);
if (found == _blocks.end()) { if (found == _blocks.end()) {
auto insertResult = _blocks.emplace(key, data.copy()); auto insertResult = _blocks.emplace(blockId, data.copy());
ASSERT(true == insertResult.second, "Inserting didn't work"); ASSERT(true == insertResult.second, "Inserting didn't work");
found = insertResult.first; found = insertResult.first;
} }
@ -97,7 +97,7 @@ uint64_t FakeBlockStore::blockSizeFromPhysicalBlockSize(uint64_t blockSize) cons
return blockSize; return blockSize;
} }
void FakeBlockStore::forEachBlock(std::function<void (const Key &)> callback) const { void FakeBlockStore::forEachBlock(std::function<void (const BlockId &)> callback) const {
for (const auto &entry : _blocks) { for (const auto &entry : _blocks) {
callback(entry.first); callback(entry.first);
} }

View File

@ -31,19 +31,19 @@ class FakeBlockStore final: public BlockStoreWithRandomKeys {
public: public:
FakeBlockStore(); FakeBlockStore();
boost::optional<cpputils::unique_ref<Block>> tryCreate(const Key &key, cpputils::Data data) override; boost::optional<cpputils::unique_ref<Block>> tryCreate(const BlockId &blockId, cpputils::Data data) override;
cpputils::unique_ref<Block> overwrite(const blockstore::Key &key, cpputils::Data data) override; cpputils::unique_ref<Block> overwrite(const blockstore::BlockId &blockId, cpputils::Data data) override;
boost::optional<cpputils::unique_ref<Block>> load(const Key &key) override; boost::optional<cpputils::unique_ref<Block>> load(const BlockId &blockId) override;
void remove(const Key &key) override; void remove(const BlockId &blockId) override;
uint64_t numBlocks() const override; uint64_t numBlocks() const override;
uint64_t estimateNumFreeBytes() const override; uint64_t estimateNumFreeBytes() const override;
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override; uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
void forEachBlock(std::function<void (const Key &)> callback) const override; void forEachBlock(std::function<void (const BlockId &)> callback) const override;
void updateData(const Key &key, const cpputils::Data &data); void updateData(const BlockId &blockId, const cpputils::Data &data);
private: private:
std::unordered_map<Key, cpputils::Data> _blocks; std::unordered_map<BlockId, cpputils::Data> _blocks;
//This vector keeps a handle of the data regions for all created FakeBlock objects. //This vector keeps a handle of the data regions for all created FakeBlock objects.
//This way, it is ensured that no two created FakeBlock objects will work on the //This way, it is ensured that no two created FakeBlock objects will work on the
@ -54,8 +54,8 @@ private:
mutable std::mutex _mutex; mutable std::mutex _mutex;
cpputils::unique_ref<Block> makeFakeBlockFromData(const Key &key, const cpputils::Data &data, bool dirty); cpputils::unique_ref<Block> makeFakeBlockFromData(const BlockId &blockId, const cpputils::Data &data, bool dirty);
boost::optional<cpputils::unique_ref<Block>> _load(const Key &key); boost::optional<cpputils::unique_ref<Block>> _load(const BlockId &blockId);
DISALLOW_COPY_AND_ASSIGN(FakeBlockStore); DISALLOW_COPY_AND_ASSIGN(FakeBlockStore);
}; };

View File

@ -2,7 +2,7 @@
#ifndef MESSMER_BLOCKSTORE_INTERFACE_BLOCK_H_ #ifndef MESSMER_BLOCKSTORE_INTERFACE_BLOCK_H_
#define MESSMER_BLOCKSTORE_INTERFACE_BLOCK_H_ #define MESSMER_BLOCKSTORE_INTERFACE_BLOCK_H_
#include "../utils/Key.h" #include "blockstore/utils/BlockId.h"
#include <cstring> #include <cstring>
namespace blockstore { namespace blockstore {
@ -24,15 +24,15 @@ public:
//TODO Test resize() //TODO Test resize()
virtual void resize(size_t newSize) = 0; virtual void resize(size_t newSize) = 0;
const Key &key() const { const BlockId &blockId() const {
return _key; return _blockId;
} }
protected: protected:
Block(const Key &key) : _key(key) {} Block(const BlockId &blockId) : _blockId(blockId) {}
private: private:
const Key _key; const BlockId _blockId;
}; };
} }

View File

@ -14,15 +14,15 @@ class BlockStore {
public: public:
virtual ~BlockStore() {} virtual ~BlockStore() {}
virtual Key createKey() = 0; virtual BlockId createBlockId() = 0;
//Returns boost::none if key already exists //Returns boost::none if id already exists
// TODO Can we make data passed in by ref? // TODO Can we make data passed in by ref?
virtual boost::optional<cpputils::unique_ref<Block>> tryCreate(const Key &key, cpputils::Data data) = 0; virtual boost::optional<cpputils::unique_ref<Block>> tryCreate(const BlockId &blockId, cpputils::Data data) = 0;
//TODO Use boost::optional (if key doesn't exist) //TODO Use boost::optional (if id doesn't exist)
// Return nullptr if block with this key doesn't exists // Return nullptr if block with this id doesn't exists
virtual boost::optional<cpputils::unique_ref<Block>> load(const Key &key) = 0; virtual boost::optional<cpputils::unique_ref<Block>> load(const BlockId &blockId) = 0;
virtual cpputils::unique_ref<Block> overwrite(const blockstore::Key &key, cpputils::Data data) = 0; virtual cpputils::unique_ref<Block> overwrite(const blockstore::BlockId &blockId, cpputils::Data data) = 0;
virtual void remove(const Key &key) = 0; virtual void remove(const BlockId &blockId) = 0;
virtual uint64_t numBlocks() const = 0; virtual uint64_t numBlocks() const = 0;
//TODO Test estimateNumFreeBytes in all block stores //TODO Test estimateNumFreeBytes in all block stores
virtual uint64_t estimateNumFreeBytes() const = 0; virtual uint64_t estimateNumFreeBytes() const = 0;
@ -31,18 +31,18 @@ public:
// This can be used to create blocks with a certain physical block size. // This can be used to create blocks with a certain physical block size.
virtual uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const = 0; // TODO Test virtual uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const = 0; // TODO Test
virtual void forEachBlock(std::function<void (const Key &)> callback) const = 0; virtual void forEachBlock(std::function<void (const BlockId &)> callback) const = 0;
virtual void remove(cpputils::unique_ref<Block> block) { virtual void remove(cpputils::unique_ref<Block> block) {
Key key = block->key(); BlockId blockId = block->blockId();
cpputils::destruct(std::move(block)); cpputils::destruct(std::move(block));
remove(key); remove(blockId);
} }
cpputils::unique_ref<Block> create(const cpputils::Data &data) { cpputils::unique_ref<Block> create(const cpputils::Data &data) {
while(true) { while(true) {
//TODO Copy (data.copy()) necessary? //TODO Copy (data.copy()) necessary?
auto block = tryCreate(createKey(), data.copy()); auto block = tryCreate(createBlockId(), data.copy());
if (block != boost::none) { if (block != boost::none) {
return std::move(*block); return std::move(*block);
} }

View File

@ -16,21 +16,21 @@ public:
virtual ~BlockStore2() {} virtual ~BlockStore2() {}
__attribute__((warn_unused_result)) __attribute__((warn_unused_result))
virtual bool tryCreate(const Key &key, const cpputils::Data &data) = 0; virtual bool tryCreate(const BlockId &blockId, const cpputils::Data &data) = 0;
__attribute__((warn_unused_result)) __attribute__((warn_unused_result))
virtual bool remove(const Key &key) = 0; virtual bool remove(const BlockId &blockId) = 0;
__attribute__((warn_unused_result)) __attribute__((warn_unused_result))
virtual boost::optional<cpputils::Data> load(const Key &key) const = 0; virtual boost::optional<cpputils::Data> load(const BlockId &blockId) const = 0;
// Store the block with the given key. If it doesn't exist, it is created. // Store the block with the given blockId. If it doesn't exist, it is created.
virtual void store(const Key &key, const cpputils::Data &data) = 0; virtual void store(const BlockId &blockId, const cpputils::Data &data) = 0;
Key create(const cpputils::Data& data) { BlockId create(const cpputils::Data& data) {
Key key = Key::Random(); BlockId blockId = BlockId::Random();
bool success = tryCreate(key, data); bool success = tryCreate(blockId, data);
if (success) { if (success) {
return key; return blockId;
} else { } else {
return create(data); return create(data);
} }
@ -40,7 +40,7 @@ public:
//TODO Test estimateNumFreeBytes //TODO Test estimateNumFreeBytes
virtual uint64_t estimateNumFreeBytes() const = 0; virtual uint64_t estimateNumFreeBytes() const = 0;
virtual uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const = 0; // TODO Test virtual uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const = 0; // TODO Test
virtual void forEachBlock(std::function<void (const Key &)> callback) const = 0; virtual void forEachBlock(std::function<void (const BlockId &)> callback) const = 0;
}; };
} }

View File

@ -8,14 +8,14 @@
namespace blockstore { namespace blockstore {
// This is an implementation helpers for BlockStores that use random block keys. // This is an implementation helpers for BlockStores that use random block ids.
// You should never give this static type to the client. The client should always // You should never give this static type to the client. The client should always
// work with the BlockStore interface instead. // work with the BlockStore interface instead.
// TODO Delete this class // TODO Delete this class
class BlockStoreWithRandomKeys: public BlockStore { class BlockStoreWithRandomKeys: public BlockStore {
public: public:
Key createKey() final { BlockId createBlockId() final {
return Key::Random(); return BlockId::Random();
} }
}; };

View File

@ -1 +1 @@
#include "Key.h" #include "BlockId.h"

View File

@ -1,14 +1,13 @@
#pragma once #pragma once
#ifndef MESSMER_BLOCKSTORE_UTILS_KEY_H_ #ifndef MESSMER_BLOCKSTORE_UTILS_BLOCKID_H_
#define MESSMER_BLOCKSTORE_UTILS_KEY_H_ #define MESSMER_BLOCKSTORE_UTILS_BLOCKID_H_
#include "IdWrapper.h" #include "IdWrapper.h"
namespace blockstore { namespace blockstore {
struct _BlockIdTag final {}; struct _BlockIdTag final {};
// A key here is NOT a key for encryption, but a key as used in key->value mappings ("access handle for a block"). // TODO Split from a BlobId (i.e. IdWrapper<BlobIdTag>)
// TODO Rename to BlockId and split from a BlobId (i.e. IdWrapper<BlobIdTag>)
using BlockId = IdWrapper<_BlockIdTag>; using BlockId = IdWrapper<_BlockIdTag>;
} }

View File

@ -27,7 +27,7 @@ namespace cryfs {
config.SetVersion(gitversion::VersionString()); config.SetVersion(gitversion::VersionString());
config.SetCreatedWithVersion(gitversion::VersionString()); config.SetCreatedWithVersion(gitversion::VersionString());
config.SetBlocksizeBytes(_generateBlocksizeBytes(blocksizeBytesFromCommandLine)); config.SetBlocksizeBytes(_generateBlocksizeBytes(blocksizeBytesFromCommandLine));
config.SetRootBlob(_generateRootBlobKey()); config.SetRootBlob(_generateRootBlobId());
config.SetEncryptionKey(_generateEncKey(config.Cipher())); config.SetEncryptionKey(_generateEncKey(config.Cipher()));
config.SetFilesystemId(_generateFilesystemID()); config.SetFilesystemId(_generateFilesystemID());
uint32_t myClientId = MyClientId(LocalStateDir::forFilesystemId(config.FilesystemId())).loadOrGenerate(); uint32_t myClientId = MyClientId(LocalStateDir::forFilesystemId(config.FilesystemId())).loadOrGenerate();
@ -78,7 +78,7 @@ namespace cryfs {
return key; return key;
} }
string CryConfigCreator::_generateRootBlobKey() { string CryConfigCreator::_generateRootBlobId() {
//An empty root blob entry will tell CryDevice to create a new root blob //An empty root blob entry will tell CryDevice to create a new root blob
return ""; return "";
} }

View File

@ -23,7 +23,7 @@ namespace cryfs {
private: private:
std::string _generateCipher(const boost::optional<std::string> &cipherFromCommandLine); std::string _generateCipher(const boost::optional<std::string> &cipherFromCommandLine);
std::string _generateEncKey(const std::string &cipher); std::string _generateEncKey(const std::string &cipher);
std::string _generateRootBlobKey(); std::string _generateRootBlobId();
uint32_t _generateBlocksizeBytes(const boost::optional<uint32_t> &blocksizeBytesFromCommandLine); uint32_t _generateBlocksizeBytes(const boost::optional<uint32_t> &blocksizeBytesFromCommandLine);
CryConfig::FilesystemID _generateFilesystemID(); CryConfig::FilesystemID _generateFilesystemID();
boost::optional<uint32_t> _generateExclusiveClientId(const boost::optional<bool> &missingBlockIsIntegrityViolationFromCommandLine, uint32_t myClientId); boost::optional<uint32_t> _generateExclusiveClientId(const boost::optional<bool> &missingBlockIsIntegrityViolationFromCommandLine, uint32_t myClientId);

View File

@ -30,7 +30,7 @@ using fspp::fuse::FuseErrnoException;
using blockstore::BlockStore; using blockstore::BlockStore;
using blockstore::BlockStore2; using blockstore::BlockStore2;
using blockstore::Key; using blockstore::BlockId;
using blockstore::encrypted::EncryptedBlockStore2; using blockstore::encrypted::EncryptedBlockStore2;
using blobstore::BlobStore; using blobstore::BlobStore;
using blockstore::lowtohighlevel::LowToHighLevelBlockStore; using blockstore::lowtohighlevel::LowToHighLevelBlockStore;
@ -59,7 +59,7 @@ namespace cryfs {
CryDevice::CryDevice(CryConfigFile configFile, unique_ref<BlockStore2> blockStore, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation) CryDevice::CryDevice(CryConfigFile configFile, unique_ref<BlockStore2> blockStore, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation)
: _fsBlobStore(CreateFsBlobStore(std::move(blockStore), &configFile, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation)), : _fsBlobStore(CreateFsBlobStore(std::move(blockStore), &configFile, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation)),
_rootKey(GetOrCreateRootKey(&configFile)), _rootBlobId(GetOrCreateRootBlobId(&configFile)),
_onFsAction() { _onFsAction() {
} }
@ -81,11 +81,11 @@ unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CryDevice::Crea
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
unique_ref<fsblobstore::FsBlobStore> CryDevice::MigrateOrCreateFsBlobStore(unique_ref<BlobStore> blobStore, CryConfigFile *configFile) { unique_ref<fsblobstore::FsBlobStore> CryDevice::MigrateOrCreateFsBlobStore(unique_ref<BlobStore> blobStore, CryConfigFile *configFile) {
string rootBlobKey = configFile->config()->RootBlob(); string rootBlobId = configFile->config()->RootBlob();
if ("" == rootBlobKey) { if ("" == rootBlobId) {
return make_unique_ref<FsBlobStore>(std::move(blobStore)); return make_unique_ref<FsBlobStore>(std::move(blobStore));
} }
return FsBlobStore::migrateIfNeeded(std::move(blobStore), Key::FromString(rootBlobKey)); return FsBlobStore::migrateIfNeeded(std::move(blobStore), BlockId::FromString(rootBlobId));
} }
#endif #endif
@ -119,10 +119,10 @@ unique_ref<BlockStore2> CryDevice::CreateIntegrityEncryptedBlockStore(unique_ref
return make_unique_ref<IntegrityBlockStore2>(std::move(encryptedBlockStore), integrityFilePath, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation); return make_unique_ref<IntegrityBlockStore2>(std::move(encryptedBlockStore), integrityFilePath, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation);
} }
Key CryDevice::CreateRootBlobAndReturnKey() { BlockId CryDevice::CreateRootBlobAndReturnId() {
auto rootBlob = _fsBlobStore->createDirBlob(blockstore::Key::Null()); auto rootBlob = _fsBlobStore->createDirBlob(blockstore::BlockId::Null());
rootBlob->flush(); // Don't cache, but directly write the root blob (this causes it to fail early if the base directory is not accessible) rootBlob->flush(); // Don't cache, but directly write the root blob (this causes it to fail early if the base directory is not accessible)
return rootBlob->key(); return rootBlob->blockId();
} }
optional<unique_ref<fspp::File>> CryDevice::LoadFile(const bf::path &path) { optional<unique_ref<fspp::File>> CryDevice::LoadFile(const bf::path &path) {
@ -170,7 +170,7 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
if (path.parent_path().empty()) { if (path.parent_path().empty()) {
//We are asked to load the base directory '/'. //We are asked to load the base directory '/'.
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, none, none, _rootKey)); return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, none, none, _rootBlobId));
} }
auto parentWithGrandparent = LoadDirBlobWithParent(path.parent_path()); auto parentWithGrandparent = LoadDirBlobWithParent(path.parent_path());
@ -185,11 +185,11 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
switch(entry.type()) { switch(entry.type()) {
case fspp::Dir::EntryType::DIR: case fspp::Dir::EntryType::DIR:
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, std::move(parent), std::move(grandparent), entry.key())); return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, std::move(parent), std::move(grandparent), entry.blockId()));
case fspp::Dir::EntryType::FILE: case fspp::Dir::EntryType::FILE:
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryFile>(this, std::move(parent), std::move(grandparent), entry.key())); return optional<unique_ref<fspp::Node>>(make_unique_ref<CryFile>(this, std::move(parent), std::move(grandparent), entry.blockId()));
case fspp::Dir::EntryType::SYMLINK: case fspp::Dir::EntryType::SYMLINK:
return optional<unique_ref<fspp::Node>>(make_unique_ref<CrySymlink>(this, std::move(parent), std::move(grandparent), entry.key())); return optional<unique_ref<fspp::Node>>(make_unique_ref<CrySymlink>(this, std::move(parent), std::move(grandparent), entry.blockId()));
} }
ASSERT(false, "Switch/case not exhaustive"); ASSERT(false, "Switch/case not exhaustive");
} }
@ -205,13 +205,13 @@ CryDevice::DirBlobWithParent CryDevice::LoadDirBlobWithParent(const bf::path &pa
CryDevice::BlobWithParent CryDevice::LoadBlobWithParent(const bf::path &path) { CryDevice::BlobWithParent CryDevice::LoadBlobWithParent(const bf::path &path) {
optional<unique_ref<DirBlobRef>> parentBlob = none; optional<unique_ref<DirBlobRef>> parentBlob = none;
optional<unique_ref<FsBlobRef>> currentBlobOpt = _fsBlobStore->load(_rootKey); optional<unique_ref<FsBlobRef>> currentBlobOpt = _fsBlobStore->load(_rootBlobId);
if (currentBlobOpt == none) { if (currentBlobOpt == none) {
LOG(ERROR, "Could not load root blob. Is the base directory accessible?"); LOG(ERROR, "Could not load root blob. Is the base directory accessible?");
throw FuseErrnoException(EIO); throw FuseErrnoException(EIO);
} }
unique_ref<FsBlobRef> currentBlob = std::move(*currentBlobOpt); unique_ref<FsBlobRef> currentBlob = std::move(*currentBlobOpt);
ASSERT(currentBlob->parentPointer() == Key::Null(), "Root Blob should have a nullptr as parent"); ASSERT(currentBlob->parentPointer() == BlockId::Null(), "Root Blob should have a nullptr as parent");
for (const bf::path &component : path.relative_path()) { for (const bf::path &component : path.relative_path()) {
auto currentDir = dynamic_pointer_move<DirBlobRef>(currentBlob); auto currentDir = dynamic_pointer_move<DirBlobRef>(currentBlob);
@ -223,14 +223,14 @@ CryDevice::BlobWithParent CryDevice::LoadBlobWithParent(const bf::path &path) {
if (childOpt == boost::none) { if (childOpt == boost::none) {
throw FuseErrnoException(ENOENT); // Child entry in directory not found throw FuseErrnoException(ENOENT); // Child entry in directory not found
} }
Key childKey = childOpt->key(); BlockId childId = childOpt->blockId();
auto nextBlob = _fsBlobStore->load(childKey); auto nextBlob = _fsBlobStore->load(childId);
if (nextBlob == none) { if (nextBlob == none) {
throw FuseErrnoException(ENOENT); // Blob for directory entry not found throw FuseErrnoException(ENOENT); // Blob for directory entry not found
} }
parentBlob = std::move(*currentDir); parentBlob = std::move(*currentDir);
currentBlob = std::move(*nextBlob); currentBlob = std::move(*nextBlob);
ASSERT(currentBlob->parentPointer() == (*parentBlob)->key(), "Blob has wrong parent pointer"); ASSERT(currentBlob->parentPointer() == (*parentBlob)->blockId(), "Blob has wrong parent pointer");
} }
return BlobWithParent{std::move(currentBlob), std::move(parentBlob)}; return BlobWithParent{std::move(currentBlob), std::move(parentBlob)};
@ -258,46 +258,46 @@ void CryDevice::statfs(const bf::path &path, struct statvfs *fsstat) {
fsstat->f_frsize = fsstat->f_bsize; // even though this is supposed to be ignored, osxfuse needs it. fsstat->f_frsize = fsstat->f_bsize; // even though this is supposed to be ignored, osxfuse needs it.
} }
unique_ref<FileBlobRef> CryDevice::CreateFileBlob(const blockstore::Key &parent) { unique_ref<FileBlobRef> CryDevice::CreateFileBlob(const blockstore::BlockId &parent) {
return _fsBlobStore->createFileBlob(parent); return _fsBlobStore->createFileBlob(parent);
} }
unique_ref<DirBlobRef> CryDevice::CreateDirBlob(const blockstore::Key &parent) { unique_ref<DirBlobRef> CryDevice::CreateDirBlob(const blockstore::BlockId &parent) {
return _fsBlobStore->createDirBlob(parent); return _fsBlobStore->createDirBlob(parent);
} }
unique_ref<SymlinkBlobRef> CryDevice::CreateSymlinkBlob(const bf::path &target, const blockstore::Key &parent) { unique_ref<SymlinkBlobRef> CryDevice::CreateSymlinkBlob(const bf::path &target, const blockstore::BlockId &parent) {
return _fsBlobStore->createSymlinkBlob(target, parent); return _fsBlobStore->createSymlinkBlob(target, parent);
} }
unique_ref<FsBlobRef> CryDevice::LoadBlob(const blockstore::Key &key) { unique_ref<FsBlobRef> CryDevice::LoadBlob(const blockstore::BlockId &blockId) {
auto blob = _fsBlobStore->load(key); auto blob = _fsBlobStore->load(blockId);
if (blob == none) { if (blob == none) {
LOG(ERROR, "Could not load blob {}. Is the base directory accessible?", key.ToString()); LOG(ERROR, "Could not load blob {}. Is the base directory accessible?", blockId.ToString());
throw FuseErrnoException(EIO); throw FuseErrnoException(EIO);
} }
return std::move(*blob); return std::move(*blob);
} }
void CryDevice::RemoveBlob(const blockstore::Key &key) { void CryDevice::RemoveBlob(const blockstore::BlockId &blockId) {
auto blob = _fsBlobStore->load(key); auto blob = _fsBlobStore->load(blockId);
if (blob == none) { if (blob == none) {
LOG(ERROR, "Could not load blob. Is the base directory accessible?", key.ToString()); LOG(ERROR, "Could not load blob {}. Is the base directory accessible?", blockId.ToString());
throw FuseErrnoException(EIO); throw FuseErrnoException(EIO);
} }
_fsBlobStore->remove(std::move(*blob)); _fsBlobStore->remove(std::move(*blob));
} }
Key CryDevice::GetOrCreateRootKey(CryConfigFile *configFile) { BlockId CryDevice::GetOrCreateRootBlobId(CryConfigFile *configFile) {
string root_key = configFile->config()->RootBlob(); string root_blockId = configFile->config()->RootBlob();
if (root_key == "") { if (root_blockId == "") {
auto new_key = CreateRootBlobAndReturnKey(); auto new_blockId = CreateRootBlobAndReturnId();
configFile->config()->SetRootBlob(new_key.ToString()); configFile->config()->SetRootBlob(new_blockId.ToString());
configFile->save(); configFile->save();
return new_key; return new_blockId;
} }
return Key::FromString(root_key); return BlockId::FromString(root_blockId);
} }
cpputils::unique_ref<blockstore::BlockStore2> CryDevice::CreateEncryptedBlockStore(const CryConfig &config, unique_ref<BlockStore2> baseBlockStore) { cpputils::unique_ref<blockstore::BlockStore2> CryDevice::CreateEncryptedBlockStore(const CryConfig &config, unique_ref<BlockStore2> baseBlockStore) {

View File

@ -22,16 +22,16 @@ public:
void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) override; void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) override;
cpputils::unique_ref<parallelaccessfsblobstore::FileBlobRef> CreateFileBlob(const blockstore::Key &parent); cpputils::unique_ref<parallelaccessfsblobstore::FileBlobRef> CreateFileBlob(const blockstore::BlockId &parent);
cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> CreateDirBlob(const blockstore::Key &parent); cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> CreateDirBlob(const blockstore::BlockId &parent);
cpputils::unique_ref<parallelaccessfsblobstore::SymlinkBlobRef> CreateSymlinkBlob(const boost::filesystem::path &target, const blockstore::Key &parent); cpputils::unique_ref<parallelaccessfsblobstore::SymlinkBlobRef> CreateSymlinkBlob(const boost::filesystem::path &target, const blockstore::BlockId &parent);
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> LoadBlob(const blockstore::Key &key); cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> LoadBlob(const blockstore::BlockId &blockId);
struct DirBlobWithParent { struct DirBlobWithParent {
cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> blob; cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> blob;
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent; boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
}; };
DirBlobWithParent LoadDirBlobWithParent(const boost::filesystem::path &path); DirBlobWithParent LoadDirBlobWithParent(const boost::filesystem::path &path);
void RemoveBlob(const blockstore::Key &key); void RemoveBlob(const blockstore::BlockId &blockId);
void onFsAction(std::function<void()> callback); void onFsAction(std::function<void()> callback);
@ -48,11 +48,11 @@ private:
cpputils::unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> _fsBlobStore; cpputils::unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> _fsBlobStore;
blockstore::Key _rootKey; blockstore::BlockId _rootBlobId;
std::vector<std::function<void()>> _onFsAction; std::vector<std::function<void()>> _onFsAction;
blockstore::Key GetOrCreateRootKey(CryConfigFile *config); blockstore::BlockId GetOrCreateRootBlobId(CryConfigFile *config);
blockstore::Key CreateRootBlobAndReturnKey(); blockstore::BlockId CreateRootBlobAndReturnId();
static cpputils::unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CreateFsBlobStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation); static cpputils::unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CreateFsBlobStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
static cpputils::unique_ref<fsblobstore::FsBlobStore> MigrateOrCreateFsBlobStore(cpputils::unique_ref<blobstore::BlobStore> blobStore, CryConfigFile *configFile); static cpputils::unique_ref<fsblobstore::FsBlobStore> MigrateOrCreateFsBlobStore(cpputils::unique_ref<blobstore::BlobStore> blobStore, CryConfigFile *configFile);

View File

@ -21,7 +21,7 @@ namespace bf = boost::filesystem;
using std::string; using std::string;
using std::vector; using std::vector;
using blockstore::Key; using blockstore::BlockId;
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
using cpputils::dynamic_pointer_move; using cpputils::dynamic_pointer_move;
@ -31,8 +31,8 @@ using cryfs::parallelaccessfsblobstore::DirBlobRef;
namespace cryfs { namespace cryfs {
CryDir::CryDir(CryDevice *device, optional<unique_ref<DirBlobRef>> parent, optional<unique_ref<DirBlobRef>> grandparent, const Key &key) CryDir::CryDir(CryDevice *device, optional<unique_ref<DirBlobRef>> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId)
: CryNode(device, std::move(parent), std::move(grandparent), key) { : CryNode(device, std::move(parent), std::move(grandparent), blockId) {
} }
CryDir::~CryDir() { CryDir::~CryDir() {
@ -42,12 +42,12 @@ unique_ref<fspp::OpenFile> CryDir::createAndOpenFile(const string &name, mode_t
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
if (!isRootDir()) { if (!isRootDir()) {
//TODO Instead of doing nothing when we're the root directory, handle timestamps in the root dir correctly (and delete isRootDir() function) //TODO Instead of doing nothing when we're the root directory, handle timestamps in the root dir correctly (and delete isRootDir() function)
parent()->updateModificationTimestampForChild(key()); parent()->updateModificationTimestampForChild(blockId());
} }
auto child = device()->CreateFileBlob(key()); auto child = device()->CreateFileBlob(blockId());
auto now = cpputils::time::now(); auto now = cpputils::time::now();
auto dirBlob = LoadBlob(); auto dirBlob = LoadBlob();
dirBlob->AddChildFile(name, child->key(), mode, uid, gid, now, now); dirBlob->AddChildFile(name, child->blockId(), mode, uid, gid, now, now);
return make_unique_ref<CryOpenFile>(device(), std::move(dirBlob), std::move(child)); return make_unique_ref<CryOpenFile>(device(), std::move(dirBlob), std::move(child));
} }
@ -55,12 +55,12 @@ void CryDir::createDir(const string &name, mode_t mode, uid_t uid, gid_t gid) {
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
if (!isRootDir()) { if (!isRootDir()) {
//TODO Instead of doing nothing when we're the root directory, handle timestamps in the root dir correctly (and delete isRootDir() function) //TODO Instead of doing nothing when we're the root directory, handle timestamps in the root dir correctly (and delete isRootDir() function)
parent()->updateModificationTimestampForChild(key()); parent()->updateModificationTimestampForChild(blockId());
} }
auto blob = LoadBlob(); auto blob = LoadBlob();
auto child = device()->CreateDirBlob(key()); auto child = device()->CreateDirBlob(blockId());
auto now = cpputils::time::now(); auto now = cpputils::time::now();
blob->AddChildDir(name, child->key(), mode, uid, gid, now, now); blob->AddChildDir(name, child->blockId(), mode, uid, gid, now, now);
} }
unique_ref<DirBlobRef> CryDir::LoadBlob() const { unique_ref<DirBlobRef> CryDir::LoadBlob() const {
@ -74,7 +74,7 @@ unique_ref<vector<fspp::Dir::Entry>> CryDir::children() {
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
if (!isRootDir()) { if (!isRootDir()) {
//TODO Instead of doing nothing when we're the root directory, handle timestamps in the root dir correctly (and delete isRootDir() function) //TODO Instead of doing nothing when we're the root directory, handle timestamps in the root dir correctly (and delete isRootDir() function)
parent()->updateAccessTimestampForChild(key(), fsblobstore::TimestampUpdateBehavior::RELATIME); parent()->updateAccessTimestampForChild(blockId(), fsblobstore::TimestampUpdateBehavior::RELATIME);
} }
auto children = make_unique_ref<vector<fspp::Dir::Entry>>(); auto children = make_unique_ref<vector<fspp::Dir::Entry>>();
children->push_back(fspp::Dir::Entry(fspp::Dir::EntryType::DIR, ".")); children->push_back(fspp::Dir::Entry(fspp::Dir::EntryType::DIR, "."));
@ -93,19 +93,19 @@ void CryDir::createSymlink(const string &name, const bf::path &target, uid_t uid
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
if (!isRootDir()) { if (!isRootDir()) {
//TODO Instead of doing nothing when we're the root directory, handle timestamps in the root dir correctly (and delete isRootDir() function) //TODO Instead of doing nothing when we're the root directory, handle timestamps in the root dir correctly (and delete isRootDir() function)
parent()->updateModificationTimestampForChild(key()); parent()->updateModificationTimestampForChild(blockId());
} }
auto blob = LoadBlob(); auto blob = LoadBlob();
auto child = device()->CreateSymlinkBlob(target, key()); auto child = device()->CreateSymlinkBlob(target, blockId());
auto now = cpputils::time::now(); auto now = cpputils::time::now();
blob->AddChildSymlink(name, child->key(), uid, gid, now, now); blob->AddChildSymlink(name, child->blockId(), uid, gid, now, now);
} }
void CryDir::remove() { void CryDir::remove() {
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
if (grandparent() != none) { if (grandparent() != none) {
//TODO Instead of doing nothing when we're in the root directory, handle timestamps in the root dir correctly //TODO Instead of doing nothing when we're in the root directory, handle timestamps in the root dir correctly
(*grandparent())->updateModificationTimestampForChild(parent()->key()); (*grandparent())->updateModificationTimestampForChild(parent()->blockId());
} }
{ {
auto blob = LoadBlob(); auto blob = LoadBlob();

View File

@ -10,7 +10,7 @@ namespace cryfs {
class CryDir final: public fspp::Dir, public CryNode { class CryDir final: public fspp::Dir, public CryNode {
public: public:
CryDir(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::Key &key); CryDir(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId);
~CryDir(); ~CryDir();
//TODO return type variance to CryFile/CryDir? //TODO return type variance to CryFile/CryDir?

View File

@ -10,7 +10,7 @@ namespace bf = boost::filesystem;
using fspp::fuse::CHECK_RETVAL; using fspp::fuse::CHECK_RETVAL;
using fspp::fuse::FuseErrnoException; using fspp::fuse::FuseErrnoException;
using blockstore::Key; using blockstore::BlockId;
using boost::none; using boost::none;
using boost::optional; using boost::optional;
using cpputils::unique_ref; using cpputils::unique_ref;
@ -21,8 +21,8 @@ using cryfs::parallelaccessfsblobstore::FileBlobRef;
namespace cryfs { namespace cryfs {
CryFile::CryFile(CryDevice *device, unique_ref<DirBlobRef> parent, optional<unique_ref<DirBlobRef>> grandparent, const Key &key) CryFile::CryFile(CryDevice *device, unique_ref<DirBlobRef> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId)
: CryNode(device, std::move(parent), std::move(grandparent), key) { : CryNode(device, std::move(parent), std::move(grandparent), blockId) {
} }
CryFile::~CryFile() { CryFile::~CryFile() {
@ -47,7 +47,7 @@ void CryFile::truncate(off_t size) {
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
auto blob = LoadBlob(); auto blob = LoadBlob();
blob->resize(size); blob->resize(size);
parent()->updateModificationTimestampForChild(key()); parent()->updateModificationTimestampForChild(blockId());
} }
fspp::Dir::EntryType CryFile::getType() const { fspp::Dir::EntryType CryFile::getType() const {
@ -59,7 +59,7 @@ void CryFile::remove() {
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
if (grandparent() != none) { if (grandparent() != none) {
//TODO Instead of doing nothing when we're in the root directory, handle timestamps in the root dir correctly //TODO Instead of doing nothing when we're in the root directory, handle timestamps in the root dir correctly
(*grandparent())->updateModificationTimestampForChild(parent()->key()); (*grandparent())->updateModificationTimestampForChild(parent()->blockId());
} }
removeNode(); removeNode();
} }

View File

@ -11,7 +11,7 @@ namespace cryfs {
class CryFile final: public fspp::File, public CryNode { class CryFile final: public fspp::File, public CryNode {
public: public:
CryFile(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::Key &key); CryFile(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId);
~CryFile(); ~CryFile();
cpputils::unique_ref<fspp::OpenFile> open(int flags) override; cpputils::unique_ref<fspp::OpenFile> open(int flags) override;

View File

@ -13,7 +13,7 @@
namespace bf = boost::filesystem; namespace bf = boost::filesystem;
using blockstore::Key; using blockstore::BlockId;
using blobstore::Blob; using blobstore::Blob;
using cpputils::dynamic_pointer_move; using cpputils::dynamic_pointer_move;
using cpputils::unique_ref; using cpputils::unique_ref;
@ -30,11 +30,11 @@ using fspp::fuse::FuseErrnoException;
namespace cryfs { namespace cryfs {
CryNode::CryNode(CryDevice *device, optional<unique_ref<DirBlobRef>> parent, optional<unique_ref<DirBlobRef>> grandparent, const Key &key) CryNode::CryNode(CryDevice *device, optional<unique_ref<DirBlobRef>> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId)
: _device(device), : _device(device),
_parent(none), _parent(none),
_grandparent(none), _grandparent(none),
_key(key) { _blockId(blockId) {
ASSERT(parent != none || grandparent == none, "Grandparent can only be set when parent is not none"); ASSERT(parent != none || grandparent == none, "Grandparent can only be set when parent is not none");
@ -85,24 +85,24 @@ void CryNode::rename(const bf::path &to) {
auto targetDir = std::move(targetDirWithParent.blob); auto targetDir = std::move(targetDirWithParent.blob);
auto targetDirParent = std::move(targetDirWithParent.parent); auto targetDirParent = std::move(targetDirWithParent.parent);
auto old = (*_parent)->GetChild(_key); auto old = (*_parent)->GetChild(_blockId);
if (old == boost::none) { if (old == boost::none) {
throw FuseErrnoException(EIO); throw FuseErrnoException(EIO);
} }
fsblobstore::DirEntry oldEntry = *old; // Copying this (instead of only keeping the reference) is necessary, because the operations below (i.e. RenameChild()) might make a reference invalid. fsblobstore::DirEntry oldEntry = *old; // Copying this (instead of only keeping the reference) is necessary, because the operations below (i.e. RenameChild()) might make a reference invalid.
auto onOverwritten = [this] (const blockstore::Key &key) { auto onOverwritten = [this] (const blockstore::BlockId &blockId) {
device()->RemoveBlob(key); device()->RemoveBlob(blockId);
}; };
_updateParentModificationTimestamp(); _updateParentModificationTimestamp();
if (targetDir->key() == (*_parent)->key()) { if (targetDir->blockId() == (*_parent)->blockId()) {
targetDir->RenameChild(oldEntry.key(), to.filename().native(), onOverwritten); targetDir->RenameChild(oldEntry.blockId(), to.filename().native(), onOverwritten);
} else { } else {
_updateTargetDirModificationTimestamp(*targetDir, std::move(targetDirParent)); _updateTargetDirModificationTimestamp(*targetDir, std::move(targetDirParent));
targetDir->AddOrOverwriteChild(to.filename().native(), oldEntry.key(), oldEntry.type(), oldEntry.mode(), oldEntry.uid(), oldEntry.gid(), targetDir->AddOrOverwriteChild(to.filename().native(), oldEntry.blockId(), oldEntry.type(), oldEntry.mode(), oldEntry.uid(), oldEntry.gid(),
oldEntry.lastAccessTime(), oldEntry.lastModificationTime(), onOverwritten); oldEntry.lastAccessTime(), oldEntry.lastModificationTime(), onOverwritten);
(*_parent)->RemoveChild(oldEntry.name()); (*_parent)->RemoveChild(oldEntry.name());
// targetDir is now the new parent for this node. Adapt to it, so we can call further operations on this node object. // targetDir is now the new parent for this node. Adapt to it, so we can call further operations on this node object.
LoadBlob()->setParentPointer(targetDir->key()); LoadBlob()->setParentPointer(targetDir->blockId());
_parent = std::move(targetDir); _parent = std::move(targetDir);
} }
} }
@ -111,14 +111,14 @@ void CryNode::_updateParentModificationTimestamp() {
if (_grandparent != none) { if (_grandparent != none) {
// TODO Handle timestamps of the root directory (_grandparent == none) correctly. // TODO Handle timestamps of the root directory (_grandparent == none) correctly.
ASSERT(_parent != none, "Grandparent is set, so also parent has to be set"); ASSERT(_parent != none, "Grandparent is set, so also parent has to be set");
(*_grandparent)->updateModificationTimestampForChild((*_parent)->key()); (*_grandparent)->updateModificationTimestampForChild((*_parent)->blockId());
} }
} }
void CryNode::_updateTargetDirModificationTimestamp(const DirBlobRef &targetDir, optional<unique_ref<DirBlobRef>> targetDirParent) { void CryNode::_updateTargetDirModificationTimestamp(const DirBlobRef &targetDir, optional<unique_ref<DirBlobRef>> targetDirParent) {
if (targetDirParent != none) { if (targetDirParent != none) {
// TODO Handle timestamps of the root directory (targetDirParent == none) correctly. // TODO Handle timestamps of the root directory (targetDirParent == none) correctly.
(*targetDirParent)->updateModificationTimestampForChild(targetDir.key()); (*targetDirParent)->updateModificationTimestampForChild(targetDir.blockId());
} }
} }
@ -130,7 +130,7 @@ void CryNode::utimens(timespec lastAccessTime, timespec lastModificationTime) {
//TODO What should we do? //TODO What should we do?
throw FuseErrnoException(EIO); throw FuseErrnoException(EIO);
} }
(*_parent)->utimensChild(_key, lastAccessTime, lastModificationTime); (*_parent)->utimensChild(_blockId, lastAccessTime, lastModificationTime);
} }
void CryNode::removeNode() { void CryNode::removeNode() {
@ -140,8 +140,8 @@ void CryNode::removeNode() {
//TODO What should we do? //TODO What should we do?
throw FuseErrnoException(EIO); throw FuseErrnoException(EIO);
} }
(*_parent)->RemoveChild(_key); (*_parent)->RemoveChild(_blockId);
_device->RemoveBlob(_key); _device->RemoveBlob(_blockId);
} }
CryDevice *CryNode::device() { CryDevice *CryNode::device() {
@ -153,13 +153,13 @@ const CryDevice *CryNode::device() const {
} }
unique_ref<FsBlobRef> CryNode::LoadBlob() const { unique_ref<FsBlobRef> CryNode::LoadBlob() const {
auto blob = _device->LoadBlob(_key); auto blob = _device->LoadBlob(_blockId);
ASSERT(_parent == none || blob->parentPointer() == (*_parent)->key(), "Blob has wrong parent pointer."); ASSERT(_parent == none || blob->parentPointer() == (*_parent)->blockId(), "Blob has wrong parent pointer.");
return blob; return blob;
} }
const blockstore::Key &CryNode::key() const { const blockstore::BlockId &CryNode::blockId() const {
return _key; return _blockId;
} }
void CryNode::stat(struct ::stat *result) const { void CryNode::stat(struct ::stat *result) const {
@ -179,7 +179,7 @@ void CryNode::stat(struct ::stat *result) const {
result->st_mtim = now; result->st_mtim = now;
result->st_ctim = now; result->st_ctim = now;
} else { } else {
(*_parent)->statChild(_key, result); (*_parent)->statChild(_blockId, result);
} }
} }
@ -190,7 +190,7 @@ void CryNode::chmod(mode_t mode) {
//TODO What should we do? //TODO What should we do?
throw FuseErrnoException(EIO); throw FuseErrnoException(EIO);
} }
(*_parent)->chmodChild(_key, mode); (*_parent)->chmodChild(_blockId, mode);
} }
void CryNode::chown(uid_t uid, gid_t gid) { void CryNode::chown(uid_t uid, gid_t gid) {
@ -200,15 +200,15 @@ void CryNode::chown(uid_t uid, gid_t gid) {
//TODO What should we do? //TODO What should we do?
throw FuseErrnoException(EIO); throw FuseErrnoException(EIO);
} }
(*_parent)->chownChild(_key, uid, gid); (*_parent)->chownChild(_blockId, uid, gid);
} }
bool CryNode::checkParentPointer() { bool CryNode::checkParentPointer() {
auto parentPointer = LoadBlob()->parentPointer(); auto parentPointer = LoadBlob()->parentPointer();
if (_parent == none) { if (_parent == none) {
return parentPointer == Key::Null(); return parentPointer == BlockId::Null();
} else { } else {
return parentPointer == (*_parent)->key(); return parentPointer == (*_parent)->blockId();
} }
} }

View File

@ -15,7 +15,7 @@ public:
virtual ~CryNode(); virtual ~CryNode();
// TODO grandparent is only needed to set the timestamps of the parent directory on rename and remove. Delete grandparent parameter once we store timestamps in the blob itself instead of in the directory listing. // TODO grandparent is only needed to set the timestamps of the parent directory on rename and remove. Delete grandparent parameter once we store timestamps in the blob itself instead of in the directory listing.
CryNode(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::Key &key); CryNode(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId);
void access(int mask) const override; void access(int mask) const override;
void stat(struct ::stat *result) const override; void stat(struct ::stat *result) const override;
void chmod(mode_t mode) override; void chmod(mode_t mode) override;
@ -31,7 +31,7 @@ protected:
CryDevice *device(); CryDevice *device();
const CryDevice *device() const; const CryDevice *device() const;
const blockstore::Key &key() const; const blockstore::BlockId &blockId() const;
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> LoadBlob() const; cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> LoadBlob() const;
bool isRootDir() const; bool isRootDir() const;
std::shared_ptr<const parallelaccessfsblobstore::DirBlobRef> parent() const; std::shared_ptr<const parallelaccessfsblobstore::DirBlobRef> parent() const;
@ -49,7 +49,7 @@ private:
CryDevice *_device; CryDevice *_device;
boost::optional<std::shared_ptr<parallelaccessfsblobstore::DirBlobRef>> _parent; boost::optional<std::shared_ptr<parallelaccessfsblobstore::DirBlobRef>> _parent;
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> _grandparent; boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> _grandparent;
blockstore::Key _key; blockstore::BlockId _blockId;
DISALLOW_COPY_AND_ASSIGN(CryNode); DISALLOW_COPY_AND_ASSIGN(CryNode);
}; };

View File

@ -36,24 +36,24 @@ void CryOpenFile::flush() {
void CryOpenFile::stat(struct ::stat *result) const { void CryOpenFile::stat(struct ::stat *result) const {
_device->callFsActionCallbacks(); _device->callFsActionCallbacks();
result->st_size = _fileBlob->size(); result->st_size = _fileBlob->size();
_parent->statChildWithSizeAlreadySet(_fileBlob->key(), result); _parent->statChildWithSizeAlreadySet(_fileBlob->blockId(), result);
} }
void CryOpenFile::truncate(off_t size) const { void CryOpenFile::truncate(off_t size) const {
_device->callFsActionCallbacks(); _device->callFsActionCallbacks();
_fileBlob->resize(size); _fileBlob->resize(size);
_parent->updateModificationTimestampForChild(_fileBlob->key()); _parent->updateModificationTimestampForChild(_fileBlob->blockId());
} }
size_t CryOpenFile::read(void *buf, size_t count, off_t offset) const { size_t CryOpenFile::read(void *buf, size_t count, off_t offset) const {
_device->callFsActionCallbacks(); _device->callFsActionCallbacks();
_parent->updateAccessTimestampForChild(_fileBlob->key(), fsblobstore::TimestampUpdateBehavior::RELATIME); _parent->updateAccessTimestampForChild(_fileBlob->blockId(), fsblobstore::TimestampUpdateBehavior::RELATIME);
return _fileBlob->read(buf, offset, count); return _fileBlob->read(buf, offset, count);
} }
void CryOpenFile::write(const void *buf, size_t count, off_t offset) { void CryOpenFile::write(const void *buf, size_t count, off_t offset) {
_device->callFsActionCallbacks(); _device->callFsActionCallbacks();
_parent->updateModificationTimestampForChild(_fileBlob->key()); _parent->updateModificationTimestampForChild(_fileBlob->blockId());
_fileBlob->write(buf, offset, count); _fileBlob->write(buf, offset, count);
} }

View File

@ -15,7 +15,7 @@ namespace bf = boost::filesystem;
using std::string; using std::string;
using std::vector; using std::vector;
using blockstore::Key; using blockstore::BlockId;
using boost::none; using boost::none;
using boost::optional; using boost::optional;
using cpputils::unique_ref; using cpputils::unique_ref;
@ -26,8 +26,8 @@ using cryfs::parallelaccessfsblobstore::DirBlobRef;
namespace cryfs { namespace cryfs {
CrySymlink::CrySymlink(CryDevice *device, unique_ref<DirBlobRef> parent, optional<unique_ref<DirBlobRef>> grandparent, const Key &key) CrySymlink::CrySymlink(CryDevice *device, unique_ref<DirBlobRef> parent, optional<unique_ref<DirBlobRef>> grandparent, const BlockId &blockId)
: CryNode(device, std::move(parent), std::move(grandparent), key) { : CryNode(device, std::move(parent), std::move(grandparent), blockId) {
} }
CrySymlink::~CrySymlink() { CrySymlink::~CrySymlink() {
@ -47,7 +47,7 @@ fspp::Dir::EntryType CrySymlink::getType() const {
bf::path CrySymlink::target() { bf::path CrySymlink::target() {
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
parent()->updateAccessTimestampForChild(key(), fsblobstore::TimestampUpdateBehavior::RELATIME); parent()->updateAccessTimestampForChild(blockId(), fsblobstore::TimestampUpdateBehavior::RELATIME);
auto blob = LoadBlob(); auto blob = LoadBlob();
return blob->target(); return blob->target();
} }
@ -56,7 +56,7 @@ void CrySymlink::remove() {
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
if (grandparent() != none) { if (grandparent() != none) {
//TODO Instead of doing nothing when we're in the root directory, handle timestamps in the root dir correctly //TODO Instead of doing nothing when we're in the root directory, handle timestamps in the root dir correctly
(*grandparent())->updateModificationTimestampForChild(parent()->key()); (*grandparent())->updateModificationTimestampForChild(parent()->blockId());
} }
removeNode(); removeNode();
} }

View File

@ -11,7 +11,7 @@ namespace cryfs {
class CrySymlink final: public fspp::Symlink, public CryNode { class CrySymlink final: public fspp::Symlink, public CryNode {
public: public:
CrySymlink(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::Key &key); CrySymlink(CryDevice *device, cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId);
~CrySymlink(); ~CrySymlink();
boost::filesystem::path target() override; boost::filesystem::path target() override;

View File

@ -6,7 +6,7 @@ using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
using cpputils::dynamic_pointer_move; using cpputils::dynamic_pointer_move;
using blobstore::BlobStore; using blobstore::BlobStore;
using blockstore::Key; using blockstore::BlockId;
using boost::optional; using boost::optional;
using boost::none; using boost::none;
using std::function; using std::function;
@ -19,12 +19,12 @@ using cryfs::fsblobstore::SymlinkBlob;
namespace cryfs { namespace cryfs {
namespace cachingfsblobstore { namespace cachingfsblobstore {
optional<unique_ref<FsBlobRef>> CachingFsBlobStore::load(const Key &key) { optional<unique_ref<FsBlobRef>> CachingFsBlobStore::load(const BlockId &blockId) {
auto fromCache = _cache.pop(key); auto fromCache = _cache.pop(blockId);
if (fromCache != none) { if (fromCache != none) {
return _makeRef(std::move(*fromCache)); return _makeRef(std::move(*fromCache));
} }
auto fromBaseStore = _baseBlobStore->load(key); auto fromBaseStore = _baseBlobStore->load(blockId);
if (fromBaseStore != none) { if (fromBaseStore != none) {
return _makeRef(std::move(*fromBaseStore)); return _makeRef(std::move(*fromBaseStore));
} }

View File

@ -19,12 +19,12 @@ namespace cryfs {
CachingFsBlobStore(cpputils::unique_ref<fsblobstore::FsBlobStore> baseBlobStore); CachingFsBlobStore(cpputils::unique_ref<fsblobstore::FsBlobStore> baseBlobStore);
~CachingFsBlobStore(); ~CachingFsBlobStore();
cpputils::unique_ref<FileBlobRef> createFileBlob(const blockstore::Key &parent); cpputils::unique_ref<FileBlobRef> createFileBlob(const blockstore::BlockId &parent);
cpputils::unique_ref<DirBlobRef> createDirBlob(const blockstore::Key &parent); cpputils::unique_ref<DirBlobRef> createDirBlob(const blockstore::BlockId &parent);
cpputils::unique_ref<SymlinkBlobRef> createSymlinkBlob(const boost::filesystem::path &target, const blockstore::Key &parent); cpputils::unique_ref<SymlinkBlobRef> createSymlinkBlob(const boost::filesystem::path &target, const blockstore::BlockId &parent);
boost::optional<cpputils::unique_ref<FsBlobRef>> load(const blockstore::Key &key); boost::optional<cpputils::unique_ref<FsBlobRef>> load(const blockstore::BlockId &blockId);
void remove(cpputils::unique_ref<FsBlobRef> blob); void remove(cpputils::unique_ref<FsBlobRef> blob);
void remove(const blockstore::Key &key); void remove(const blockstore::BlockId &blockId);
uint64_t virtualBlocksizeBytes() const; uint64_t virtualBlocksizeBytes() const;
uint64_t numBlocks() const; uint64_t numBlocks() const;
uint64_t estimateSpaceForNumBlocksLeft() const; uint64_t estimateSpaceForNumBlocksLeft() const;
@ -38,7 +38,7 @@ namespace cryfs {
//TODO Move Cache to some common location, not in blockstore //TODO Move Cache to some common location, not in blockstore
//TODO Use other cache config (i.e. smaller max number of entries) here than in blockstore //TODO Use other cache config (i.e. smaller max number of entries) here than in blockstore
blockstore::caching::Cache<blockstore::Key, cpputils::unique_ref<fsblobstore::FsBlob>, 50> _cache; blockstore::caching::Cache<blockstore::BlockId, cpputils::unique_ref<fsblobstore::FsBlob>, 50> _cache;
DISALLOW_COPY_AND_ASSIGN(CachingFsBlobStore); DISALLOW_COPY_AND_ASSIGN(CachingFsBlobStore);
}; };
@ -51,21 +51,21 @@ namespace cryfs {
inline CachingFsBlobStore::~CachingFsBlobStore() { inline CachingFsBlobStore::~CachingFsBlobStore() {
} }
inline cpputils::unique_ref<FileBlobRef> CachingFsBlobStore::createFileBlob(const blockstore::Key &parent) { inline cpputils::unique_ref<FileBlobRef> CachingFsBlobStore::createFileBlob(const blockstore::BlockId &parent) {
// This already creates the file blob in the underlying blobstore. // This already creates the file blob in the underlying blobstore.
// We could also cache this operation, but that is more complicated (blockstore::CachingBlockStore does it) // We could also cache this operation, but that is more complicated (blockstore::CachingBlockStore does it)
// and probably not worth it here. // and probably not worth it here.
return cpputils::make_unique_ref<FileBlobRef>(_baseBlobStore->createFileBlob(parent), this); return cpputils::make_unique_ref<FileBlobRef>(_baseBlobStore->createFileBlob(parent), this);
} }
inline cpputils::unique_ref<DirBlobRef> CachingFsBlobStore::createDirBlob(const blockstore::Key &parent) { inline cpputils::unique_ref<DirBlobRef> CachingFsBlobStore::createDirBlob(const blockstore::BlockId &parent) {
// This already creates the file blob in the underlying blobstore. // This already creates the file blob in the underlying blobstore.
// We could also cache this operation, but that is more complicated (blockstore::CachingBlockStore does it) // We could also cache this operation, but that is more complicated (blockstore::CachingBlockStore does it)
// and probably not worth it here. // and probably not worth it here.
return cpputils::make_unique_ref<DirBlobRef>(_baseBlobStore->createDirBlob(parent), this); return cpputils::make_unique_ref<DirBlobRef>(_baseBlobStore->createDirBlob(parent), this);
} }
inline cpputils::unique_ref<SymlinkBlobRef> CachingFsBlobStore::createSymlinkBlob(const boost::filesystem::path &target, const blockstore::Key &parent) { inline cpputils::unique_ref<SymlinkBlobRef> CachingFsBlobStore::createSymlinkBlob(const boost::filesystem::path &target, const blockstore::BlockId &parent) {
// This already creates the file blob in the underlying blobstore. // This already creates the file blob in the underlying blobstore.
// We could also cache this operation, but that is more complicated (blockstore::CachingBlockStore does it) // We could also cache this operation, but that is more complicated (blockstore::CachingBlockStore does it)
// and probably not worth it here. // and probably not worth it here.
@ -77,18 +77,18 @@ namespace cryfs {
return _baseBlobStore->remove(std::move(baseBlob)); return _baseBlobStore->remove(std::move(baseBlob));
} }
inline void CachingFsBlobStore::remove(const blockstore::Key &key) { inline void CachingFsBlobStore::remove(const blockstore::BlockId &blockId) {
auto fromCache = _cache.pop(key); auto fromCache = _cache.pop(blockId);
if (fromCache != boost::none) { if (fromCache != boost::none) {
remove(_makeRef(std::move(*fromCache))); remove(_makeRef(std::move(*fromCache)));
} else { } else {
_baseBlobStore->remove(key); _baseBlobStore->remove(blockId);
} }
} }
inline void CachingFsBlobStore::releaseForCache(cpputils::unique_ref<fsblobstore::FsBlob> baseBlob) { inline void CachingFsBlobStore::releaseForCache(cpputils::unique_ref<fsblobstore::FsBlob> baseBlob) {
blockstore::Key key = baseBlob->key(); blockstore::BlockId blockId = baseBlob->blockId();
_cache.push(key, std::move(baseBlob)); _cache.push(blockId, std::move(baseBlob));
} }
inline uint64_t CachingFsBlobStore::virtualBlocksizeBytes() const { inline uint64_t CachingFsBlobStore::virtualBlocksizeBytes() const {

View File

@ -23,16 +23,16 @@ public:
return _base->GetChild(name); return _base->GetChild(name);
} }
boost::optional<const Entry&> GetChild(const blockstore::Key &key) const { boost::optional<const Entry&> GetChild(const blockstore::BlockId &blockId) const {
return _base->GetChild(key); return _base->GetChild(blockId);
} }
size_t NumChildren() const { size_t NumChildren() const {
return _base->NumChildren(); return _base->NumChildren();
} }
void RemoveChild(const blockstore::Key &key) { void RemoveChild(const blockstore::BlockId &blockId) {
return _base->RemoveChild(key); return _base->RemoveChild(blockId);
} }
void RemoveChild(const std::string &name) { void RemoveChild(const std::string &name) {
@ -43,69 +43,69 @@ public:
return _base->flush(); return _base->flush();
} }
void AddOrOverwriteChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type, void AddOrOverwriteChild(const std::string &name, const blockstore::BlockId &blobId, fspp::Dir::EntryType type,
mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime,
std::function<void (const blockstore::Key &key)> onOverwritten) { std::function<void (const blockstore::BlockId &blockId)> onOverwritten) {
return _base->AddOrOverwriteChild(name, blobKey, type, mode, uid, gid, lastAccessTime, lastModificationTime, onOverwritten); return _base->AddOrOverwriteChild(name, blobId, type, mode, uid, gid, lastAccessTime, lastModificationTime, onOverwritten);
} }
void RenameChild(const blockstore::Key &key, const std::string &newName, std::function<void (const blockstore::Key &key)> onOverwritten) { void RenameChild(const blockstore::BlockId &blockId, const std::string &newName, std::function<void (const blockstore::BlockId &blockId)> onOverwritten) {
return _base->RenameChild(key, newName, onOverwritten); return _base->RenameChild(blockId, newName, onOverwritten);
} }
void statChild(const blockstore::Key &key, struct ::stat *result) const { void statChild(const blockstore::BlockId &blockId, struct ::stat *result) const {
return _base->statChild(key, result); return _base->statChild(blockId, result);
} }
void statChildWithSizeAlreadySet(const blockstore::Key &key, struct ::stat *result) const { void statChildWithSizeAlreadySet(const blockstore::BlockId &blockId, struct ::stat *result) const {
return _base->statChildWithSizeAlreadySet(key, result); return _base->statChildWithSizeAlreadySet(blockId, result);
} }
void updateAccessTimestampForChild(const blockstore::Key &key, fsblobstore::TimestampUpdateBehavior timestampUpdateBehavior) { void updateAccessTimestampForChild(const blockstore::BlockId &blockId, fsblobstore::TimestampUpdateBehavior timestampUpdateBehavior) {
return _base->updateAccessTimestampForChild(key, timestampUpdateBehavior); return _base->updateAccessTimestampForChild(blockId, timestampUpdateBehavior);
} }
void updateModificationTimestampForChild(const blockstore::Key &key) { void updateModificationTimestampForChild(const blockstore::BlockId &blockId) {
return _base->updateModificationTimestampForChild(key); return _base->updateModificationTimestampForChild(blockId);
} }
void chmodChild(const blockstore::Key &key, mode_t mode) { void chmodChild(const blockstore::BlockId &blockId, mode_t mode) {
return _base->chmodChild(key, mode); return _base->chmodChild(blockId, mode);
} }
void chownChild(const blockstore::Key &key, uid_t uid, gid_t gid) { void chownChild(const blockstore::BlockId &blockId, uid_t uid, gid_t gid) {
return _base->chownChild(key, uid, gid); return _base->chownChild(blockId, uid, gid);
} }
void utimensChild(const blockstore::Key &key, timespec lastAccessTime, timespec lastModificationTime) { void utimensChild(const blockstore::BlockId &blockId, timespec lastAccessTime, timespec lastModificationTime) {
return _base->utimensChild(key, lastAccessTime, lastModificationTime); return _base->utimensChild(blockId, lastAccessTime, lastModificationTime);
} }
void AddChildDir(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { void AddChildDir(const std::string &name, const blockstore::BlockId &blobId, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
return _base->AddChildDir(name, blobKey, mode, uid, gid, lastAccessTime, lastModificationTime); return _base->AddChildDir(name, blobId, mode, uid, gid, lastAccessTime, lastModificationTime);
} }
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { void AddChildFile(const std::string &name, const blockstore::BlockId &blobId, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
return _base->AddChildFile(name, blobKey, mode, uid, gid, lastAccessTime, lastModificationTime); return _base->AddChildFile(name, blobId, mode, uid, gid, lastAccessTime, lastModificationTime);
} }
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { void AddChildSymlink(const std::string &name, const blockstore::BlockId &blobId, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
return _base->AddChildSymlink(name, blobKey, uid, gid, lastAccessTime, lastModificationTime); return _base->AddChildSymlink(name, blobId, uid, gid, lastAccessTime, lastModificationTime);
} }
void AppendChildrenTo(std::vector<fspp::Dir::Entry> *result) const { void AppendChildrenTo(std::vector<fspp::Dir::Entry> *result) const {
return _base->AppendChildrenTo(result); return _base->AppendChildrenTo(result);
} }
const blockstore::Key &key() const { const blockstore::BlockId &blockId() const {
return _base->key(); return _base->blockId();
} }
off_t lstat_size() const { off_t lstat_size() const {
return _base->lstat_size(); return _base->lstat_size();
} }
void setLstatSizeGetter(std::function<off_t(const blockstore::Key&)> getLstatSize) { void setLstatSizeGetter(std::function<off_t(const blockstore::BlockId&)> getLstatSize) {
return _base->setLstatSizeGetter(getLstatSize); return _base->setLstatSizeGetter(getLstatSize);
} }

View File

@ -36,8 +36,8 @@ public:
return _base->flush(); return _base->flush();
} }
const blockstore::Key &key() const { const blockstore::BlockId &blockId() const {
return _base->key(); return _base->blockId();
} }
off_t lstat_size() const { off_t lstat_size() const {

View File

@ -12,15 +12,15 @@ class CachingFsBlobStore;
class FsBlobRef { class FsBlobRef {
public: public:
virtual ~FsBlobRef(); virtual ~FsBlobRef();
virtual const blockstore::Key &key() const = 0; virtual const blockstore::BlockId &blockId() const = 0;
virtual off_t lstat_size() const = 0; virtual off_t lstat_size() const = 0;
const blockstore::Key &parentPointer() const { const blockstore::BlockId &parentPointer() const {
return _baseBlob->parentPointer(); return _baseBlob->parentPointer();
} }
void setParentPointer(const blockstore::Key &parentKey) { void setParentPointer(const blockstore::BlockId &parentBlobId) {
return _baseBlob->setParentPointer(parentKey); return _baseBlob->setParentPointer(parentBlobId);
} }
cpputils::unique_ref<fsblobstore::FsBlob> releaseBaseBlob() { cpputils::unique_ref<fsblobstore::FsBlob> releaseBaseBlob() {

View File

@ -20,8 +20,8 @@ public:
return _base->target(); return _base->target();
} }
const blockstore::Key &key() const { const blockstore::BlockId &blockId() const {
return _base->key(); return _base->blockId();
} }
off_t lstat_size() const { off_t lstat_size() const {

View File

@ -17,7 +17,7 @@ using std::pair;
using std::make_pair; using std::make_pair;
using blobstore::Blob; using blobstore::Blob;
using blockstore::Key; using blockstore::BlockId;
using cpputils::Data; using cpputils::Data;
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
@ -28,7 +28,7 @@ namespace fsblobstore {
constexpr off_t DirBlob::DIR_LSTAT_SIZE; constexpr off_t DirBlob::DIR_LSTAT_SIZE;
DirBlob::DirBlob(FsBlobStore *fsBlobStore, unique_ref<Blob> blob, std::function<off_t (const blockstore::Key&)> getLstatSize) : DirBlob::DirBlob(FsBlobStore *fsBlobStore, unique_ref<Blob> blob, std::function<off_t (const blockstore::BlockId&)> getLstatSize) :
FsBlob(std::move(blob)), _fsBlobStore(fsBlobStore), _getLstatSize(getLstatSize), _entries(), _mutex(), _changed(false) { FsBlob(std::move(blob)), _fsBlobStore(fsBlobStore), _getLstatSize(getLstatSize), _entries(), _mutex(), _changed(false) {
ASSERT(baseBlob().blobType() == FsBlobView::BlobType::DIR, "Loaded blob is not a directory"); ASSERT(baseBlob().blobType() == FsBlobView::BlobType::DIR, "Loaded blob is not a directory");
_readEntriesFromBlob(); _readEntriesFromBlob();
@ -45,7 +45,7 @@ void DirBlob::flush() {
baseBlob().flush(); baseBlob().flush();
} }
unique_ref<DirBlob> DirBlob::InitializeEmptyDir(FsBlobStore *fsBlobStore, unique_ref<Blob> blob, const blockstore::Key &parent, std::function<off_t(const blockstore::Key&)> getLstatSize) { unique_ref<DirBlob> DirBlob::InitializeEmptyDir(FsBlobStore *fsBlobStore, unique_ref<Blob> blob, const blockstore::BlockId &parent, std::function<off_t(const blockstore::BlockId&)> getLstatSize) {
InitializeBlob(blob.get(), FsBlobView::BlobType::DIR, parent); InitializeBlob(blob.get(), FsBlobView::BlobType::DIR, parent);
return make_unique_ref<DirBlob>(fsBlobStore, std::move(blob), getLstatSize); return make_unique_ref<DirBlob>(fsBlobStore, std::move(blob), getLstatSize);
} }
@ -65,38 +65,38 @@ void DirBlob::_readEntriesFromBlob() {
_entries.deserializeFrom(static_cast<uint8_t*>(data.data()), data.size()); _entries.deserializeFrom(static_cast<uint8_t*>(data.data()), data.size());
} }
void DirBlob::AddChildDir(const std::string &name, const Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { void DirBlob::AddChildDir(const std::string &name, const BlockId &blobId, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_addChild(name, blobKey, fspp::Dir::EntryType::DIR, mode, uid, gid, lastAccessTime, lastModificationTime); _addChild(name, blobId, fspp::Dir::EntryType::DIR, mode, uid, gid, lastAccessTime, lastModificationTime);
} }
void DirBlob::AddChildFile(const std::string &name, const Key &blobKey, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { void DirBlob::AddChildFile(const std::string &name, const BlockId &blobId, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_addChild(name, blobKey, fspp::Dir::EntryType::FILE, mode, uid, gid, lastAccessTime, lastModificationTime); _addChild(name, blobId, fspp::Dir::EntryType::FILE, mode, uid, gid, lastAccessTime, lastModificationTime);
} }
void DirBlob::AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { void DirBlob::AddChildSymlink(const std::string &name, const blockstore::BlockId &blobId, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_addChild(name, blobKey, fspp::Dir::EntryType::SYMLINK, S_IFLNK | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH, uid, gid, lastAccessTime, lastModificationTime); _addChild(name, blobId, fspp::Dir::EntryType::SYMLINK, S_IFLNK | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH, uid, gid, lastAccessTime, lastModificationTime);
} }
void DirBlob::_addChild(const std::string &name, const Key &blobKey, void DirBlob::_addChild(const std::string &name, const BlockId &blobId,
fspp::Dir::EntryType entryType, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { fspp::Dir::EntryType entryType, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
_entries.add(name, blobKey, entryType, mode, uid, gid, lastAccessTime, lastModificationTime); _entries.add(name, blobId, entryType, mode, uid, gid, lastAccessTime, lastModificationTime);
_changed = true; _changed = true;
} }
void DirBlob::AddOrOverwriteChild(const std::string &name, const Key &blobKey, fspp::Dir::EntryType entryType, void DirBlob::AddOrOverwriteChild(const std::string &name, const BlockId &blobId, fspp::Dir::EntryType entryType,
mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime,
std::function<void (const blockstore::Key &key)> onOverwritten) { std::function<void (const blockstore::BlockId &blockId)> onOverwritten) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_entries.addOrOverwrite(name, blobKey, entryType, mode, uid, gid, lastAccessTime, lastModificationTime, onOverwritten); _entries.addOrOverwrite(name, blobId, entryType, mode, uid, gid, lastAccessTime, lastModificationTime, onOverwritten);
_changed = true; _changed = true;
} }
void DirBlob::RenameChild(const blockstore::Key &key, const std::string &newName, std::function<void (const blockstore::Key &key)> onOverwritten) { void DirBlob::RenameChild(const blockstore::BlockId &blockId, const std::string &newName, std::function<void (const blockstore::BlockId &blockId)> onOverwritten) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_entries.rename(key, newName, onOverwritten); _entries.rename(blockId, newName, onOverwritten);
_changed = true; _changed = true;
} }
@ -105,9 +105,9 @@ boost::optional<const DirEntry&> DirBlob::GetChild(const string &name) const {
return _entries.get(name); return _entries.get(name);
} }
boost::optional<const DirEntry&> DirBlob::GetChild(const Key &key) const { boost::optional<const DirEntry&> DirBlob::GetChild(const BlockId &blockId) const {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
return _entries.get(key); return _entries.get(blockId);
} }
void DirBlob::RemoveChild(const string &name) { void DirBlob::RemoveChild(const string &name) {
@ -116,9 +116,9 @@ void DirBlob::RemoveChild(const string &name) {
_changed = true; _changed = true;
} }
void DirBlob::RemoveChild(const Key &key) { void DirBlob::RemoveChild(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_entries.remove(key); _entries.remove(blockId);
_changed = true; _changed = true;
} }
@ -134,13 +134,13 @@ off_t DirBlob::lstat_size() const {
return DIR_LSTAT_SIZE; return DIR_LSTAT_SIZE;
} }
void DirBlob::statChild(const Key &key, struct ::stat *result) const { void DirBlob::statChild(const BlockId &blockId, struct ::stat *result) const {
result->st_size = _getLstatSize(key); result->st_size = _getLstatSize(blockId);
statChildWithSizeAlreadySet(key, result); statChildWithSizeAlreadySet(blockId, result);
} }
void DirBlob::statChildWithSizeAlreadySet(const Key &key, struct ::stat *result) const { void DirBlob::statChildWithSizeAlreadySet(const BlockId &blockId, struct ::stat *result) const {
auto childOpt = GetChild(key); auto childOpt = GetChild(blockId);
if (childOpt == boost::none) { if (childOpt == boost::none) {
throw fspp::fuse::FuseErrnoException(ENOENT); throw fspp::fuse::FuseErrnoException(ENOENT);
} }
@ -158,39 +158,39 @@ void DirBlob::statChildWithSizeAlreadySet(const Key &key, struct ::stat *result)
result->st_blksize = _fsBlobStore->virtualBlocksizeBytes(); result->st_blksize = _fsBlobStore->virtualBlocksizeBytes();
} }
void DirBlob::updateAccessTimestampForChild(const Key &key, TimestampUpdateBehavior timestampUpdateBehavior) { void DirBlob::updateAccessTimestampForChild(const BlockId &blockId, TimestampUpdateBehavior timestampUpdateBehavior) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
if (_entries.updateAccessTimestampForChild(key, timestampUpdateBehavior)) { if (_entries.updateAccessTimestampForChild(blockId, timestampUpdateBehavior)) {
_changed = true; _changed = true;
} }
} }
void DirBlob::updateModificationTimestampForChild(const Key &key) { void DirBlob::updateModificationTimestampForChild(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_entries.updateModificationTimestampForChild(key); _entries.updateModificationTimestampForChild(blockId);
_changed = true; _changed = true;
} }
void DirBlob::chmodChild(const Key &key, mode_t mode) { void DirBlob::chmodChild(const BlockId &blockId, mode_t mode) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_entries.setMode(key, mode); _entries.setMode(blockId, mode);
_changed = true; _changed = true;
} }
void DirBlob::chownChild(const Key &key, uid_t uid, gid_t gid) { void DirBlob::chownChild(const BlockId &blockId, uid_t uid, gid_t gid) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
if(_entries.setUidGid(key, uid, gid)) { if(_entries.setUidGid(blockId, uid, gid)) {
_changed = true; _changed = true;
} }
} }
void DirBlob::utimensChild(const Key &key, timespec lastAccessTime, timespec lastModificationTime) { void DirBlob::utimensChild(const BlockId &blockId, timespec lastAccessTime, timespec lastModificationTime) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_entries.setAccessTimes(key, lastAccessTime, lastModificationTime); _entries.setAccessTimes(blockId, lastAccessTime, lastModificationTime);
_changed = true; _changed = true;
} }
void DirBlob::setLstatSizeGetter(std::function<off_t(const blockstore::Key&)> getLstatSize) { void DirBlob::setLstatSizeGetter(std::function<off_t(const blockstore::BlockId&)> getLstatSize) {
std::unique_lock<std::mutex> lock(_mutex); std::unique_lock<std::mutex> lock(_mutex);
_getLstatSize = getLstatSize; _getLstatSize = getLstatSize;
} }

View File

@ -2,7 +2,7 @@
#ifndef MESSMER_CRYFS_FILESYSTEM_FSBLOBSTORE_DIRBLOB_H_ #ifndef MESSMER_CRYFS_FILESYSTEM_FSBLOBSTORE_DIRBLOB_H_
#define MESSMER_CRYFS_FILESYSTEM_FSBLOBSTORE_DIRBLOB_H_ #define MESSMER_CRYFS_FILESYSTEM_FSBLOBSTORE_DIRBLOB_H_
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include <cpp-utils/macros.h> #include <cpp-utils/macros.h>
#include <fspp/fs_interface/Dir.h> #include <fspp/fs_interface/Dir.h>
#include "FsBlob.h" #include "FsBlob.h"
@ -18,10 +18,10 @@ namespace cryfs {
constexpr static off_t DIR_LSTAT_SIZE = 4096; constexpr static off_t DIR_LSTAT_SIZE = 4096;
static cpputils::unique_ref<DirBlob> InitializeEmptyDir(FsBlobStore *fsBlobStore, cpputils::unique_ref<blobstore::Blob> blob, static cpputils::unique_ref<DirBlob> InitializeEmptyDir(FsBlobStore *fsBlobStore, cpputils::unique_ref<blobstore::Blob> blob,
const blockstore::Key &parent, const blockstore::BlockId &parent,
std::function<off_t (const blockstore::Key&)> getLstatSize); std::function<off_t (const blockstore::BlockId&)> getLstatSize);
DirBlob(FsBlobStore *fsBlobStore, cpputils::unique_ref<blobstore::Blob> blob, std::function<off_t (const blockstore::Key&)> getLstatSize); DirBlob(FsBlobStore *fsBlobStore, cpputils::unique_ref<blobstore::Blob> blob, std::function<off_t (const blockstore::BlockId&)> getLstatSize);
~DirBlob(); ~DirBlob();
@ -34,47 +34,47 @@ namespace cryfs {
boost::optional<const DirEntry&> GetChild(const std::string &name) const; boost::optional<const DirEntry&> GetChild(const std::string &name) const;
boost::optional<const DirEntry&> GetChild(const blockstore::Key &key) const; boost::optional<const DirEntry&> GetChild(const blockstore::BlockId &blobId) const;
void AddChildDir(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, void AddChildDir(const std::string &name, const blockstore::BlockId &blobId, mode_t mode, uid_t uid,
gid_t gid, timespec lastAccessTime, timespec lastModificationTime); gid_t gid, timespec lastAccessTime, timespec lastModificationTime);
void AddChildFile(const std::string &name, const blockstore::Key &blobKey, mode_t mode, uid_t uid, void AddChildFile(const std::string &name, const blockstore::BlockId &blobId, mode_t mode, uid_t uid,
gid_t gid, timespec lastAccessTime, timespec lastModificationTime); gid_t gid, timespec lastAccessTime, timespec lastModificationTime);
void AddChildSymlink(const std::string &name, const blockstore::Key &blobKey, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime); void AddChildSymlink(const std::string &name, const blockstore::BlockId &blobId, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime);
void AddOrOverwriteChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type, void AddOrOverwriteChild(const std::string &name, const blockstore::BlockId &blobId, fspp::Dir::EntryType type,
mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime, mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime,
std::function<void (const blockstore::Key &key)> onOverwritten); std::function<void (const blockstore::BlockId &blockId)> onOverwritten);
void RenameChild(const blockstore::Key &key, const std::string &newName, std::function<void (const blockstore::Key &key)> onOverwritten); void RenameChild(const blockstore::BlockId &blockId, const std::string &newName, std::function<void (const blockstore::BlockId &blockId)> onOverwritten);
void RemoveChild(const std::string &name); void RemoveChild(const std::string &name);
void RemoveChild(const blockstore::Key &key); void RemoveChild(const blockstore::BlockId &blockId);
void flush(); void flush();
void statChild(const blockstore::Key &key, struct ::stat *result) const; void statChild(const blockstore::BlockId &blockId, struct ::stat *result) const;
void statChildWithSizeAlreadySet(const blockstore::Key &key, struct ::stat *result) const; void statChildWithSizeAlreadySet(const blockstore::BlockId &blockId, struct ::stat *result) const;
void updateAccessTimestampForChild(const blockstore::Key &key, TimestampUpdateBehavior timestampUpdateBehavior); void updateAccessTimestampForChild(const blockstore::BlockId &blockId, TimestampUpdateBehavior timestampUpdateBehavior);
void updateModificationTimestampForChild(const blockstore::Key &key); void updateModificationTimestampForChild(const blockstore::BlockId &blockId);
void chmodChild(const blockstore::Key &key, mode_t mode); void chmodChild(const blockstore::BlockId &blockId, mode_t mode);
void chownChild(const blockstore::Key &key, uid_t uid, gid_t gid); void chownChild(const blockstore::BlockId &blockId, uid_t uid, gid_t gid);
void utimensChild(const blockstore::Key &key, timespec lastAccessTime, timespec lastModificationTime); void utimensChild(const blockstore::BlockId &blockId, timespec lastAccessTime, timespec lastModificationTime);
void setLstatSizeGetter(std::function<off_t(const blockstore::Key&)> getLstatSize); void setLstatSizeGetter(std::function<off_t(const blockstore::BlockId&)> getLstatSize);
private: private:
void _addChild(const std::string &name, const blockstore::Key &blobKey, fspp::Dir::EntryType type, void _addChild(const std::string &name, const blockstore::BlockId &blobId, fspp::Dir::EntryType type,
mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime); mode_t mode, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime);
void _readEntriesFromBlob(); void _readEntriesFromBlob();
void _writeEntriesToBlob(); void _writeEntriesToBlob();
@ -82,7 +82,7 @@ namespace cryfs {
cpputils::unique_ref<blobstore::Blob> releaseBaseBlob() override; cpputils::unique_ref<blobstore::Blob> releaseBaseBlob() override;
FsBlobStore *_fsBlobStore; FsBlobStore *_fsBlobStore;
std::function<off_t (const blockstore::Key&)> _getLstatSize; std::function<off_t (const blockstore::BlockId&)> _getLstatSize;
DirEntryList _entries; DirEntryList _entries;
mutable std::mutex _mutex; mutable std::mutex _mutex;
bool _changed; bool _changed;

View File

@ -1,12 +1,12 @@
#include "FileBlob.h" #include "FileBlob.h"
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include <cassert> #include <cassert>
using blobstore::Blob; using blobstore::Blob;
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
using blockstore::Key; using blockstore::BlockId;
namespace cryfs { namespace cryfs {
namespace fsblobstore { namespace fsblobstore {
@ -16,7 +16,7 @@ FileBlob::FileBlob(unique_ref<Blob> blob)
ASSERT(baseBlob().blobType() == FsBlobView::BlobType::FILE, "Loaded blob is not a file"); ASSERT(baseBlob().blobType() == FsBlobView::BlobType::FILE, "Loaded blob is not a file");
} }
unique_ref<FileBlob> FileBlob::InitializeEmptyFile(unique_ref<Blob> blob, const blockstore::Key &parent) { unique_ref<FileBlob> FileBlob::InitializeEmptyFile(unique_ref<Blob> blob, const blockstore::BlockId &parent) {
InitializeBlob(blob.get(), FsBlobView::BlobType::FILE, parent); InitializeBlob(blob.get(), FsBlobView::BlobType::FILE, parent);
return make_unique_ref<FileBlob>(std::move(blob)); return make_unique_ref<FileBlob>(std::move(blob));
} }

View File

@ -9,7 +9,7 @@ namespace cryfs {
class FileBlob final: public FsBlob { class FileBlob final: public FsBlob {
public: public:
static cpputils::unique_ref<FileBlob> InitializeEmptyFile(cpputils::unique_ref<blobstore::Blob> blob, const blockstore::Key &parent); static cpputils::unique_ref<FileBlob> InitializeEmptyFile(cpputils::unique_ref<blobstore::Blob> blob, const blockstore::BlockId &parent);
FileBlob(cpputils::unique_ref<blobstore::Blob> blob); FileBlob(cpputils::unique_ref<blobstore::Blob> blob);

View File

@ -13,9 +13,9 @@ namespace cryfs {
virtual ~FsBlob(); virtual ~FsBlob();
virtual off_t lstat_size() const = 0; virtual off_t lstat_size() const = 0;
const blockstore::Key &key() const; const blockstore::BlockId &blockId() const;
const blockstore::Key &parentPointer() const; const blockstore::BlockId &parentPointer() const;
void setParentPointer(const blockstore::Key &parentKey); void setParentPointer(const blockstore::BlockId &parentId);
protected: protected:
FsBlob(cpputils::unique_ref<blobstore::Blob> baseBlob); FsBlob(cpputils::unique_ref<blobstore::Blob> baseBlob);
@ -23,7 +23,7 @@ namespace cryfs {
FsBlobView &baseBlob(); FsBlobView &baseBlob();
const FsBlobView &baseBlob() const; const FsBlobView &baseBlob() const;
static void InitializeBlob(blobstore::Blob *blob, FsBlobView::BlobType magicNumber, const blockstore::Key &parent); static void InitializeBlob(blobstore::Blob *blob, FsBlobView::BlobType magicNumber, const blockstore::BlockId &parent);
friend class FsBlobStore; friend class FsBlobStore;
virtual cpputils::unique_ref<blobstore::Blob> releaseBaseBlob(); virtual cpputils::unique_ref<blobstore::Blob> releaseBaseBlob();
@ -47,8 +47,8 @@ namespace cryfs {
inline FsBlob::~FsBlob() { inline FsBlob::~FsBlob() {
} }
inline const blockstore::Key &FsBlob::key() const { inline const blockstore::BlockId &FsBlob::blockId() const {
return _baseBlob.key(); return _baseBlob.blockId();
} }
inline const FsBlobView &FsBlob::baseBlob() const { inline const FsBlobView &FsBlob::baseBlob() const {
@ -59,7 +59,7 @@ namespace cryfs {
return _baseBlob; return _baseBlob;
} }
inline void FsBlob::InitializeBlob(blobstore::Blob *blob, FsBlobView::BlobType magicNumber, const blockstore::Key &parent) { inline void FsBlob::InitializeBlob(blobstore::Blob *blob, FsBlobView::BlobType magicNumber, const blockstore::BlockId &parent) {
FsBlobView::InitializeBlob(blob, magicNumber, parent); FsBlobView::InitializeBlob(blob, magicNumber, parent);
} }
@ -67,12 +67,12 @@ namespace cryfs {
return _baseBlob.releaseBaseBlob(); return _baseBlob.releaseBaseBlob();
} }
inline const blockstore::Key &FsBlob::parentPointer() const { inline const blockstore::BlockId &FsBlob::parentPointer() const {
return _baseBlob.parentPointer(); return _baseBlob.parentPointer();
} }
inline void FsBlob::setParentPointer(const blockstore::Key &parentKey) { inline void FsBlob::setParentPointer(const blockstore::BlockId &parentId) {
return _baseBlob.setParentPointer(parentKey); return _baseBlob.setParentPointer(parentId);
} }
} }
} }

View File

@ -7,7 +7,7 @@ namespace bf = boost::filesystem;
using cpputils::unique_ref; using cpputils::unique_ref;
using cpputils::make_unique_ref; using cpputils::make_unique_ref;
using blobstore::BlobStore; using blobstore::BlobStore;
using blockstore::Key; using blockstore::BlockId;
using boost::none; using boost::none;
using std::function; using std::function;
using std::vector; using std::vector;
@ -15,8 +15,8 @@ using std::vector;
namespace cryfs { namespace cryfs {
namespace fsblobstore { namespace fsblobstore {
boost::optional<unique_ref<FsBlob>> FsBlobStore::load(const blockstore::Key &key) { boost::optional<unique_ref<FsBlob>> FsBlobStore::load(const blockstore::BlockId &blockId) {
auto blob = _baseBlobStore->load(key); auto blob = _baseBlobStore->load(blockId);
if (blob == none) { if (blob == none) {
return none; return none;
} }
@ -33,8 +33,8 @@ boost::optional<unique_ref<FsBlob>> FsBlobStore::load(const blockstore::Key &key
} }
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
unique_ref<FsBlobStore> FsBlobStore::migrateIfNeeded(unique_ref<BlobStore> blobStore, const blockstore::Key &rootKey) { unique_ref<FsBlobStore> FsBlobStore::migrateIfNeeded(unique_ref<BlobStore> blobStore, const blockstore::BlockId &rootBlobId) {
auto rootBlob = blobStore->load(rootKey); auto rootBlob = blobStore->load(rootBlobId);
ASSERT(rootBlob != none, "Could not load root blob"); ASSERT(rootBlob != none, "Could not load root blob");
uint16_t format = FsBlobView::getFormatVersionHeader(**rootBlob); uint16_t format = FsBlobView::getFormatVersionHeader(**rootBlob);
@ -42,14 +42,14 @@ boost::optional<unique_ref<FsBlob>> FsBlobStore::load(const blockstore::Key &key
if (format == 0) { if (format == 0) {
// migration needed // migration needed
std::cout << "Migrating file system for conflict resolution features. Please don't interrupt this process. This can take a while..." << std::flush; std::cout << "Migrating file system for conflict resolution features. Please don't interrupt this process. This can take a while..." << std::flush;
fsBlobStore->_migrate(std::move(*rootBlob), blockstore::Key::Null()); fsBlobStore->_migrate(std::move(*rootBlob), blockstore::BlockId::Null());
std::cout << "done" << std::endl; std::cout << "done" << std::endl;
} }
return fsBlobStore; return fsBlobStore;
} }
void FsBlobStore::_migrate(unique_ref<blobstore::Blob> node, const blockstore::Key &parentKey) { void FsBlobStore::_migrate(unique_ref<blobstore::Blob> node, const blockstore::BlockId &parentId) {
FsBlobView::migrate(node.get(), parentKey); FsBlobView::migrate(node.get(), parentId);
if (FsBlobView::blobType(*node) == FsBlobView::BlobType::DIR) { if (FsBlobView::blobType(*node) == FsBlobView::BlobType::DIR) {
DirBlob dir(this, std::move(node), _getLstatSize()); DirBlob dir(this, std::move(node), _getLstatSize());
vector<fspp::Dir::Entry> children; vector<fspp::Dir::Entry> children;
@ -57,9 +57,9 @@ boost::optional<unique_ref<FsBlob>> FsBlobStore::load(const blockstore::Key &key
for (const auto &child : children) { for (const auto &child : children) {
auto childEntry = dir.GetChild(child.name); auto childEntry = dir.GetChild(child.name);
ASSERT(childEntry != none, "Couldn't load child, although it was returned as a child in the lsit."); ASSERT(childEntry != none, "Couldn't load child, although it was returned as a child in the lsit.");
auto childBlob = _baseBlobStore->load(childEntry->key()); auto childBlob = _baseBlobStore->load(childEntry->blockId());
ASSERT(childBlob != none, "Couldn't load child blob"); ASSERT(childBlob != none, "Couldn't load child blob");
_migrate(std::move(*childBlob), dir.key()); _migrate(std::move(*childBlob), dir.blockId());
} }
} }
} }

View File

@ -17,28 +17,28 @@ namespace cryfs {
public: public:
FsBlobStore(cpputils::unique_ref<blobstore::BlobStore> baseBlobStore); FsBlobStore(cpputils::unique_ref<blobstore::BlobStore> baseBlobStore);
cpputils::unique_ref<FileBlob> createFileBlob(const blockstore::Key &parent); cpputils::unique_ref<FileBlob> createFileBlob(const blockstore::BlockId &parent);
cpputils::unique_ref<DirBlob> createDirBlob(const blockstore::Key &parent); cpputils::unique_ref<DirBlob> createDirBlob(const blockstore::BlockId &parent);
cpputils::unique_ref<SymlinkBlob> createSymlinkBlob(const boost::filesystem::path &target, const blockstore::Key &parent); cpputils::unique_ref<SymlinkBlob> createSymlinkBlob(const boost::filesystem::path &target, const blockstore::BlockId &parent);
boost::optional<cpputils::unique_ref<FsBlob>> load(const blockstore::Key &key); boost::optional<cpputils::unique_ref<FsBlob>> load(const blockstore::BlockId &blockId);
void remove(cpputils::unique_ref<FsBlob> blob); void remove(cpputils::unique_ref<FsBlob> blob);
void remove(const blockstore::Key &key); void remove(const blockstore::BlockId &blockId);
uint64_t numBlocks() const; uint64_t numBlocks() const;
uint64_t estimateSpaceForNumBlocksLeft() const; uint64_t estimateSpaceForNumBlocksLeft() const;
uint64_t virtualBlocksizeBytes() const; uint64_t virtualBlocksizeBytes() const;
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
static cpputils::unique_ref<FsBlobStore> migrateIfNeeded(cpputils::unique_ref<blobstore::BlobStore> blobStore, const blockstore::Key &rootKey); static cpputils::unique_ref<FsBlobStore> migrateIfNeeded(cpputils::unique_ref<blobstore::BlobStore> blobStore, const blockstore::BlockId &blockId);
#endif #endif
private: private:
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
void _migrate(cpputils::unique_ref<blobstore::Blob> node, const blockstore::Key &parentKey); void _migrate(cpputils::unique_ref<blobstore::Blob> node, const blockstore::BlockId &parentId);
#endif #endif
std::function<off_t(const blockstore::Key &)> _getLstatSize(); std::function<off_t(const blockstore::BlockId &)> _getLstatSize();
cpputils::unique_ref<blobstore::BlobStore> _baseBlobStore; cpputils::unique_ref<blobstore::BlobStore> _baseBlobStore;
@ -49,17 +49,17 @@ namespace cryfs {
: _baseBlobStore(std::move(baseBlobStore)) { : _baseBlobStore(std::move(baseBlobStore)) {
} }
inline cpputils::unique_ref<FileBlob> FsBlobStore::createFileBlob(const blockstore::Key &parent) { inline cpputils::unique_ref<FileBlob> FsBlobStore::createFileBlob(const blockstore::BlockId &parent) {
auto blob = _baseBlobStore->create(); auto blob = _baseBlobStore->create();
return FileBlob::InitializeEmptyFile(std::move(blob), parent); return FileBlob::InitializeEmptyFile(std::move(blob), parent);
} }
inline cpputils::unique_ref<DirBlob> FsBlobStore::createDirBlob(const blockstore::Key &parent) { inline cpputils::unique_ref<DirBlob> FsBlobStore::createDirBlob(const blockstore::BlockId &parent) {
auto blob = _baseBlobStore->create(); auto blob = _baseBlobStore->create();
return DirBlob::InitializeEmptyDir(this, std::move(blob), parent, _getLstatSize()); return DirBlob::InitializeEmptyDir(this, std::move(blob), parent, _getLstatSize());
} }
inline cpputils::unique_ref<SymlinkBlob> FsBlobStore::createSymlinkBlob(const boost::filesystem::path &target, const blockstore::Key &parent) { inline cpputils::unique_ref<SymlinkBlob> FsBlobStore::createSymlinkBlob(const boost::filesystem::path &target, const blockstore::BlockId &parent) {
auto blob = _baseBlobStore->create(); auto blob = _baseBlobStore->create();
return SymlinkBlob::InitializeSymlink(std::move(blob), target, parent); return SymlinkBlob::InitializeSymlink(std::move(blob), target, parent);
} }
@ -76,13 +76,13 @@ namespace cryfs {
_baseBlobStore->remove(blob->releaseBaseBlob()); _baseBlobStore->remove(blob->releaseBaseBlob());
} }
inline void FsBlobStore::remove(const blockstore::Key &key) { inline void FsBlobStore::remove(const blockstore::BlockId &blockId) {
_baseBlobStore->remove(key); _baseBlobStore->remove(blockId);
} }
inline std::function<off_t (const blockstore::Key &)> FsBlobStore::_getLstatSize() { inline std::function<off_t (const blockstore::BlockId &)> FsBlobStore::_getLstatSize() {
return [this] (const blockstore::Key &key) { return [this] (const blockstore::BlockId &blockId) {
auto blob = load(key); auto blob = load(blockId);
ASSERT(blob != boost::none, "Blob not found"); ASSERT(blob != boost::none, "Blob not found");
return (*blob)->lstat_size(); return (*blob)->lstat_size();
}; };

View File

@ -7,16 +7,16 @@ namespace cryfs {
constexpr unsigned int FsBlobView::HEADER_SIZE; constexpr unsigned int FsBlobView::HEADER_SIZE;
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
void FsBlobView::migrate(blobstore::Blob *blob, const blockstore::Key &parentKey) { void FsBlobView::migrate(blobstore::Blob *blob, const blockstore::BlockId &parentId) {
constexpr unsigned int OLD_HEADER_SIZE = sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t); constexpr unsigned int OLD_HEADER_SIZE = sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t);
ASSERT(FsBlobView::getFormatVersionHeader(*blob) == 0, "Block already migrated"); ASSERT(FsBlobView::getFormatVersionHeader(*blob) == 0, "Block already migrated");
// Resize blob and move data back // Resize blob and move data back
cpputils::Data data = blob->readAll(); cpputils::Data data = blob->readAll();
blob->resize(blob->size() + blockstore::Key::BINARY_LENGTH); blob->resize(blob->size() + blockstore::BlockId::BINARY_LENGTH);
blob->write(data.dataOffset(OLD_HEADER_SIZE), HEADER_SIZE, data.size() - OLD_HEADER_SIZE); blob->write(data.dataOffset(OLD_HEADER_SIZE), HEADER_SIZE, data.size() - OLD_HEADER_SIZE);
// Write parent pointer // Write parent pointer
blob->write(parentKey.data().data(), sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t), blockstore::Key::BINARY_LENGTH); blob->write(parentId.data().data(), sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t), blockstore::BlockId::BINARY_LENGTH);
// Update format version number // Update format version number
blob->write(&FORMAT_VERSION_HEADER, 0, sizeof(FORMAT_VERSION_HEADER)); blob->write(&FORMAT_VERSION_HEADER, 0, sizeof(FORMAT_VERSION_HEADER));
} }

View File

@ -17,18 +17,18 @@ namespace cryfs {
SYMLINK = 0x02 SYMLINK = 0x02
}; };
FsBlobView(cpputils::unique_ref<blobstore::Blob> baseBlob): _baseBlob(std::move(baseBlob)), _parentPointer(blockstore::Key::Null()) { FsBlobView(cpputils::unique_ref<blobstore::Blob> baseBlob): _baseBlob(std::move(baseBlob)), _parentPointer(blockstore::BlockId::Null()) {
_checkHeader(*_baseBlob); _checkHeader(*_baseBlob);
_loadParentPointer(); _loadParentPointer();
} }
static void InitializeBlob(blobstore::Blob *baseBlob, BlobType blobType, const blockstore::Key &parent) { static void InitializeBlob(blobstore::Blob *baseBlob, BlobType blobType, const blockstore::BlockId &parent) {
baseBlob->resize(sizeof(FORMAT_VERSION_HEADER) + 1); baseBlob->resize(sizeof(FORMAT_VERSION_HEADER) + 1);
baseBlob->write(&FORMAT_VERSION_HEADER, 0, sizeof(FORMAT_VERSION_HEADER)); baseBlob->write(&FORMAT_VERSION_HEADER, 0, sizeof(FORMAT_VERSION_HEADER));
uint8_t blobTypeInt = static_cast<uint8_t>(blobType); uint8_t blobTypeInt = static_cast<uint8_t>(blobType);
baseBlob->write(&blobTypeInt, sizeof(FORMAT_VERSION_HEADER), sizeof(uint8_t)); baseBlob->write(&blobTypeInt, sizeof(FORMAT_VERSION_HEADER), sizeof(uint8_t));
baseBlob->write(parent.data().data(), sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t), blockstore::Key::BINARY_LENGTH); baseBlob->write(parent.data().data(), sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t), blockstore::BlockId::BINARY_LENGTH);
static_assert(HEADER_SIZE == sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t) + blockstore::Key::BINARY_LENGTH, "If this fails, the header is not initialized correctly in this function."); static_assert(HEADER_SIZE == sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t) + blockstore::BlockId::BINARY_LENGTH, "If this fails, the header is not initialized correctly in this function.");
} }
static BlobType blobType(const blobstore::Blob &blob) { static BlobType blobType(const blobstore::Blob &blob) {
@ -40,17 +40,17 @@ namespace cryfs {
return _blobType(*_baseBlob); return _blobType(*_baseBlob);
} }
const blockstore::Key &parentPointer() const { const blockstore::BlockId &parentPointer() const {
return _parentPointer; return _parentPointer;
} }
void setParentPointer(const blockstore::Key &parentKey) { void setParentPointer(const blockstore::BlockId &parentId) {
_parentPointer = parentKey; _parentPointer = parentId;
_storeParentPointer(); _storeParentPointer();
} }
const blockstore::Key &key() const override { const blockstore::BlockId &blockId() const override {
return _baseBlob->key(); return _baseBlob->blockId();
} }
uint64_t size() const override { uint64_t size() const override {
@ -97,12 +97,12 @@ namespace cryfs {
} }
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
static void migrate(blobstore::Blob *blob, const blockstore::Key &parentKey); static void migrate(blobstore::Blob *blob, const blockstore::BlockId &parentId);
#endif #endif
private: private:
static constexpr uint16_t FORMAT_VERSION_HEADER = 1; static constexpr uint16_t FORMAT_VERSION_HEADER = 1;
static constexpr unsigned int HEADER_SIZE = sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t) + blockstore::Key::BINARY_LENGTH; static constexpr unsigned int HEADER_SIZE = sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t) + blockstore::BlockId::BINARY_LENGTH;
static void _checkHeader(const blobstore::Blob &blob) { static void _checkHeader(const blobstore::Blob &blob) {
uint16_t actualFormatVersion = getFormatVersionHeader(blob); uint16_t actualFormatVersion = getFormatVersionHeader(blob);
@ -118,18 +118,18 @@ namespace cryfs {
} }
void _loadParentPointer() { void _loadParentPointer() {
auto idData = cpputils::FixedSizeData<blockstore::Key::BINARY_LENGTH>::Null(); auto idData = cpputils::FixedSizeData<blockstore::BlockId::BINARY_LENGTH>::Null();
_baseBlob->read(idData.data(), sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t), blockstore::Key::BINARY_LENGTH); _baseBlob->read(idData.data(), sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t), blockstore::BlockId::BINARY_LENGTH);
_parentPointer = blockstore::Key(idData); _parentPointer = blockstore::BlockId(idData);
} }
void _storeParentPointer() { void _storeParentPointer() {
_baseBlob->write(_parentPointer.data().data(), sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t), blockstore::Key::BINARY_LENGTH); _baseBlob->write(_parentPointer.data().data(), sizeof(FORMAT_VERSION_HEADER) + sizeof(uint8_t), blockstore::BlockId::BINARY_LENGTH);
} }
cpputils::unique_ref<blobstore::Blob> _baseBlob; cpputils::unique_ref<blobstore::Blob> _baseBlob;
blockstore::Key _parentPointer; blockstore::BlockId _parentPointer;
DISALLOW_COPY_AND_ASSIGN(FsBlobView); DISALLOW_COPY_AND_ASSIGN(FsBlobView);
}; };

View File

@ -1,6 +1,6 @@
#include "SymlinkBlob.h" #include "SymlinkBlob.h"
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include <cassert> #include <cassert>
using std::string; using std::string;
@ -18,7 +18,7 @@ SymlinkBlob::SymlinkBlob(unique_ref<Blob> blob)
ASSERT(baseBlob().blobType() == FsBlobView::BlobType::SYMLINK, "Loaded blob is not a symlink"); ASSERT(baseBlob().blobType() == FsBlobView::BlobType::SYMLINK, "Loaded blob is not a symlink");
} }
unique_ref<SymlinkBlob> SymlinkBlob::InitializeSymlink(unique_ref<Blob> blob, const bf::path &target, const blockstore::Key &parent) { unique_ref<SymlinkBlob> SymlinkBlob::InitializeSymlink(unique_ref<Blob> blob, const bf::path &target, const blockstore::BlockId &parent) {
InitializeBlob(blob.get(), FsBlobView::BlobType::SYMLINK, parent); InitializeBlob(blob.get(), FsBlobView::BlobType::SYMLINK, parent);
FsBlobView symlinkBlobView(std::move(blob)); FsBlobView symlinkBlobView(std::move(blob));
string targetStr = target.native(); string targetStr = target.native();

View File

@ -11,7 +11,7 @@ namespace cryfs {
class SymlinkBlob final: public FsBlob { class SymlinkBlob final: public FsBlob {
public: public:
static cpputils::unique_ref<SymlinkBlob> InitializeSymlink(cpputils::unique_ref<blobstore::Blob> blob, static cpputils::unique_ref<SymlinkBlob> InitializeSymlink(cpputils::unique_ref<blobstore::Blob> blob,
const boost::filesystem::path &target, const blockstore::Key &parent); const boost::filesystem::path &target, const blockstore::BlockId &parent);
SymlinkBlob(cpputils::unique_ref<blobstore::Blob> blob); SymlinkBlob(cpputils::unique_ref<blobstore::Blob> blob);

View File

@ -2,7 +2,7 @@
using std::vector; using std::vector;
using std::string; using std::string;
using blockstore::Key; using blockstore::BlockId;
namespace cryfs { namespace cryfs {
namespace fsblobstore { namespace fsblobstore {
@ -23,7 +23,7 @@ namespace cryfs {
offset += _serializeTimeValue(dest + offset, _lastModificationTime); offset += _serializeTimeValue(dest + offset, _lastModificationTime);
offset += _serializeTimeValue(dest + offset, _lastMetadataChangeTime); offset += _serializeTimeValue(dest + offset, _lastMetadataChangeTime);
offset += _serializeString(dest + offset, _name); offset += _serializeString(dest + offset, _name);
offset += _serializeKey(dest + offset, _key); offset += _serializeBlockId(dest + offset, _blockId);
ASSERT(offset == serializedSize(), "Didn't write correct number of elements"); ASSERT(offset == serializedSize(), "Didn't write correct number of elements");
} }
@ -36,9 +36,9 @@ namespace cryfs {
timespec lastModificationTime = _deserializeTimeValue(&pos); timespec lastModificationTime = _deserializeTimeValue(&pos);
timespec lastMetadataChangeTime = _deserializeTimeValue(&pos); timespec lastMetadataChangeTime = _deserializeTimeValue(&pos);
string name = _deserializeString(&pos); string name = _deserializeString(&pos);
Key key = _deserializeKey(&pos); BlockId blockId = _deserializeBlockId(&pos);
result->emplace_back(type, name, key, mode, uid, gid, lastAccessTime, lastModificationTime, lastMetadataChangeTime); result->emplace_back(type, name, blockId, mode, uid, gid, lastAccessTime, lastModificationTime, lastMetadataChangeTime);
return pos; return pos;
} }
@ -99,20 +99,20 @@ namespace cryfs {
return value; return value;
} }
unsigned int DirEntry::_serializeKey(uint8_t *dest, const Key &key) { unsigned int DirEntry::_serializeBlockId(uint8_t *dest, const BlockId &blockId) {
key.ToBinary(dest); blockId.ToBinary(dest);
return key.BINARY_LENGTH; return blockId.BINARY_LENGTH;
} }
Key DirEntry::_deserializeKey(const char **pos) { BlockId DirEntry::_deserializeBlockId(const char **pos) {
Key key = Key::FromBinary(*pos); BlockId blockId = BlockId::FromBinary(*pos);
*pos += Key::BINARY_LENGTH; *pos += BlockId::BINARY_LENGTH;
return key; return blockId;
} }
size_t DirEntry::serializedSize() const { size_t DirEntry::serializedSize() const {
return 1 + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + 3*_serializedTimeValueSize() + ( return 1 + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + 3*_serializedTimeValueSize() + (
_name.size() + 1) + _key.BINARY_LENGTH; _name.size() + 1) + _blockId.BINARY_LENGTH;
} }
} }
} }

View File

@ -2,7 +2,7 @@
#ifndef MESSMER_CRYFS_FILESYSTEM_FSBLOBSTORE_UTILS_DIRENTRY_H #ifndef MESSMER_CRYFS_FILESYSTEM_FSBLOBSTORE_UTILS_DIRENTRY_H
#define MESSMER_CRYFS_FILESYSTEM_FSBLOBSTORE_UTILS_DIRENTRY_H #define MESSMER_CRYFS_FILESYSTEM_FSBLOBSTORE_UTILS_DIRENTRY_H
#include <blockstore/utils/Key.h> #include <blockstore/utils/BlockId.h>
#include <fspp/fs_interface/Dir.h> #include <fspp/fs_interface/Dir.h>
#include <cpp-utils/system/time.h> #include <cpp-utils/system/time.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -12,7 +12,7 @@ namespace cryfs {
class DirEntry final { class DirEntry final {
public: public:
DirEntry(fspp::Dir::EntryType type, const std::string &name, const blockstore::Key &key, mode_t mode, DirEntry(fspp::Dir::EntryType type, const std::string &name, const blockstore::BlockId &blockId, mode_t mode,
uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime,
timespec lastMetadataChangeTime); timespec lastMetadataChangeTime);
@ -26,7 +26,7 @@ namespace cryfs {
const std::string &name() const; const std::string &name() const;
void setName(const std::string &value); void setName(const std::string &value);
const blockstore::Key &key() const; const blockstore::BlockId &blockId() const;
mode_t mode() const; mode_t mode() const;
void setMode(mode_t value); void setMode(mode_t value);
@ -51,18 +51,18 @@ namespace cryfs {
static unsigned int _serializeUint8(uint8_t *dest, uint8_t value); static unsigned int _serializeUint8(uint8_t *dest, uint8_t value);
static unsigned int _serializeUint32(uint8_t *dest, uint32_t value); static unsigned int _serializeUint32(uint8_t *dest, uint32_t value);
static unsigned int _serializeString(uint8_t *dest, const std::string &value); static unsigned int _serializeString(uint8_t *dest, const std::string &value);
static unsigned int _serializeKey(uint8_t *dest, const blockstore::Key &value); static unsigned int _serializeBlockId(uint8_t *dest, const blockstore::BlockId &value);
static timespec _deserializeTimeValue(const char **pos); static timespec _deserializeTimeValue(const char **pos);
static uint8_t _deserializeUint8(const char **pos); static uint8_t _deserializeUint8(const char **pos);
static uint32_t _deserializeUint32(const char **pos); static uint32_t _deserializeUint32(const char **pos);
static std::string _deserializeString(const char **pos); static std::string _deserializeString(const char **pos);
static blockstore::Key _deserializeKey(const char **pos); static blockstore::BlockId _deserializeBlockId(const char **pos);
void _updateLastMetadataChangeTime(); void _updateLastMetadataChangeTime();
fspp::Dir::EntryType _type; fspp::Dir::EntryType _type;
std::string _name; std::string _name;
blockstore::Key _key; blockstore::BlockId _blockId;
mode_t _mode; mode_t _mode;
uid_t _uid; uid_t _uid;
gid_t _gid; gid_t _gid;
@ -71,10 +71,10 @@ namespace cryfs {
timespec _lastMetadataChangeTime; timespec _lastMetadataChangeTime;
}; };
inline DirEntry::DirEntry(fspp::Dir::EntryType type, const std::string &name, const blockstore::Key &key, mode_t mode, inline DirEntry::DirEntry(fspp::Dir::EntryType type, const std::string &name, const blockstore::BlockId &blockId, mode_t mode,
uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime,
timespec lastMetadataChangeTime) timespec lastMetadataChangeTime)
: _type(type), _name(name), _key(key), _mode(mode), _uid(uid), _gid(gid), _lastAccessTime(lastAccessTime), : _type(type), _name(name), _blockId(blockId), _mode(mode), _uid(uid), _gid(gid), _lastAccessTime(lastAccessTime),
_lastModificationTime(lastModificationTime), _lastMetadataChangeTime(lastMetadataChangeTime) { _lastModificationTime(lastModificationTime), _lastMetadataChangeTime(lastMetadataChangeTime) {
switch (_type) { switch (_type) {
case fspp::Dir::EntryType::FILE: case fspp::Dir::EntryType::FILE:
@ -100,8 +100,8 @@ namespace cryfs {
return _name; return _name;
} }
inline const blockstore::Key &DirEntry::key() const { inline const blockstore::BlockId &DirEntry::blockId() const {
return _key; return _blockId;
} }
inline mode_t DirEntry::mode() const { inline mode_t DirEntry::mode() const {

View File

@ -8,7 +8,7 @@
using cpputils::Data; using cpputils::Data;
using std::string; using std::string;
using std::vector; using std::vector;
using blockstore::Key; using blockstore::BlockId;
namespace cryfs { namespace cryfs {
namespace fsblobstore { namespace fsblobstore {
@ -20,7 +20,7 @@ Data DirEntryList::serialize() const {
Data serialized(_serializedSize()); Data serialized(_serializedSize());
unsigned int offset = 0; unsigned int offset = 0;
for (auto iter = _entries.begin(); iter != _entries.end(); ++iter) { for (auto iter = _entries.begin(); iter != _entries.end(); ++iter) {
ASSERT(iter == _entries.begin() || std::less<Key>()((iter-1)->key(), iter->key()), "Invariant hurt: Directory entries should be ordered by key and not have duplicate keys."); ASSERT(iter == _entries.begin() || std::less<BlockId>()((iter-1)->blockId(), iter->blockId()), "Invariant hurt: Directory entries should be ordered by blockId and not have duplicate blockIds.");
iter->serialize(static_cast<uint8_t*>(serialized.dataOffset(offset))); iter->serialize(static_cast<uint8_t*>(serialized.dataOffset(offset)));
offset += iter->serializedSize(); offset += iter->serializedSize();
} }
@ -40,7 +40,7 @@ void DirEntryList::deserializeFrom(const void *data, uint64_t size) {
const char *pos = static_cast<const char*>(data); const char *pos = static_cast<const char*>(data);
while (pos < static_cast<const char*>(data) + size) { while (pos < static_cast<const char*>(data) + size) {
pos = DirEntry::deserializeAndAddToVector(pos, &_entries); pos = DirEntry::deserializeAndAddToVector(pos, &_entries);
ASSERT(_entries.size() == 1 || std::less<Key>()(_entries[_entries.size()-2].key(), _entries[_entries.size()-1].key()), "Invariant hurt: Directory entries should be ordered by key and not have duplicate keys."); ASSERT(_entries.size() == 1 || std::less<BlockId>()(_entries[_entries.size()-2].blockId(), _entries[_entries.size()-1].blockId()), "Invariant hurt: Directory entries should be ordered by blockId and not have duplicate blockIds.");
} }
} }
@ -48,41 +48,41 @@ bool DirEntryList::_hasChild(const string &name) const {
return _entries.end() != _findByName(name); return _entries.end() != _findByName(name);
} }
void DirEntryList::add(const string &name, const Key &blobKey, fspp::Dir::EntryType entryType, mode_t mode, void DirEntryList::add(const string &name, const BlockId &blobId, fspp::Dir::EntryType entryType, mode_t mode,
uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
if (_hasChild(name)) { if (_hasChild(name)) {
throw fspp::fuse::FuseErrnoException(EEXIST); throw fspp::fuse::FuseErrnoException(EEXIST);
} }
_add(name, blobKey, entryType, mode, uid, gid, lastAccessTime, lastModificationTime); _add(name, blobId, entryType, mode, uid, gid, lastAccessTime, lastModificationTime);
} }
void DirEntryList::_add(const string &name, const Key &blobKey, fspp::Dir::EntryType entryType, mode_t mode, void DirEntryList::_add(const string &name, const BlockId &blobId, fspp::Dir::EntryType entryType, mode_t mode,
uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
auto insert_pos = _findUpperBound(blobKey); auto insert_pos = _findUpperBound(blobId);
_entries.emplace(insert_pos, entryType, name, blobKey, mode, uid, gid, lastAccessTime, lastModificationTime, cpputils::time::now()); _entries.emplace(insert_pos, entryType, name, blobId, mode, uid, gid, lastAccessTime, lastModificationTime, cpputils::time::now());
} }
void DirEntryList::addOrOverwrite(const string &name, const Key &blobKey, fspp::Dir::EntryType entryType, mode_t mode, void DirEntryList::addOrOverwrite(const string &name, const BlockId &blobId, fspp::Dir::EntryType entryType, mode_t mode,
uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime, uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime,
std::function<void (const blockstore::Key &key)> onOverwritten) { std::function<void (const blockstore::BlockId &blockId)> onOverwritten) {
auto found = _findByName(name); auto found = _findByName(name);
if (found != _entries.end()) { if (found != _entries.end()) {
onOverwritten(found->key()); onOverwritten(found->blockId());
_overwrite(found, name, blobKey, entryType, mode, uid, gid, lastAccessTime, lastModificationTime); _overwrite(found, name, blobId, entryType, mode, uid, gid, lastAccessTime, lastModificationTime);
} else { } else {
_add(name, blobKey, entryType, mode, uid, gid, lastAccessTime, lastModificationTime); _add(name, blobId, entryType, mode, uid, gid, lastAccessTime, lastModificationTime);
} }
} }
void DirEntryList::rename(const blockstore::Key &key, const std::string &name, std::function<void (const blockstore::Key &key)> onOverwritten) { void DirEntryList::rename(const blockstore::BlockId &blockId, const std::string &name, std::function<void (const blockstore::BlockId &blockId)> onOverwritten) {
auto foundSameName = _findByName(name); auto foundSameName = _findByName(name);
if (foundSameName != _entries.end() && foundSameName->key() != key) { if (foundSameName != _entries.end() && foundSameName->blockId() != blockId) {
_checkAllowedOverwrite(foundSameName->type(), _findByKey(key)->type()); _checkAllowedOverwrite(foundSameName->type(), _findById(blockId)->type());
onOverwritten(foundSameName->key()); onOverwritten(foundSameName->blockId());
_entries.erase(foundSameName); _entries.erase(foundSameName);
} }
_findByKey(key)->setName(name); _findById(blockId)->setName(name);
} }
void DirEntryList::_checkAllowedOverwrite(fspp::Dir::EntryType oldType, fspp::Dir::EntryType newType) { void DirEntryList::_checkAllowedOverwrite(fspp::Dir::EntryType oldType, fspp::Dir::EntryType newType) {
@ -98,13 +98,13 @@ void DirEntryList::_checkAllowedOverwrite(fspp::Dir::EntryType oldType, fspp::Di
} }
} }
void DirEntryList::_overwrite(vector<DirEntry>::iterator entry, const string &name, const Key &blobKey, fspp::Dir::EntryType entryType, mode_t mode, void DirEntryList::_overwrite(vector<DirEntry>::iterator entry, const string &name, const BlockId &blobId, fspp::Dir::EntryType entryType, mode_t mode,
uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) { uid_t uid, gid_t gid, timespec lastAccessTime, timespec lastModificationTime) {
_checkAllowedOverwrite(entry->type(), entryType); _checkAllowedOverwrite(entry->type(), entryType);
// The new entry has possibly a different key, so it has to be in a different list position (list is ordered by keys). // The new entry has possibly a different blockId, so it has to be in a different list position (list is ordered by blockIds).
// That's why we remove-and-add instead of just modifying the existing entry. // That's why we remove-and-add instead of just modifying the existing entry.
_entries.erase(entry); _entries.erase(entry);
_add(name, blobKey, entryType, mode, uid, gid, lastAccessTime, lastModificationTime); _add(name, blobId, entryType, mode, uid, gid, lastAccessTime, lastModificationTime);
} }
boost::optional<const DirEntry&> DirEntryList::get(const string &name) const { boost::optional<const DirEntry&> DirEntryList::get(const string &name) const {
@ -115,8 +115,8 @@ boost::optional<const DirEntry&> DirEntryList::get(const string &name) const {
return *found; return *found;
} }
boost::optional<const DirEntry&> DirEntryList::get(const Key &key) const { boost::optional<const DirEntry&> DirEntryList::get(const BlockId &blockId) const {
auto found = _findByKey(key); auto found = _findById(blockId);
if (found == _entries.end()) { if (found == _entries.end()) {
return boost::none; return boost::none;
} }
@ -131,10 +131,10 @@ void DirEntryList::remove(const string &name) {
_entries.erase(found); _entries.erase(found);
} }
void DirEntryList::remove(const Key &key) { void DirEntryList::remove(const BlockId &blockId) {
auto lowerBound = _findLowerBound(key); auto lowerBound = _findLowerBound(blockId);
auto upperBound = std::find_if(lowerBound, _entries.end(), [&key] (const DirEntry &entry) { auto upperBound = std::find_if(lowerBound, _entries.end(), [&blockId] (const DirEntry &entry) {
return entry.key() != key; return entry.blockId() != blockId;
}); });
_entries.erase(lowerBound, upperBound); _entries.erase(lowerBound, upperBound);
} }
@ -149,27 +149,27 @@ vector<DirEntry>::const_iterator DirEntryList::_findByName(const string &name) c
return const_cast<DirEntryList*>(this)->_findByName(name); return const_cast<DirEntryList*>(this)->_findByName(name);
} }
vector<DirEntry>::iterator DirEntryList::_findByKey(const Key &key) { vector<DirEntry>::iterator DirEntryList::_findById(const BlockId &blockId) {
auto found = _findLowerBound(key); auto found = _findLowerBound(blockId);
if (found == _entries.end() || found->key() != key) { if (found == _entries.end() || found->blockId() != blockId) {
throw fspp::fuse::FuseErrnoException(ENOENT); throw fspp::fuse::FuseErrnoException(ENOENT);
} }
return found; return found;
} }
vector<DirEntry>::iterator DirEntryList::_findLowerBound(const Key &key) { vector<DirEntry>::iterator DirEntryList::_findLowerBound(const BlockId &blockId) {
return _findFirst(key, [&key] (const DirEntry &entry) { return _findFirst(blockId, [&blockId] (const DirEntry &entry) {
return !std::less<Key>()(entry.key(), key); return !std::less<BlockId>()(entry.blockId(), blockId);
}); });
} }
vector<DirEntry>::iterator DirEntryList::_findUpperBound(const Key &key) { vector<DirEntry>::iterator DirEntryList::_findUpperBound(const BlockId &blockId) {
return _findFirst(key, [&key] (const DirEntry &entry) { return _findFirst(blockId, [&blockId] (const DirEntry &entry) {
return std::less<Key>()(key, entry.key()); return std::less<BlockId>()(blockId, entry.blockId());
}); });
} }
vector<DirEntry>::iterator DirEntryList::_findFirst(const Key &hint, std::function<bool (const DirEntry&)> pred) { vector<DirEntry>::iterator DirEntryList::_findFirst(const BlockId &hint, std::function<bool (const DirEntry&)> pred) {
//TODO Factor out a datastructure that keeps a sorted std::vector and allows these _findLowerBound()/_findUpperBound operations using this hinted linear search //TODO Factor out a datastructure that keeps a sorted std::vector and allows these _findLowerBound()/_findUpperBound operations using this hinted linear search
if (_entries.size() == 0) { if (_entries.size() == 0) {
return _entries.end(); return _entries.end();
@ -186,8 +186,8 @@ vector<DirEntry>::iterator DirEntryList::_findFirst(const Key &hint, std::functi
return iter; return iter;
} }
vector<DirEntry>::const_iterator DirEntryList::_findByKey(const Key &key) const { vector<DirEntry>::const_iterator DirEntryList::_findById(const BlockId &blockId) const {
return const_cast<DirEntryList*>(this)->_findByKey(key); return const_cast<DirEntryList*>(this)->_findById(blockId);
} }
size_t DirEntryList::size() const { size_t DirEntryList::size() const {
@ -202,14 +202,14 @@ DirEntryList::const_iterator DirEntryList::end() const {
return _entries.end(); return _entries.end();
} }
void DirEntryList::setMode(const Key &key, mode_t mode) { void DirEntryList::setMode(const BlockId &blockId, mode_t mode) {
auto found = _findByKey(key); auto found = _findById(blockId);
ASSERT ((S_ISREG(mode) && S_ISREG(found->mode())) || (S_ISDIR(mode) && S_ISDIR(found->mode())) || (S_ISLNK(mode)), "Unknown mode in entry"); ASSERT ((S_ISREG(mode) && S_ISREG(found->mode())) || (S_ISDIR(mode) && S_ISDIR(found->mode())) || (S_ISLNK(mode)), "Unknown mode in entry");
found->setMode(mode); found->setMode(mode);
} }
bool DirEntryList::setUidGid(const Key &key, uid_t uid, gid_t gid) { bool DirEntryList::setUidGid(const BlockId &blockId, uid_t uid, gid_t gid) {
auto found = _findByKey(key); auto found = _findById(blockId);
bool changed = false; bool changed = false;
if (uid != (uid_t)-1) { if (uid != (uid_t)-1) {
found->setUid(uid); found->setUid(uid);
@ -222,15 +222,15 @@ bool DirEntryList::setUidGid(const Key &key, uid_t uid, gid_t gid) {
return changed; return changed;
} }
void DirEntryList::setAccessTimes(const blockstore::Key &key, timespec lastAccessTime, timespec lastModificationTime) { void DirEntryList::setAccessTimes(const blockstore::BlockId &blockId, timespec lastAccessTime, timespec lastModificationTime) {
auto found = _findByKey(key); auto found = _findById(blockId);
found->setLastAccessTime(lastAccessTime); found->setLastAccessTime(lastAccessTime);
found->setLastModificationTime(lastModificationTime); found->setLastModificationTime(lastModificationTime);
} }
bool DirEntryList::updateAccessTimestampForChild(const blockstore::Key &key, TimestampUpdateBehavior timestampUpdateBehavior) { bool DirEntryList::updateAccessTimestampForChild(const blockstore::BlockId &blockId, TimestampUpdateBehavior timestampUpdateBehavior) {
ASSERT(timestampUpdateBehavior == TimestampUpdateBehavior::RELATIME, "Currently only relatime supported"); ASSERT(timestampUpdateBehavior == TimestampUpdateBehavior::RELATIME, "Currently only relatime supported");
auto found = _findByKey(key); auto found = _findById(blockId);
const timespec lastAccessTime = found->lastAccessTime(); const timespec lastAccessTime = found->lastAccessTime();
const timespec lastModificationTime = found->lastModificationTime(); const timespec lastModificationTime = found->lastModificationTime();
const timespec now = cpputils::time::now(); const timespec now = cpputils::time::now();
@ -246,8 +246,8 @@ bool DirEntryList::updateAccessTimestampForChild(const blockstore::Key &key, Tim
return changed; return changed;
} }
void DirEntryList::updateModificationTimestampForChild(const blockstore::Key &key) { void DirEntryList::updateModificationTimestampForChild(const blockstore::BlockId &blockId) {
auto found = _findByKey(key); auto found = _findById(blockId);
found->setLastModificationTime(cpputils::time::now()); found->setLastModificationTime(cpputils::time::now());
} }

Some files were not shown because too many files have changed in this diff Show More