libcryfs: switch to cryfs develop

This commit is contained in:
Matéo Duparc 2024-06-07 17:40:01 +02:00
commit 0398d48b09
Signed by: hardcoresushi
GPG Key ID: AFE384344A45E13A
144 changed files with 635 additions and 701 deletions

View File

@ -16,6 +16,9 @@ Checks: |
-cert-err60-cpp,
-bugprone-macro-parentheses,
-bugprone-exception-escape,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-narrowing-conversions,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-no-malloc,
-cppcoreguidelines-pro-type-const-cast,
@ -30,6 +33,7 @@ Checks: |
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-non-private-member-variables-in-classes,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-narrowing-conversions,
-clang-analyzer-optin.cplusplus.VirtualCall,
-clang-analyzer-cplusplus.NewDeleteLeaks,
-misc-macro-parentheses,

View File

@ -1,8 +1,5 @@
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
# TODO Remove this deprecated policy switch once we're on cmake 3.4 or later
cmake_policy(SET CMP0065 OLD)
# TODO Perf test:
# - try if setting CRYPTOPP_NATIVE_ARCH=ON and adding -march=native to the compile commands for cryfs source files makes a difference
# -> if yes, offer a cmake option to enable both of these
@ -27,7 +24,7 @@ option(USE_IWYU "build with iwyu checks enabled" OFF)
option(CLANG_TIDY_WARNINGS_AS_ERRORS "treat clang-tidy warnings as errors" OFF)
if (MSVC)
option(DOKAN_PATH "Location of the Dokan library, e.g. C:\\Program Files\\Dokan\\DokanLibrary-1.1.0" "")
option(DOKAN_PATH "Location of the Dokan library, e.g. C:\\Program Files\\Dokan\\DokanLibrary-2.0.6" "")
endif()
# Default value is to build in release mode but with debug symbols

View File

@ -7,7 +7,7 @@
"inheritEnvironments": [ "msvc_x86" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "-DBUILD_TESTING=on -DDOKAN_PATH=\"C:\\Program Files\\Dokan\\Dokan Library-1.3.0\"",
"cmakeCommandArgs": "-DBUILD_TESTING=on -DDOKAN_PATH=\"C:\\Program Files\\Dokan\\Dokan Library-2.0.6\"",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
@ -18,7 +18,7 @@
"inheritEnvironments": [ "msvc_x86" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "-DBUILD_TESTING=on -DDOKAN_PATH=\"C:\\Program Files\\Dokan\\Dokan Library-1.3.0\"",
"cmakeCommandArgs": "-DBUILD_TESTING=on -DDOKAN_PATH=\"C:\\Program Files\\Dokan\\Dokan Library-2.0.6\"",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
@ -29,7 +29,7 @@
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "-DBUILD_TESTING=on -DDOKAN_PATH=\"C:\\Program Files\\Dokan\\Dokan Library-1.3.0\"",
"cmakeCommandArgs": "-DBUILD_TESTING=on -DDOKAN_PATH=\"C:\\Program Files\\Dokan\\Dokan Library-2.0.6\"",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
@ -40,7 +40,7 @@
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "-DBUILD_TESTING=on -DDOKAN_PATH=\"C:\\Program Files\\Dokan\\Dokan Library-1.3.0\"",
"cmakeCommandArgs": "-DBUILD_TESTING=on -DDOKAN_PATH=\"C:\\Program Files\\Dokan\\Dokan Library-2.0.6\"",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
}

View File

@ -1,3 +1,19 @@
Version 0.12.0 (unreleased)
---------------
* Added a man page for `cryfs-unmount`
* Fixed small inaccuracy in calculation of free space in statvfs
* Use libcurl dependency from conan instead of requiring it to be preinstalled
* Updated dependencies to
* Fuse 2.9
* DokanY 2.0.6.1000
* range-v3/0.12.0
* boost 1.79
* spdlog/1.11.0
Version 0.11.5 (unreleased)
---------------
* Fix an issue when using `-o` atime mount options
Version 0.11.4
---------------
* Fixed build issue with GCC 13 (see https://github.com/cryfs/cryfs/pull/448 )

View File

@ -20,6 +20,9 @@ function(target_activate_cpp14 TARGET)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND APPLE)
target_compile_options(${TARGET} PUBLIC -stdlib=libc++)
endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND APPLE)
# We need ENABLE_EXPORTS so that boost::stacktrace works correctly
set_property(TARGET ${TARGET} PROPERTY ENABLE_EXPORTS 1)
endfunction(target_activate_cpp14)
# Find clang-tidy executable (for use in target_enable_style_warnings)

View File

@ -10,7 +10,6 @@ set(SOURCES
implementations/onblocks/datanodestore/DataLeafNode.cpp
implementations/onblocks/datanodestore/DataInnerNode.cpp
implementations/onblocks/datanodestore/DataNodeStore.cpp
implementations/onblocks/datatreestore/impl/algorithms.cpp
implementations/onblocks/datatreestore/impl/CachedValue.cpp
implementations/onblocks/datatreestore/impl/LeafTraverser.cpp
implementations/onblocks/datatreestore/LeafHandle.cpp

View File

@ -21,7 +21,7 @@ class DataTreeRef;
class BlobOnBlocks final: public Blob {
public:
BlobOnBlocks(cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> datatree);
~BlobOnBlocks();
~BlobOnBlocks() override;
const blockstore::BlockId &blockId() const override;

View File

@ -17,7 +17,7 @@ class ParallelAccessDataTreeStore;
class BlobStoreOnBlocks final: public BlobStore {
public:
BlobStoreOnBlocks(cpputils::unique_ref<blockstore::BlockStore> blockStore, uint64_t physicalBlocksizeBytes);
~BlobStoreOnBlocks();
~BlobStoreOnBlocks() override;
cpputils::unique_ref<Blob> create() override;
boost::optional<cpputils::unique_ref<Blob>> load(const blockstore::BlockId &blockId) override;

View File

@ -17,7 +17,7 @@ public:
using ChildEntry = DataInnerNode_ChildEntry;
DataInnerNode(DataNodeView block);
~DataInnerNode();
~DataInnerNode() override;
uint32_t maxStoreableChildren() const;

View File

@ -26,13 +26,13 @@ DataLeafNode::~DataLeafNode() {
unique_ref<DataLeafNode> DataLeafNode::CreateNewNode(BlockStore *blockStore, const DataNodeLayout &layout, Data data) {
ASSERT(data.size() <= layout.maxBytesPerLeaf(), "Data passed in is too large for one leaf.");
uint32_t size = data.size();
const uint32_t size = data.size();
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 BlockId &blockId, Data data) {
ASSERT(data.size() == layout.maxBytesPerLeaf(), "Data passed in is too large for one leaf.");
uint32_t size = data.size();
const uint32_t size = data.size();
return make_unique_ref<DataLeafNode>(DataNodeView::overwrite(blockStore, layout, DataNode::FORMAT_VERSION_HEADER, 0, size, blockId, std::move(data)));
}
@ -52,7 +52,7 @@ uint32_t DataLeafNode::numBytes() const {
void DataLeafNode::resize(uint32_t new_size) {
ASSERT(new_size <= maxStoreableBytes(), "Trying to resize to a size larger than the maximal size");
uint32_t old_size = node().Size();
const uint32_t old_size = node().Size();
if (new_size < old_size) {
fillDataWithZeroesFromTo(new_size, old_size);
}

View File

@ -15,7 +15,7 @@ public:
static cpputils::unique_ref<DataLeafNode> OverwriteNode(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, const blockstore::BlockId &blockId, cpputils::Data data);
DataLeafNode(DataNodeView block);
~DataLeafNode();
~DataLeafNode() override;
//Returning uint64_t, because calculations handling this probably need to be done in 64bit to support >4GB blobs.
uint64_t maxStoreableBytes() const;

View File

@ -23,7 +23,7 @@ namespace onblocks {
namespace datanodestore {
DataNodeStore::DataNodeStore(unique_ref<BlockStore> blockstore, uint64_t physicalBlocksizeBytes)
: _blockstore(std::move(blockstore)), _layout(_blockstore->blockSizeFromPhysicalBlockSize(physicalBlocksizeBytes)) {
: _blockstore(std::move(blockstore)), _layout(_blockstore->blockSizeFromPhysicalBlockSize(physicalBlocksizeBytes)), _physicalBlockSizeBytes(physicalBlocksizeBytes) {
}
DataNodeStore::~DataNodeStore() {
@ -80,7 +80,7 @@ unique_ref<DataNode> DataNodeStore::overwriteNodeWith(unique_ref<DataNode> targe
}
void DataNodeStore::remove(unique_ref<DataNode> node) {
BlockId blockId = node->blockId();
const BlockId blockId = node->blockId();
cpputils::destruct(std::move(node));
remove(blockId);
}
@ -127,11 +127,11 @@ uint64_t DataNodeStore::numNodes() const {
}
uint64_t DataNodeStore::estimateSpaceForNumNodesLeft() const {
return _blockstore->estimateNumFreeBytes() / _layout.blocksizeBytes();
return _blockstore->estimateNumFreeBytes() / _physicalBlockSizeBytes;
}
uint64_t DataNodeStore::virtualBlocksizeBytes() const {
return _layout.blocksizeBytes();
return _layout.maxBytesPerLeaf();
}
DataNodeLayout DataNodeStore::layout() const {

View File

@ -57,6 +57,7 @@ private:
cpputils::unique_ref<blockstore::BlockStore> _blockstore;
const DataNodeLayout _layout;
uint64_t _physicalBlockSizeBytes;
DISALLOW_COPY_AND_ASSIGN(DataNodeStore);
};

View File

@ -67,7 +67,7 @@ public:
static DataNodeView create(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, uint16_t formatVersion, uint8_t depth, uint32_t size, cpputils::Data data) {
ASSERT(data.size() <= layout.datasizeBytes(), "Data is too large for node");
cpputils::Data serialized = serialize_(layout, formatVersion, depth, size, std::move(data));
const cpputils::Data serialized = serialize_(layout, formatVersion, depth, size, std::move(data));
ASSERT(serialized.size() == layout.blocksizeBytes(), "Wrong block size");
auto block = blockStore->create(serialized);
return DataNodeView(std::move(block));

View File

@ -5,8 +5,6 @@
#include "../datanodestore/DataLeafNode.h"
#include "../utils/Math.h"
#include "impl/algorithms.h"
#include <cpp-utils/pointer/cast.h>
#include <cpp-utils/pointer/optional_ownership_ptr.h>
#include <cmath>
@ -53,7 +51,7 @@ const BlockId &DataTree::blockId() const {
void DataTree::flush() const {
// By grabbing a lock, we ensure that all modifying functions don't run currently and are therefore flushed.
// It's only a shared lock, because this doesn't modify the tree structure.
shared_lock<shared_mutex> lock(_treeStructureMutex);
const shared_lock<shared_mutex> lock(_treeStructureMutex);
// We also have to flush the root node
_rootNode->flush();
}
@ -61,7 +59,7 @@ void DataTree::flush() const {
unique_ref<DataNode> DataTree::releaseRootNode() {
// Lock also ensures that the root node is currently set (traversing unsets it temporarily)
// It's a unique lock because this "modifies" tree structure by changing _rootNode.
unique_lock<shared_mutex> lock(_treeStructureMutex);
const unique_lock<shared_mutex> lock(_treeStructureMutex);
return std::move(_rootNode);
}
@ -76,13 +74,13 @@ uint32_t DataTree::numNodes() const {
}
uint32_t DataTree::numLeaves() const {
shared_lock<shared_mutex> lock(_treeStructureMutex);
const shared_lock<shared_mutex> lock(_treeStructureMutex);
return _getOrComputeSizeCache().numLeaves;
}
uint64_t DataTree::numBytes() const {
shared_lock<shared_mutex> lock(_treeStructureMutex);
const shared_lock<shared_mutex> lock(_treeStructureMutex);
return _numBytes();
}
@ -109,11 +107,11 @@ DataTree::SizeCache DataTree::_computeSizeCache(const DataNode &node) const {
}
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(node);
uint32_t numLeavesInLeftChildren = static_cast<uint32_t>(inner.numChildren()-1) * _leavesPerFullChild(inner);
uint64_t numBytesInLeftChildren = numLeavesInLeftChildren * _nodeStore->layout().maxBytesPerLeaf();
const uint32_t numLeavesInLeftChildren = static_cast<uint32_t>(inner.numChildren()-1) * _leavesPerFullChild(inner);
const uint64_t numBytesInLeftChildren = numLeavesInLeftChildren * _nodeStore->layout().maxBytesPerLeaf();
auto lastChild = _nodeStore->load(inner.readLastChild().blockId());
ASSERT(lastChild != none, "Couldn't load last child");
SizeCache sizeInRightChild = _computeSizeCache(**lastChild);
const SizeCache sizeInRightChild = _computeSizeCache(**lastChild);
return SizeCache {
numLeavesInLeftChildren + sizeInRightChild.numLeaves,
@ -138,16 +136,16 @@ void DataTree::_traverseLeavesByByteIndices(uint64_t beginByte, uint64_t sizeByt
return;
}
uint64_t endByte = beginByte + sizeBytes;
uint64_t _maxBytesPerLeaf = maxBytesPerLeaf();
uint32_t firstLeaf = beginByte / _maxBytesPerLeaf;
uint32_t endLeaf = utils::ceilDivision(endByte, _maxBytesPerLeaf);
const uint64_t endByte = beginByte + sizeBytes;
const uint64_t _maxBytesPerLeaf = maxBytesPerLeaf();
const uint32_t firstLeaf = beginByte / _maxBytesPerLeaf;
const uint32_t endLeaf = utils::ceilDivision(endByte, _maxBytesPerLeaf);
bool blobIsGrowingFromThisTraversal = false;
auto _onExistingLeaf = [&onExistingLeaf, beginByte, endByte, endLeaf, _maxBytesPerLeaf, &blobIsGrowingFromThisTraversal] (uint32_t leafIndex, bool isRightBorderLeaf, LeafHandle leafHandle) {
uint64_t indexOfFirstLeafByte = leafIndex * _maxBytesPerLeaf;
const uint64_t indexOfFirstLeafByte = leafIndex * _maxBytesPerLeaf;
ASSERT(endByte > indexOfFirstLeafByte, "Traversal went too far right");
uint32_t dataBegin = utils::maxZeroSubtraction(beginByte, indexOfFirstLeafByte);
uint32_t dataEnd = std::min(_maxBytesPerLeaf, endByte - indexOfFirstLeafByte);
const uint32_t dataBegin = utils::maxZeroSubtraction(beginByte, indexOfFirstLeafByte);
const uint32_t dataEnd = std::min(_maxBytesPerLeaf, endByte - indexOfFirstLeafByte);
// If we are traversing exactly until the last leaf, then the last leaf wasn't resized by the traversal and might have a wrong size. We have to fix it.
if (isRightBorderLeaf) {
ASSERT(leafIndex == endLeaf-1, "If we traversed further right, this wouldn't be the right border leaf.");
@ -162,10 +160,10 @@ void DataTree::_traverseLeavesByByteIndices(uint64_t beginByte, uint64_t sizeByt
auto _onCreateLeaf = [&onCreateLeaf, _maxBytesPerLeaf, beginByte, firstLeaf, endByte, endLeaf, &blobIsGrowingFromThisTraversal, readOnlyTraversal] (uint32_t leafIndex) -> Data {
ASSERT(!readOnlyTraversal, "Cannot create leaves in a read-only traversal");
blobIsGrowingFromThisTraversal = true;
uint64_t indexOfFirstLeafByte = leafIndex * _maxBytesPerLeaf;
const uint64_t indexOfFirstLeafByte = leafIndex * _maxBytesPerLeaf;
ASSERT(endByte > indexOfFirstLeafByte, "Traversal went too far right");
uint32_t dataBegin = utils::maxZeroSubtraction(beginByte, indexOfFirstLeafByte);
uint32_t dataEnd = std::min(_maxBytesPerLeaf, endByte - indexOfFirstLeafByte);
const uint32_t dataBegin = utils::maxZeroSubtraction(beginByte, indexOfFirstLeafByte);
const uint32_t dataEnd = std::min(_maxBytesPerLeaf, endByte - indexOfFirstLeafByte);
ASSERT(leafIndex == firstLeaf || dataBegin == 0, "Only the leftmost leaf can have a gap on the left.");
ASSERT(leafIndex == endLeaf-1 || dataEnd == _maxBytesPerLeaf, "Only the rightmost leaf can have a gap on the right");
Data data = onCreateLeaf(indexOfFirstLeafByte + dataBegin, dataEnd-dataBegin);
@ -197,11 +195,11 @@ uint32_t DataTree::_leavesPerFullChild(const DataInnerNode &root) const {
}
void DataTree::resizeNumBytes(uint64_t newNumBytes) {
std::unique_lock<shared_mutex> lock(_treeStructureMutex);
const std::unique_lock<shared_mutex> lock(_treeStructureMutex);
uint32_t newNumLeaves = std::max(UINT64_C(1), utils::ceilDivision(newNumBytes, _nodeStore->layout().maxBytesPerLeaf()));
uint32_t newLastLeafSize = newNumBytes - (newNumLeaves-1) * _nodeStore->layout().maxBytesPerLeaf();
uint32_t maxChildrenPerInnerNode = _nodeStore->layout().maxChildrenPerInnerNode();
const uint32_t newNumLeaves = std::max(UINT64_C(1), utils::ceilDivision(newNumBytes, _nodeStore->layout().maxBytesPerLeaf()));
const uint32_t newLastLeafSize = newNumBytes - (newNumLeaves-1) * _nodeStore->layout().maxBytesPerLeaf();
const uint32_t maxChildrenPerInnerNode = _nodeStore->layout().maxChildrenPerInnerNode();
auto onExistingLeaf = [newLastLeafSize] (uint32_t /*index*/, bool /*isRightBorderLeaf*/, LeafHandle leafHandle) {
auto leaf = leafHandle.node();
// This is only called, if the new last leaf was already existing
@ -216,10 +214,10 @@ void DataTree::resizeNumBytes(uint64_t newNumBytes) {
auto onBacktrackFromSubtree = [this, newNumLeaves, maxChildrenPerInnerNode] (DataInnerNode* node) {
// This is only called for the right border nodes of the new tree.
// When growing size, the following is a no-op. When shrinking, we're deleting the children that aren't needed anymore.
uint32_t maxLeavesPerChild = utils::intPow(static_cast<uint64_t>(maxChildrenPerInnerNode), (static_cast<uint64_t>(node->depth())-1));
uint32_t neededNodesOnChildLevel = utils::ceilDivision(newNumLeaves, maxLeavesPerChild);
uint32_t neededSiblings = utils::ceilDivision(neededNodesOnChildLevel, maxChildrenPerInnerNode);
uint32_t neededChildrenForRightBorderNode = neededNodesOnChildLevel - (neededSiblings-1) * maxChildrenPerInnerNode;
const uint32_t maxLeavesPerChild = utils::intPow(static_cast<uint64_t>(maxChildrenPerInnerNode), (static_cast<uint64_t>(node->depth())-1));
const uint32_t neededNodesOnChildLevel = utils::ceilDivision(newNumLeaves, maxLeavesPerChild);
const uint32_t neededSiblings = utils::ceilDivision(neededNodesOnChildLevel, maxChildrenPerInnerNode);
const uint32_t neededChildrenForRightBorderNode = neededNodesOnChildLevel - (neededSiblings-1) * maxChildrenPerInnerNode;
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.
while(node->numChildren() > neededChildrenForRightBorderNode) {
@ -240,12 +238,12 @@ uint64_t DataTree::maxBytesPerLeaf() const {
}
uint8_t DataTree::depth() const {
shared_lock<shared_mutex> lock(_treeStructureMutex);
const shared_lock<shared_mutex> lock(_treeStructureMutex);
return _rootNode->depth();
}
void DataTree::readBytes(void *target, uint64_t offset, uint64_t count) const {
shared_lock<shared_mutex> lock(_treeStructureMutex);
const shared_lock<shared_mutex> lock(_treeStructureMutex);
const uint64_t _size = _numBytes();
if(offset > _size || offset + count > _size) {
@ -258,10 +256,10 @@ void DataTree::readBytes(void *target, uint64_t offset, uint64_t count) const {
}
Data DataTree::readAllBytes() const {
shared_lock<shared_mutex> lock(_treeStructureMutex);
const shared_lock<shared_mutex> lock(_treeStructureMutex);
//TODO Querying numBytes can be inefficient. Is this possible without a call to size()?
uint64_t count = _numBytes();
const uint64_t count = _numBytes();
Data result(count);
_doReadBytes(result.data(), 0, count);
@ -269,7 +267,7 @@ Data DataTree::readAllBytes() const {
}
uint64_t DataTree::tryReadBytes(void *target, uint64_t offset, uint64_t count) const {
shared_lock<shared_mutex> lock(_treeStructureMutex);
const shared_lock<shared_mutex> lock(_treeStructureMutex);
auto result = _tryReadBytes(target, offset, count);
return result;
}
@ -296,7 +294,7 @@ void DataTree::_doReadBytes(void *target, uint64_t offset, uint64_t count) const
}
void DataTree::writeBytes(const void *source, uint64_t offset, uint64_t count) {
unique_lock<shared_mutex> lock(_treeStructureMutex);
const unique_lock<shared_mutex> lock(_treeStructureMutex);
auto onExistingLeaf = [source, offset, count] (uint64_t indexOfFirstLeafByte, LeafHandle leaf, uint32_t leafDataOffset, uint32_t leafDataSize) {
ASSERT(indexOfFirstLeafByte+leafDataOffset>=offset && indexOfFirstLeafByte-offset+leafDataOffset <= count && indexOfFirstLeafByte-offset+leafDataOffset+leafDataSize <= count, "Reading from source out of bounds");

View File

@ -18,14 +18,14 @@ public:
T getOrCompute(std::function<T ()> compute) {
boost::upgrade_lock<boost::shared_mutex> readLock(_mutex);
if (_cache == boost::none) {
boost::upgrade_to_unique_lock<boost::shared_mutex> writeLock(readLock);
const boost::upgrade_to_unique_lock<boost::shared_mutex> writeLock(readLock);
_cache = compute();
}
return *_cache;
}
void update(std::function<void (boost::optional<T>*)> func) {
boost::unique_lock<boost::shared_mutex> writeLock(_mutex);
const boost::unique_lock<boost::shared_mutex> writeLock(_mutex);
func(&_cache);
}

View File

@ -37,8 +37,8 @@ namespace blobstore {
// beginIndex<numLeaves<endIndex, beginIndex=numLeaves<endIndex,
// numLeaves<beginIndex<endIndex, numLeaves<beginIndex=endIndex
uint32_t maxLeavesForDepth = _maxLeavesForTreeDepth((*root)->depth());
bool increaseTreeDepth = endIndex > maxLeavesForDepth;
const uint32_t maxLeavesForDepth = _maxLeavesForTreeDepth((*root)->depth());
const bool increaseTreeDepth = endIndex > maxLeavesForDepth;
ASSERT(!_readOnlyTraversal || !increaseTreeDepth, "Tried to grow a tree on a read only traversal");
if ((*root)->depth() == 0) {
@ -49,7 +49,7 @@ namespace blobstore {
leaf->resize(_nodeStore->layout().maxBytesPerLeaf());
}
if (beginIndex == 0 && endIndex >= 1) {
bool isRightBorderLeaf = (endIndex == 1);
const bool isRightBorderLeaf = (endIndex == 1);
onExistingLeaf(0, isRightBorderLeaf, LeafHandle(_nodeStore, leaf));
}
} else {
@ -119,21 +119,21 @@ namespace blobstore {
//TODO Call callbacks for different leaves in parallel.
uint32_t leavesPerChild = _maxLeavesForTreeDepth(root->depth()-1);
uint32_t beginChild = beginIndex/leavesPerChild;
uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild);
const uint32_t leavesPerChild = _maxLeavesForTreeDepth(root->depth()-1);
const uint32_t beginChild = beginIndex/leavesPerChild;
const uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild);
ASSERT(endChild <= _nodeStore->layout().maxChildrenPerInnerNode(), "Traversal region would need increasing the tree depth. This should have happened before calling this function.");
uint32_t numChildren = root->numChildren();
const uint32_t numChildren = root->numChildren();
ASSERT(!growLastLeaf || endChild >= numChildren, "Can only grow last leaf if it exists");
ASSERT(!_readOnlyTraversal || endChild <= numChildren, "Can only traverse out of bounds in a read-only traversal");
bool shouldGrowLastExistingLeaf = growLastLeaf || endChild > numChildren;
const bool shouldGrowLastExistingLeaf = growLastLeaf || endChild > numChildren;
// If we traverse outside of the valid region (i.e. usually would only traverse to new leaves and not to the last 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) {
ASSERT(numChildren > 0, "Node doesn't have children.");
auto childBlockId = root->readLastChild().blockId();
uint32_t childOffset = (numChildren-1) * leavesPerChild;
const uint32_t childOffset = (numChildren-1) * leavesPerChild;
_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*/) -> Data {ASSERT(false, "We don't actually traverse any leaves.");},
@ -143,12 +143,12 @@ namespace blobstore {
// Traverse existing children
for (uint32_t childIndex = beginChild; childIndex < std::min(endChild, numChildren); ++childIndex) {
auto childBlockId = root->readChild(childIndex).blockId();
uint32_t childOffset = childIndex * leavesPerChild;
uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset);
uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
bool isFirstChild = (childIndex == beginChild);
bool isLastExistingChild = (childIndex == numChildren - 1);
bool isLastChild = isLastExistingChild && (numChildren == endChild);
const uint32_t childOffset = childIndex * leavesPerChild;
const uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset);
const uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
const bool isFirstChild = (childIndex == beginChild);
const bool isLastExistingChild = (childIndex == numChildren - 1);
const 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.");
_traverseExistingSubtree(childBlockId, root->depth()-1, localBeginIndex, localEndIndex, leafOffset + childOffset, isLeftBorderOfTraversal && isFirstChild,
isRightBorderNode && isLastChild, shouldGrowLastExistingLeaf && isLastExistingChild, onExistingLeaf, onCreateLeaf, onBacktrackFromSubtree);
@ -158,9 +158,9 @@ namespace blobstore {
for (uint32_t childIndex = numChildren; childIndex < endChild; ++childIndex) {
ASSERT(!_readOnlyTraversal, "Can't create new children in a read-only traversal");
uint32_t childOffset = childIndex * leavesPerChild;
uint32_t localBeginIndex = std::min(leavesPerChild, utils::maxZeroSubtraction(beginIndex, childOffset));
uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
const uint32_t childOffset = childIndex * leavesPerChild;
const uint32_t localBeginIndex = std::min(leavesPerChild, utils::maxZeroSubtraction(beginIndex, childOffset));
const uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
auto leafCreator = (childIndex >= beginChild) ? onCreateLeaf : _createMaxSizeLeaf();
auto child = _createNewSubtree(localBeginIndex, localEndIndex, leafOffset + childOffset, root->depth() - 1, leafCreator, onBacktrackFromSubtree);
root->addChild(*child);
@ -184,18 +184,18 @@ namespace blobstore {
return _nodeStore->createNewLeafNode(leafCreator(leafOffset));
}
uint8_t minNeededDepth = utils::ceilLog(_nodeStore->layout().maxChildrenPerInnerNode(), static_cast<uint64_t>(endIndex));
const uint8_t minNeededDepth = utils::ceilLog(_nodeStore->layout().maxChildrenPerInnerNode(), static_cast<uint64_t>(endIndex));
ASSERT(depth >= minNeededDepth, "Given tree depth doesn't fit given number of leaves to create.");
uint32_t leavesPerChild = _maxLeavesForTreeDepth(depth-1);
uint32_t beginChild = beginIndex/leavesPerChild;
uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild);
const uint32_t leavesPerChild = _maxLeavesForTreeDepth(depth-1);
const uint32_t beginChild = beginIndex/leavesPerChild;
const uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild);
vector<blockstore::BlockId> children;
children.reserve(endChild);
// 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)
for (uint32_t childIndex = 0; childIndex < beginChild; ++childIndex) {
uint32_t childOffset = childIndex * leavesPerChild;
const uint32_t childOffset = childIndex * leavesPerChild;
auto child = _createNewSubtree(leavesPerChild, leavesPerChild, leafOffset + childOffset, depth - 1,
[] (uint32_t /*index*/)->Data {ASSERT(false, "We're only creating gap leaves here, not traversing any.");},
[] (DataInnerNode* /*node*/) {});
@ -204,9 +204,9 @@ namespace blobstore {
}
// Create new children that are traversed
for(uint32_t childIndex = beginChild; childIndex < endChild; ++childIndex) {
uint32_t childOffset = childIndex * leavesPerChild;
uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset);
uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
const uint32_t childOffset = childIndex * leavesPerChild;
const uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset);
const uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
auto child = _createNewSubtree(localBeginIndex, localEndIndex, leafOffset + childOffset, depth - 1, onCreateLeaf, onBacktrackFromSubtree);
ASSERT(child->depth() == depth-1, "Created child node has wrong depth");
children.push_back(child->blockId());
@ -229,7 +229,7 @@ namespace blobstore {
function<Data (uint32_t index)> LeafTraverser::_createMaxSizeLeaf() const {
ASSERT(!_readOnlyTraversal, "Can't create a new leaf in a read-only traversal");
uint64_t maxBytesPerLeaf = _nodeStore->layout().maxBytesPerLeaf();
const uint64_t maxBytesPerLeaf = _nodeStore->layout().maxBytesPerLeaf();
return [maxBytesPerLeaf] (uint32_t /*index*/) -> Data {
return Data(maxBytesPerLeaf).FillWithZeroes();
};

View File

@ -1,69 +0,0 @@
#include "algorithms.h"
#include <cpp-utils/pointer/cast.h>
#include <blockstore/utils/BlockId.h>
#include "../../datanodestore/DataInnerNode.h"
#include "../../datanodestore/DataNodeStore.h"
#include <cpp-utils/assert/assert.h>
using std::function;
using cpputils::optional_ownership_ptr;
using cpputils::dynamic_pointer_move;
using cpputils::unique_ref;
using blobstore::onblocks::datanodestore::DataInnerNode;
using blobstore::onblocks::datanodestore::DataNode;
using blobstore::onblocks::datanodestore::DataNodeStore;
using blockstore::BlockId;
using boost::optional;
using boost::none;
namespace blobstore {
namespace onblocks {
namespace datatreestore {
namespace algorithms {
optional<unique_ref<DataInnerNode>> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) {
BlockId blockId = node.readLastChild().blockId();
auto lastChild = nodeStore->load(blockId);
ASSERT(lastChild != none, "Couldn't load last child");
return dynamic_pointer_move<DataInnerNode>(*lastChild);
}
//Returns the lowest right border node meeting the condition specified (exclusive the leaf).
//Returns nullptr, if no inner right border node meets the condition.
optional_ownership_ptr<DataInnerNode> GetLowestInnerRightBorderNodeWithConditionOrNull(DataNodeStore *nodeStore, datanodestore::DataNode *rootNode, function<bool(const DataInnerNode &)> condition) {
optional_ownership_ptr<DataInnerNode> currentNode = cpputils::WithoutOwnership(dynamic_cast<DataInnerNode*>(rootNode));
optional_ownership_ptr<DataInnerNode> result = cpputils::null<DataInnerNode>();
for (unsigned int i=0; i < rootNode->depth(); ++i) {
//TODO This unnecessarily loads the leaf node in the last loop run
auto lastChild = getLastChildAsInnerNode(nodeStore, *currentNode);
if (condition(*currentNode)) {
result = std::move(currentNode);
}
if (lastChild == none) {
// lastChild is a leaf
ASSERT(static_cast<int>(i) == rootNode->depth()-1, "Couldn't get last child as inner node but we're not deep enough yet for the last child to be a leaf");
break;
}
currentNode = cpputils::WithOwnership(std::move(*lastChild));
}
return result;
}
optional_ownership_ptr<DataInnerNode> GetLowestRightBorderNodeWithMoreThanOneChildOrNull(DataNodeStore *nodeStore, DataNode *rootNode) {
return GetLowestInnerRightBorderNodeWithConditionOrNull(nodeStore, rootNode, [] (const datanodestore::DataInnerNode &node) {
return node.numChildren() > 1;
});
}
optional_ownership_ptr<datanodestore::DataInnerNode> GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(datanodestore::DataNodeStore *nodeStore, datanodestore::DataNode *rootNode) {
return GetLowestInnerRightBorderNodeWithConditionOrNull(nodeStore, rootNode, [] (const datanodestore::DataInnerNode &node) {
return node.numChildren() < node.maxStoreableChildren();
});
}
}
}
}
}

View File

@ -1,30 +0,0 @@
#pragma once
#ifndef MESSMER_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_IMPL_ALGORITHMS_H_
#define MESSMER_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_IMPL_ALGORITHMS_H_
#include <cpp-utils/pointer/optional_ownership_ptr.h>
namespace blobstore {
namespace onblocks {
namespace datanodestore{
class DataNode;
class DataInnerNode;
class DataNodeStore;
}
namespace datatreestore {
namespace algorithms {
//Returns the lowest right border node with at least two children.
//Returns nullptr, if all right border nodes have only one child (since the root is a right border node, this means that the whole tree has exactly one leaf)
cpputils::optional_ownership_ptr<datanodestore::DataInnerNode> GetLowestRightBorderNodeWithMoreThanOneChildOrNull(datanodestore::DataNodeStore *nodeStore, datanodestore::DataNode *rootNode);
//Returns the lowest right border node with less than k children (not considering leaves).
//Returns nullptr, if all right border nodes have k children (the tree is full)
cpputils::optional_ownership_ptr<datanodestore::DataInnerNode> GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(datanodestore::DataNodeStore *nodeStore, datanodestore::DataNode *rootNode);
}
}
}
}
#endif

View File

@ -31,12 +31,12 @@ optional<unique_ref<DataTreeRef>> ParallelAccessDataTreeStore::load(const blocks
unique_ref<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() {
auto dataTree = _dataTreeStore->createNewTree();
BlockId blockId = dataTree->blockId();
const BlockId blockId = dataTree->blockId();
return _parallelAccessStore.add(blockId, std::move(dataTree)); // NOLINT (workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82481 )
}
void ParallelAccessDataTreeStore::remove(unique_ref<DataTreeRef> tree) {
BlockId blockId = tree->blockId();
const BlockId blockId = tree->blockId();
return _parallelAccessStore.remove(blockId, std::move(tree));
}

View File

@ -9,7 +9,6 @@ using cpputils::Data;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using boost::optional;
using boost::none;
using std::unique_lock;
using std::mutex;
@ -27,7 +26,7 @@ CachingBlockStore2::CachedBlock::~CachedBlock() {
_blockStore->_baseBlockStore->store(_blockId, _data);
}
// remove it from the list of blocks not in the base store, if it's on it
unique_lock<mutex> lock(_blockStore->_cachedBlocksNotInBaseStoreMutex);
const unique_lock<mutex> lock(_blockStore->_cachedBlocksNotInBaseStoreMutex);
_blockStore->_cachedBlocksNotInBaseStore.erase(_blockId);
}
@ -57,7 +56,7 @@ bool CachingBlockStore2::tryCreate(const BlockId &blockId, const Data &data) {
return false;
} else {
_cache.push(blockId, make_unique_ref<CachingBlockStore2::CachedBlock>(this, blockId, data.copy(), true));
unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
const unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
_cachedBlocksNotInBaseStore.insert(blockId);
return true;
}
@ -69,7 +68,7 @@ bool CachingBlockStore2::remove(const BlockId &blockId) {
if (popped != boost::none) {
// Remove from base store if it exists in the base store
{
unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
const unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
if (_cachedBlocksNotInBaseStore.count(blockId) == 0) {
const bool existedInBaseStore = _baseBlockStore->remove(blockId);
if (!existedInBaseStore) {
@ -125,7 +124,7 @@ void CachingBlockStore2::store(const BlockId &blockId, const Data &data) {
uint64_t CachingBlockStore2::numBlocks() const {
uint64_t numInCacheButNotInBaseStore = 0;
{
unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
const unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
numInCacheButNotInBaseStore = _cachedBlocksNotInBaseStore.size();
}
return _baseBlockStore->numBlocks() + numInCacheButNotInBaseStore;
@ -141,7 +140,7 @@ uint64_t CachingBlockStore2::blockSizeFromPhysicalBlockSize(uint64_t blockSize)
void CachingBlockStore2::forEachBlock(std::function<void (const BlockId &)> callback) const {
{
unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
const unique_lock<mutex> lock(_cachedBlocksNotInBaseStoreMutex);
for (const BlockId &blockId : _cachedBlocksNotInBaseStore) {
callback(blockId);
}

View File

@ -71,7 +71,7 @@ Cache<Key, Value, MAX_ENTRIES>::~Cache() {
template<class Key, class Value, uint32_t MAX_ENTRIES>
boost::optional<Value> Cache<Key, Value, MAX_ENTRIES>::pop(const Key &key) {
std::unique_lock<std::mutex> lock(_mutex);
cpputils::MutexPoolLock<Key> lockEntryFromBeingPopped(&_currentlyFlushingEntries, key, &lock);
const cpputils::MutexPoolLock<Key> lockEntryFromBeingPopped(&_currentlyFlushingEntries, key, &lock);
auto found = _cachedBlocks.pop(key);
if (!found) {
@ -132,7 +132,7 @@ void Cache<Key, Value, MAX_ENTRIES>::_deleteOldEntriesParallel() {
template<class Key, class Value, uint32_t MAX_ENTRIES>
void Cache<Key, Value, MAX_ENTRIES>::_deleteMatchingEntriesAtBeginningParallel(std::function<bool (const CacheEntry<Key, Value> &)> matches) {
// Twice the number of cores, so we use full CPU even if half the threads are doing I/O
unsigned int numThreads = 2 * (std::max)(1u, std::thread::hardware_concurrency());
const unsigned int numThreads = 2 * (std::max)(1u, std::thread::hardware_concurrency());
std::vector<std::future<void>> waitHandles;
for (unsigned int i = 0; i < numThreads; ++i) {
waitHandles.push_back(std::async(std::launch::async, [this, matches] {

View File

@ -21,7 +21,7 @@ public:
static cpputils::unique_ref<CompressedBlock> Decompress(cpputils::unique_ref<Block> baseBlock);
CompressedBlock(cpputils::unique_ref<Block> baseBlock, cpputils::Data decompressedData);
~CompressedBlock();
~CompressedBlock() override;
const void *data() const override;
void write(const void *source, uint64_t offset, uint64_t size) override;
@ -80,7 +80,7 @@ CompressedBlock<Compressor>::CompressedBlock(cpputils::unique_ref<Block> baseBlo
template<class Compressor>
CompressedBlock<Compressor>::~CompressedBlock() {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
_compressToBaseBlock();
}
@ -97,7 +97,7 @@ void CompressedBlock<Compressor>::write(const void *source, uint64_t offset, uin
template<class Compressor>
void CompressedBlock<Compressor>::flush() {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
_compressToBaseBlock();
return _baseBlock->flush();
}

View File

@ -12,7 +12,7 @@ template<class Compressor>
class CompressingBlockStore final: public BlockStore {
public:
CompressingBlockStore(cpputils::unique_ref<BlockStore> baseBlockStore);
~CompressingBlockStore();
~CompressingBlockStore() override;
BlockId createBlockId() override;
boost::optional<cpputils::unique_ref<Block>> tryCreate(const BlockId &blockId, cpputils::Data data) override;

View File

@ -84,7 +84,7 @@ namespace blockstore {
}
Data RunLengthEncoding::_extractData(ostringstream *stream) {
string str = stream->str();
const string str = stream->str();
Data data(str.size());
std::memcpy(data.data(), str.c_str(), str.size());
return data;

View File

@ -71,7 +71,7 @@ inline EncryptedBlockStore2<Cipher>::EncryptedBlockStore2(cpputils::unique_ref<B
template<class Cipher>
inline bool EncryptedBlockStore2<Cipher>::tryCreate(const BlockId &blockId, const cpputils::Data &data) {
cpputils::Data encrypted = _encrypt(data);
const cpputils::Data encrypted = _encrypt(data);
return _baseBlockStore->tryCreate(blockId, encrypted);
}
@ -92,7 +92,7 @@ inline boost::optional<cpputils::Data> EncryptedBlockStore2<Cipher>::load(const
template<class Cipher>
inline void EncryptedBlockStore2<Cipher>::store(const BlockId &blockId, const cpputils::Data &data) {
cpputils::Data encrypted = _encrypt(data);
const cpputils::Data encrypted = _encrypt(data);
return _baseBlockStore->store(blockId, encrypted);
}
@ -108,7 +108,7 @@ inline uint64_t EncryptedBlockStore2<Cipher>::estimateNumFreeBytes() const {
template<class Cipher>
inline uint64_t EncryptedBlockStore2<Cipher>::blockSizeFromPhysicalBlockSize(uint64_t blockSize) const {
uint64_t baseBlockSize = _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize);
const uint64_t baseBlockSize = _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize);
if (baseBlockSize <= Cipher::ciphertextSize(0) + sizeof(FORMAT_VERSION_HEADER)) {
return 0;
}
@ -122,7 +122,7 @@ inline void EncryptedBlockStore2<Cipher>::forEachBlock(std::function<void (const
template<class Cipher>
inline cpputils::Data EncryptedBlockStore2<Cipher>::_encrypt(const cpputils::Data &data) const {
cpputils::Data encrypted = Cipher::encrypt(static_cast<const CryptoPP::byte*>(data.data()), data.size(), _encKey);
const cpputils::Data encrypted = Cipher::encrypt(static_cast<const CryptoPP::byte*>(data.data()), data.size(), _encKey);
return _prependFormatHeaderToData(encrypted);
}

View File

@ -9,7 +9,6 @@ using std::make_pair;
using std::vector;
using cpputils::Data;
using boost::optional;
using boost::none;
namespace blockstore {
namespace inmemory {
@ -18,7 +17,7 @@ InMemoryBlockStore2::InMemoryBlockStore2()
: _blocks() {}
bool InMemoryBlockStore2::tryCreate(const BlockId &blockId, const Data &data) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
return _tryCreate(blockId, data);
}
@ -28,7 +27,7 @@ bool InMemoryBlockStore2::_tryCreate(const BlockId &blockId, const Data &data) {
}
bool InMemoryBlockStore2::remove(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
auto found = _blocks.find(blockId);
if (found == _blocks.end()) {
// BlockId not found
@ -40,7 +39,7 @@ bool InMemoryBlockStore2::remove(const BlockId &blockId) {
}
optional<Data> InMemoryBlockStore2::load(const BlockId &blockId) const {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
auto found = _blocks.find(blockId);
if (found == _blocks.end()) {
return boost::none;
@ -49,10 +48,10 @@ optional<Data> InMemoryBlockStore2::load(const BlockId &blockId) const {
}
void InMemoryBlockStore2::store(const BlockId &blockId, const Data &data) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
auto found = _blocks.find(blockId);
if (found == _blocks.end()) {
bool success = _tryCreate(blockId, data);
const bool success = _tryCreate(blockId, data);
if (!success) {
throw std::runtime_error("Could neither save nor create the block in InMemoryBlockStore::store()");
}
@ -63,7 +62,7 @@ void InMemoryBlockStore2::store(const BlockId &blockId, const Data &data) {
}
uint64_t InMemoryBlockStore2::numBlocks() const {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
return _blocks.size();
}
@ -76,7 +75,7 @@ uint64_t InMemoryBlockStore2::blockSizeFromPhysicalBlockSize(uint64_t blockSize)
}
vector<BlockId> InMemoryBlockStore2::_allBlockIds() const {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
vector<BlockId> result;
result.reserve(_blocks.size());
for (const auto &entry : _blocks) {

View File

@ -50,8 +50,8 @@ void IntegrityBlockStore2::_checkFormatHeader(const Data &data) const {
}
bool IntegrityBlockStore2::_checkVersionHeader(const BlockId &blockId, const Data &data) const {
uint32_t clientId = _readClientId(data);
uint64_t version = _readVersion(data);
const uint32_t clientId = _readClientId(data);
const uint64_t version = _readVersion(data);
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?");
@ -64,7 +64,7 @@ bool IntegrityBlockStore2::_checkVersionHeader(const BlockId &blockId, const Dat
bool IntegrityBlockStore2::_checkIdHeader(const BlockId &expectedBlockId, const Data &data) const {
// The obvious reason for this is to prevent adversaries from renaming blocks, but storing the block id in this way also
// makes the authenticated cipher more robust, see https://libsodium.gitbook.io/doc/secret-key_cryptography/aead#robustness
BlockId actualBlockId = _readBlockId(data);
const BlockId actualBlockId = _readBlockId(data);
if (expectedBlockId != actualBlockId) {
integrityViolationDetected("The block id is wrong. Did an attacker try to rename some blocks?");
return false;
@ -110,8 +110,8 @@ IntegrityBlockStore2::IntegrityBlockStore2(unique_ref<BlockStore2> baseBlockStor
}
bool IntegrityBlockStore2::tryCreate(const BlockId &blockId, const Data &data) {
uint64_t version = _knownBlockVersions.incrementVersion(blockId);
Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data);
const uint64_t version = _knownBlockVersions.incrementVersion(blockId);
const Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data);
return _baseBlockStore->tryCreate(blockId, dataWithHeader);
}
@ -130,11 +130,11 @@ optional<Data> IntegrityBlockStore2::load(const BlockId &blockId) const {
}
#ifndef CRYFS_NO_COMPATIBILITY
if (FORMAT_VERSION_HEADER_OLD == _readFormatHeader(*loaded)) {
Data migrated = _migrateBlock(blockId, *loaded);
const Data migrated = _migrateBlock(blockId, *loaded);
if (!_checkHeader(blockId, migrated) && !_allowIntegrityViolations) {
return optional<Data>(none);
}
Data content = _removeHeader(migrated);
const Data content = _removeHeader(migrated);
const_cast<IntegrityBlockStore2*>(this)->store(blockId, content);
return optional<Data>(_removeHeader(migrated));
}
@ -157,8 +157,8 @@ Data IntegrityBlockStore2::_migrateBlock(const BlockId &blockId, const Data &dat
#endif
void IntegrityBlockStore2::store(const BlockId &blockId, const Data &data) {
uint64_t version = _knownBlockVersions.incrementVersion(blockId);
Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data);
const uint64_t version = _knownBlockVersions.incrementVersion(blockId);
const Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data);
return _baseBlockStore->store(blockId, dataWithHeader);
}
@ -171,7 +171,7 @@ uint64_t IntegrityBlockStore2::estimateNumFreeBytes() const {
}
uint64_t IntegrityBlockStore2::blockSizeFromPhysicalBlockSize(uint64_t blockSize) const {
uint64_t baseBlockSize = _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize);
const uint64_t baseBlockSize = _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize);
if (baseBlockSize <= HEADER_LENGTH) {
return 0;
}
@ -221,9 +221,9 @@ void IntegrityBlockStore2::migrateBlockFromBlockstoreWithoutVersionNumbers(block
return;
}
uint64_t version = knownBlockVersions->incrementVersion(blockId);
cpputils::Data data = std::move(*data_);
cpputils::Data dataWithHeader = _prependHeaderToData(blockId, knownBlockVersions->myClientId(), version, data);
const uint64_t version = knownBlockVersions->incrementVersion(blockId);
const cpputils::Data data = std::move(*data_);
const cpputils::Data dataWithHeader = _prependHeaderToData(blockId, knownBlockVersions->myClientId(), version, data);
baseBlockStore->store(blockId, dataWithHeader);
}
#endif

View File

@ -23,25 +23,27 @@ constexpr uint32_t KnownBlockVersions::CLIENT_ID_FOR_DELETED_BLOCK;
KnownBlockVersions::KnownBlockVersions(const bf::path &stateFilePath, uint32_t myClientId)
:_integrityViolationOnPreviousRun(false), _knownVersions(), _lastUpdateClientId(), _stateFilePath(stateFilePath), _myClientId(myClientId), _mutex(), _valid(true) {
unique_lock<mutex> lock(_mutex);
const unique_lock<mutex> lock(_mutex);
ASSERT(_myClientId != CLIENT_ID_FOR_DELETED_BLOCK, "This is not a valid client id");
_loadStateFile();
}
KnownBlockVersions::KnownBlockVersions(KnownBlockVersions &&rhs) // NOLINT (intentionally not noexcept)
: _integrityViolationOnPreviousRun(false), _knownVersions(), _lastUpdateClientId(), _stateFilePath(), _myClientId(0), _mutex(), _valid(true) {
unique_lock<mutex> rhsLock(rhs._mutex);
unique_lock<mutex> lock(_mutex);
const unique_lock<mutex> rhsLock(rhs._mutex);
const unique_lock<mutex> lock(_mutex);
// NOLINTBEGIN(cppcoreguidelines-prefer-member-initializer) -- we need to initialize those within the mutexes
_integrityViolationOnPreviousRun = rhs._integrityViolationOnPreviousRun;
_knownVersions = std::move(rhs._knownVersions);
_lastUpdateClientId = std::move(rhs._lastUpdateClientId);
_stateFilePath = std::move(rhs._stateFilePath);
_myClientId = rhs._myClientId;
rhs._valid = false;
// NOLINTEND(cppcoreguidelines-prefer-member-initializer)
}
KnownBlockVersions::~KnownBlockVersions() {
unique_lock<mutex> lock(_mutex);
const unique_lock<mutex> lock(_mutex);
if (_valid) {
_saveStateFile();
}
@ -56,7 +58,7 @@ bool KnownBlockVersions::integrityViolationOnPreviousRun() const {
}
bool KnownBlockVersions::checkAndUpdateVersion(uint32_t clientId, const BlockId &blockId, uint64_t version) {
unique_lock<mutex> lock(_mutex);
const unique_lock<mutex> lock(_mutex);
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.
@ -81,9 +83,9 @@ bool KnownBlockVersions::checkAndUpdateVersion(uint32_t clientId, const BlockId
}
uint64_t KnownBlockVersions::incrementVersion(const BlockId &blockId) {
unique_lock<mutex> lock(_mutex);
const unique_lock<mutex> lock(_mutex);
uint64_t &found = _knownVersions[{_myClientId, blockId}]; // If the entry doesn't exist, this creates it with value 0.
uint64_t newVersion = found + 1;
const uint64_t newVersion = found + 1;
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...
throw std::runtime_error("Version overflow");
@ -138,7 +140,7 @@ void KnownBlockVersions::_saveStateFile() const {
}
std::unordered_map<ClientIdAndBlockId, uint64_t> KnownBlockVersions::_deserializeKnownVersions(Deserializer *deserializer) {
uint64_t numEntries = deserializer->readUint64();
const uint64_t numEntries = deserializer->readUint64();
std::unordered_map<ClientIdAndBlockId, uint64_t> result;
result.reserve(static_cast<uint64_t>(1.2 * numEntries)); // Reserve for factor 1.2 more, so the file system doesn't immediately have to resize it on the first new block.
for (uint64_t i = 0 ; i < numEntries; ++i) {
@ -150,7 +152,7 @@ std::unordered_map<ClientIdAndBlockId, uint64_t> KnownBlockVersions::_deserializ
}
void KnownBlockVersions::_serializeKnownVersions(Serializer *serializer, const std::unordered_map<ClientIdAndBlockId, uint64_t>& knownVersions) {
uint64_t numEntries = knownVersions.size();
const uint64_t numEntries = knownVersions.size();
serializer->writeUint64(numEntries);
for (const auto &entry : knownVersions) {
@ -159,9 +161,9 @@ void KnownBlockVersions::_serializeKnownVersions(Serializer *serializer, const s
}
pair<ClientIdAndBlockId, uint64_t> KnownBlockVersions::_deserializeKnownVersionsEntry(Deserializer *deserializer) {
uint32_t clientId = deserializer->readUint32();
BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>());
uint64_t version = deserializer->readUint64();
const uint32_t clientId = deserializer->readUint32();
const BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>());
const uint64_t version = deserializer->readUint64();
return {{clientId, blockId}, version};
};
@ -173,7 +175,7 @@ void KnownBlockVersions::_serializeKnownVersionsEntry(Serializer *serializer, co
}
std::unordered_map<BlockId, uint32_t> KnownBlockVersions::_deserializeLastUpdateClientIds(Deserializer *deserializer) {
uint64_t numEntries = deserializer->readUint64();
const uint64_t numEntries = deserializer->readUint64();
std::unordered_map<BlockId, uint32_t> result;
result.reserve(static_cast<uint64_t>(1.2 * numEntries)); // Reserve for factor 1.2 more, so the file system doesn't immediately have to resize it on the first new block.
for (uint64_t i = 0 ; i < numEntries; ++i) {
@ -184,7 +186,7 @@ std::unordered_map<BlockId, uint32_t> KnownBlockVersions::_deserializeLastUpdate
}
void KnownBlockVersions::_serializeLastUpdateClientIds(Serializer *serializer, const std::unordered_map<BlockId, uint32_t>& lastUpdateClientId) {
uint64_t numEntries = lastUpdateClientId.size();
const uint64_t numEntries = lastUpdateClientId.size();
serializer->writeUint64(numEntries);
for (const auto &entry : lastUpdateClientId) {
@ -193,8 +195,8 @@ void KnownBlockVersions::_serializeLastUpdateClientIds(Serializer *serializer, c
}
pair<BlockId, uint32_t> KnownBlockVersions::_deserializeLastUpdateClientIdEntry(Deserializer *deserializer) {
BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>());
uint32_t clientId = deserializer->readUint32();
const BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>());
const uint32_t clientId = deserializer->readUint32();
return {blockId, clientId};
};
@ -209,7 +211,7 @@ uint32_t KnownBlockVersions::myClientId() const {
}
uint64_t KnownBlockVersions::getBlockVersion(uint32_t clientId, const BlockId &blockId) const {
unique_lock<mutex> lock(_mutex);
const unique_lock<mutex> lock(_mutex);
return _knownVersions.at({clientId, blockId});
}

View File

@ -13,7 +13,7 @@ namespace blockstore {
namespace lowtohighlevel {
optional<unique_ref<LowToHighLevelBlock>> LowToHighLevelBlock::TryCreateNew(BlockStore2 *baseBlockStore, const BlockId &blockId, Data data) {
bool success = baseBlockStore->tryCreate(blockId, data);
const bool success = baseBlockStore->tryCreate(blockId, data);
if (!success) {
return none;
}
@ -43,7 +43,7 @@ LowToHighLevelBlock::LowToHighLevelBlock(const BlockId &blockId, Data data, Bloc
}
LowToHighLevelBlock::~LowToHighLevelBlock() {
unique_lock<mutex> lock(_mutex);
const unique_lock<mutex> lock(_mutex);
_storeToBaseBlock();
}
@ -58,7 +58,7 @@ void LowToHighLevelBlock::write(const void *source, uint64_t offset, uint64_t co
}
void LowToHighLevelBlock::flush() {
unique_lock<mutex> lock(_mutex);
const unique_lock<mutex> lock(_mutex);
_storeToBaseBlock();
}

View File

@ -28,7 +28,7 @@ public:
static boost::optional<cpputils::unique_ref<LowToHighLevelBlock>> Load(BlockStore2 *baseBlockStore, const BlockId &blockId);
LowToHighLevelBlock(const BlockId &blockId, cpputils::Data data, BlockStore2 *baseBlockStore);
~LowToHighLevelBlock();
~LowToHighLevelBlock() override;
const void *data() const override;
void write(const void *source, uint64_t offset, uint64_t count) override;

View File

@ -44,7 +44,7 @@ optional<unique_ref<Block>> LowToHighLevelBlockStore::load(const BlockId &blockI
}
void LowToHighLevelBlockStore::remove(const BlockId &blockId) {
bool success = _baseBlockStore->remove(blockId);
const bool success = _baseBlockStore->remove(blockId);
if (!success) {
throw std::runtime_error("Couldn't delete block with id " + blockId.ToString());
}

View File

@ -113,27 +113,27 @@ namespace blockstore {
private:
void _increaseNumCreatedBlocks() {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
_createdBlocks += 1;
}
void _increaseNumLoadedBlocks(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
_loadedBlocks.push_back(blockId);
}
void _increaseNumRemovedBlocks(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
_removedBlocks.push_back(blockId);
}
void _increaseNumResizedBlocks(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
_resizedBlocks.push_back(blockId);
}
void _increaseNumWrittenBlocks(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
_writtenBlocks.push_back(blockId);
}

View File

@ -19,7 +19,7 @@ constexpr const char* ALLOWED_BLOCKID_CHARACTERS = "0123456789ABCDEF";
}
boost::filesystem::path OnDiskBlockStore2::_getFilepath(const BlockId &blockId) const {
std::string blockIdStr = blockId.ToString();
const std::string blockIdStr = blockId.ToString();
return _rootDir / blockIdStr.substr(0, PREFIX_LENGTH) / blockIdStr.substr(PREFIX_LENGTH);
}
@ -66,7 +66,7 @@ bool OnDiskBlockStore2::remove(const BlockId &blockId) {
if (!boost::filesystem::is_regular_file(filepath)) { // TODO Is this branch necessary?
return false;
}
bool retval = boost::filesystem::remove(filepath);
const bool retval = boost::filesystem::remove(filepath);
if (!retval) {
cpputils::logging::LOG(cpputils::logging::ERR, "Couldn't find block {} to remove", blockId.ToString());
return false;
@ -121,14 +121,14 @@ void OnDiskBlockStore2::forEachBlock(std::function<void (const BlockId &)> callb
continue;
}
std::string blockIdPrefix = prefixDir->path().filename().string();
const std::string blockIdPrefix = prefixDir->path().filename().string();
if (blockIdPrefix.size() != PREFIX_LENGTH || std::string::npos != blockIdPrefix.find_first_not_of(ALLOWED_BLOCKID_CHARACTERS)) {
// directory has wrong length or an invalid character
continue;
}
for (auto block = boost::filesystem::directory_iterator(prefixDir->path()); block != boost::filesystem::directory_iterator(); ++block) {
std::string blockIdPostfix = block->path().filename().string();
const std::string blockIdPostfix = block->path().filename().string();
if (blockIdPostfix.size() != POSTFIX_LENGTH || std::string::npos != blockIdPostfix.find_first_not_of(ALLOWED_BLOCKID_CHARACTERS)) {
// filename has wrong length or an invalid character
continue;

View File

@ -60,7 +60,7 @@ unique_ref<Block> ParallelAccessBlockStore::overwrite(const BlockId &blockId, Da
}
void ParallelAccessBlockStore::remove(unique_ref<Block> block) {
BlockId blockId = block->blockId();
const BlockId blockId = block->blockId();
auto block_ref = dynamic_pointer_move<BlockRef>(block);
ASSERT(block_ref != none, "Block is not a BlockRef");
return _parallelAccessStore.remove(blockId, std::move(*block_ref));

View File

@ -14,7 +14,7 @@ class FakeBlockStore;
class FakeBlock final: public Block {
public:
FakeBlock(FakeBlockStore *store, const BlockId &blockId, std::shared_ptr<cpputils::Data> data, bool dirty);
~FakeBlock();
~FakeBlock() override;
const void *data() const override;
void write(const void *source, uint64_t offset, uint64_t size) override;

View File

@ -23,7 +23,7 @@ BlockId FakeBlockStore::createBlockId() {
}
optional<unique_ref<Block>> FakeBlockStore::tryCreate(const BlockId &blockId, Data data) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
auto insert_result = _blocks.emplace(blockId, std::move(data));
if (!insert_result.second) {
@ -35,7 +35,7 @@ optional<unique_ref<Block>> FakeBlockStore::tryCreate(const BlockId &blockId, Da
}
unique_ref<Block> FakeBlockStore::overwrite(const BlockId &blockId, Data data) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
auto insert_result = _blocks.emplace(blockId, data.copy());
if (!insert_result.second) {
@ -50,7 +50,7 @@ unique_ref<Block> FakeBlockStore::overwrite(const BlockId &blockId, Data data) {
}
optional<unique_ref<Block>> FakeBlockStore::load(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
return _load(blockId);
}
@ -64,8 +64,8 @@ optional<unique_ref<Block>> FakeBlockStore::_load(const BlockId &blockId) {
}
void FakeBlockStore::remove(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex);
int numRemoved = _blocks.erase(blockId);
const std::unique_lock<std::mutex> lock(_mutex);
const size_t numRemoved = _blocks.erase(blockId);
ASSERT(numRemoved == 1, "Block not found");
}
@ -76,7 +76,7 @@ unique_ref<Block> FakeBlockStore::makeFakeBlockFromData(const BlockId &blockId,
}
void FakeBlockStore::updateData(const BlockId &blockId, const Data &data) {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
auto found = _blocks.find(blockId);
if (found == _blocks.end()) {
auto insertResult = _blocks.emplace(blockId, data.copy());
@ -88,7 +88,7 @@ void FakeBlockStore::updateData(const BlockId &blockId, const Data &data) {
}
uint64_t FakeBlockStore::numBlocks() const {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
return _blocks.size();
}

View File

@ -34,7 +34,7 @@ public:
virtual void forEachBlock(std::function<void (const BlockId &)> callback) const = 0;
virtual void remove(cpputils::unique_ref<Block> block) {
BlockId blockId = block->blockId();
const BlockId blockId = block->blockId();
cpputils::destruct(std::move(block));
remove(blockId);
}

View File

@ -33,7 +33,7 @@ public:
BlockId create(const cpputils::Data& data) {
while (true) {
BlockId blockId = createBlockId();
bool success = tryCreate(blockId, data);
const bool success = tryCreate(blockId, data);
if (success) {
return blockId;
}

View File

@ -2,7 +2,6 @@
namespace bf = boost::filesystem;
using std::runtime_error;
using std::string;
namespace blockstore {

View File

@ -11,7 +11,7 @@ namespace blockstore {
class FileDoesntExistException final: public std::runtime_error {
public:
explicit FileDoesntExistException(const boost::filesystem::path &filepath);
~FileDoesntExistException();
~FileDoesntExistException() override;
};
}

View File

@ -61,18 +61,8 @@ if(MSVC)
target_link_libraries(${PROJECT_NAME} PUBLIC DbgHelp)
elseif (APPLE)
target_compile_definitions(${PROJECT_NAME} PRIVATE BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED)
else()
find_program(ADDR2LINE addr2line)
if ("${ADDR2LINE}" STREQUAL "ADDR2LINE-NOTFOUND")
message(WARNING "addr2line not found. Backtraces will be reduced.")
else()
message(STATUS "addr2line found. Using it for backtraces.")
target_compile_definitions(${PROJECT_NAME} PRIVATE BOOST_STACKTRACE_USE_ADDR2LINE)
target_compile_definitions(${PROJECT_NAME} PRIVATE BOOST_STACKTRACE_ADDR2LINE_LOCATION=${ADDR2LINE})
endif()
endif()
find_package(Threads REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_THREAD_LIBS_INIT})

View File

@ -39,9 +39,9 @@ void showBacktraceOnCrash() {
// the signal handler RAII objects will be initialized on first call (which will register the signal handler)
// and destroyed on program exit (which will unregister the signal handler)
static SignalHandlerRAII<&sigsegv_handler> segv(SIGSEGV);
static SignalHandlerRAII<&sigabrt_handler> abrt(SIGABRT);
static SignalHandlerRAII<&sigill_handler> ill(SIGILL);
static const SignalHandlerRAII<&sigsegv_handler> segv(SIGSEGV);
static const SignalHandlerRAII<&sigabrt_handler> abrt(SIGABRT);
static const SignalHandlerRAII<&sigill_handler> ill(SIGILL);
}
}

View File

@ -8,7 +8,7 @@ using namespace cpputils::logging;
namespace cpputils {
Data RandomPadding::add(const Data &data, size_t targetSize) {
uint32_t size = data.size();
const uint32_t size = data.size();
if (size >= targetSize - sizeof(size)) {
throw std::runtime_error("Data too large. We should increase padding target size.");
}
@ -22,7 +22,7 @@ namespace cpputils {
}
optional<Data> RandomPadding::remove(const Data &data) {
uint32_t size = deserialize<uint32_t>(data.data());
const uint32_t size = deserialize<uint32_t>(data.data());
if(sizeof(size) + size >= data.size()) {
LOG(ERR, "Config file is invalid: Invalid padding.");
return boost::none;

View File

@ -2,7 +2,6 @@
#include <cpp-utils/random/Random.h>
#include <vendor_cryptopp/sha.h>
using cpputils::Random;
using CryptoPP::SHA512;
namespace cpputils {

View File

@ -2,7 +2,6 @@
using std::istream;
using std::ostream;
using cpputils::Data;
namespace cpputils {
Data SCryptParameters::serialize() const {
@ -20,9 +19,9 @@ namespace cpputils {
SCryptParameters SCryptParameters::deserialize(const cpputils::Data &data) {
Deserializer deserializer(&data);
uint64_t n = deserializer.readUint64();
uint32_t r = deserializer.readUint32();
uint32_t p = deserializer.readUint32();
const uint64_t n = deserializer.readUint64();
const uint32_t r = deserializer.readUint32();
const uint32_t p = deserializer.readUint32();
Data salt = deserializer.readTailData();
deserializer.finished();
return SCryptParameters(std::move(salt), n, r, p);
@ -30,9 +29,9 @@ namespace cpputils {
#ifndef CRYFS_NO_COMPATIBILITY
SCryptParameters SCryptParameters::deserializeOldFormat(Deserializer *source) {
uint64_t n = source->readUint64();
uint32_t r = source->readUint32();
uint32_t p = source->readUint32();
const uint64_t n = source->readUint64();
const uint32_t r = source->readUint32();
const uint32_t p = source->readUint32();
Data salt = source->readData();
return SCryptParameters(std::move(salt), n, r, p);
}

View File

@ -13,7 +13,7 @@ namespace {
EncryptionKey _derive(size_t keySize, const std::string& password, const SCryptParameters& kdfParameters) {
auto result = EncryptionKey::Null(keySize);
size_t status = CryptoPP::Scrypt().DeriveKey(
const size_t status = CryptoPP::Scrypt().DeriveKey(
static_cast<uint8_t*>(result.data()), result.binaryLength(),
reinterpret_cast<const uint8_t*>(password.c_str()), password.size(),
static_cast<const uint8_t*>(kdfParameters.salt().data()), kdfParameters.salt().size(),
@ -36,13 +36,13 @@ SCrypt::SCrypt(const SCryptSettings& settingsForNewKeys)
}
EncryptionKey SCrypt::deriveExistingKey(size_t keySize, const std::string& password, const Data& kdfParameters) {
SCryptParameters parameters = SCryptParameters::deserialize(kdfParameters);
const SCryptParameters parameters = SCryptParameters::deserialize(kdfParameters);
auto key = _derive(keySize, password, parameters);
return key;
}
SCrypt::KeyResult SCrypt::deriveNewKey(size_t keySize, const std::string& password) {
SCryptParameters kdfParameters = _createNewSCryptParameters(_settingsForNewKeys);
const SCryptParameters kdfParameters = _createNewSCryptParameters(_settingsForNewKeys);
auto key = _derive(keySize, password, kdfParameters);
return SCrypt::KeyResult {
key,

View File

@ -23,7 +23,7 @@ namespace cpputils {
public:
static constexpr SCryptSettings ParanoidSettings = SCryptSettings {32, 1048576, 8, 16};
static constexpr SCryptSettings DefaultSettings = SCryptSettings {32, 1048576, 4, 8};
static constexpr SCryptSettings TestSettings = SCryptSettings {32, 1024, 1, 1};
static constexpr SCryptSettings TestSettings = SCryptSettings {32, 1024, 1, 2};
explicit SCrypt(const SCryptSettings& settingsForNewKeys);

View File

@ -49,7 +49,7 @@ Data AEADCipher<CryptoPPCipher, KEYSIZE_, IV_SIZE_, TAG_SIZE_>::encrypt(const Cr
Data ciphertext(ciphertextSize(plaintextSize));
iv.ToBinary(ciphertext.data());
CryptoPP::ArraySource(plaintext, plaintextSize, true,
const CryptoPP::ArraySource _1(plaintext, plaintextSize, true,
new CryptoPP::AuthenticatedEncryptionFilter(encryption,
new CryptoPP::ArraySink(static_cast<CryptoPP::byte*>(ciphertext.data()) + IV_SIZE, ciphertext.size() - IV_SIZE),
false, TAG_SIZE
@ -73,7 +73,7 @@ boost::optional<Data> AEADCipher<CryptoPPCipher, KEYSIZE_, IV_SIZE_, TAG_SIZE_>:
Data plaintext(plaintextSize(ciphertextSize));
try {
CryptoPP::ArraySource(static_cast<const CryptoPP::byte*>(ciphertextData), ciphertextSize - IV_SIZE, true,
const CryptoPP::ArraySource _1(static_cast<const CryptoPP::byte*>(ciphertextData), ciphertextSize - IV_SIZE, true,
new CryptoPP::AuthenticatedDecryptionFilter(decryption,
new CryptoPP::ArraySink(static_cast<CryptoPP::byte*>(plaintext.data()), plaintext.size()),
CryptoPP::AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_SIZE

View File

@ -19,10 +19,10 @@ public:
same_type(UINT32_C(0), X::plaintextSize(UINT32_C(5)));
same_type(UINT32_C(0), X::KEYSIZE);
same_type(UINT32_C(0), X::STRING_KEYSIZE);
typename X::EncryptionKey key = X::EncryptionKey::CreateKey(Random::OSRandom(), X::KEYSIZE);
const typename X::EncryptionKey key = X::EncryptionKey::CreateKey(Random::OSRandom(), X::KEYSIZE);
same_type(Data(0), X::encrypt(static_cast<uint8_t*>(nullptr), UINT32_C(0), key));
same_type(boost::optional<Data>(Data(0)), X::decrypt(static_cast<uint8_t*>(nullptr), UINT32_C(0), key));
string name = X::NAME;
const string name = X::NAME;
}
private:

View File

@ -59,14 +59,14 @@ namespace cpputils {
Data result(ciphertextSize(plaintextSize));
//Add a random IV
uint64_t iv = std::uniform_int_distribution<uint64_t>()(random_);
const uint64_t iv = std::uniform_int_distribution<uint64_t>()(random_);
serialize<uint64_t>(result.data(), iv);
//Use xor chiffre on plaintext
_xor(static_cast<CryptoPP::byte*>(result.dataOffset(sizeof(uint64_t))), plaintext, plaintextSize, encKey.value ^ iv);
//Add checksum information
uint64_t checksum = _checksum(static_cast<const CryptoPP::byte*>(result.data()), encKey, plaintextSize + sizeof(uint64_t));
const uint64_t checksum = _checksum(static_cast<const CryptoPP::byte*>(result.data()), encKey, plaintextSize + sizeof(uint64_t));
serialize<uint64_t>(result.dataOffset(plaintextSize + sizeof(uint64_t)), checksum);
return result;
@ -80,14 +80,14 @@ namespace cpputils {
}
//Check checksum
uint64_t expectedParity = _checksum(ciphertext, encKey, plaintextSize(ciphertextSize) + sizeof(uint64_t));
uint64_t actualParity = deserialize<uint64_t>(ciphertext + plaintextSize(ciphertextSize) + sizeof(uint64_t));
const uint64_t expectedParity = _checksum(ciphertext, encKey, plaintextSize(ciphertextSize) + sizeof(uint64_t));
const uint64_t actualParity = deserialize<uint64_t>(ciphertext + plaintextSize(ciphertextSize) + sizeof(uint64_t));
if (expectedParity != actualParity) {
return boost::none;
}
//Decrypt xor chiffre from ciphertext
uint64_t iv = deserialize<uint64_t>(ciphertext);
const uint64_t iv = deserialize<uint64_t>(ciphertext);
Data result(plaintextSize(ciphertextSize));
_xor(static_cast<CryptoPP::byte *>(result.data()), ciphertext + sizeof(uint64_t), plaintextSize(ciphertextSize), encKey.value ^ iv);

View File

@ -39,7 +39,7 @@ std::streampos Data::_getStreamSize(istream &stream) {
Data Data::LoadFromStream(istream &stream, size_t size) {
Data result(size);
stream.read(static_cast<char*>(result.data()), result.size());
stream.read(static_cast<char*>(result.data()), static_cast<std::streamsize>(result.size()));
return result;
}
@ -47,7 +47,7 @@ Data Data::FromString(const std::string &data, unique_ref<Allocator> allocator)
ASSERT(data.size() % 2 == 0, "hex encoded data cannot have odd number of characters");
Data result(data.size() / 2, std::move(allocator));
{
CryptoPP::StringSource _1(data, true,
const CryptoPP::StringSource _1(data, true,
new CryptoPP::HexDecoder(
new CryptoPP::ArraySink(static_cast<CryptoPP::byte*>(result._data), result.size())
)
@ -59,7 +59,7 @@ Data Data::FromString(const std::string &data, unique_ref<Allocator> allocator)
std::string Data::ToString() const {
std::string result;
{
CryptoPP::ArraySource _1(static_cast<const CryptoPP::byte*>(_data), _size, true,
const CryptoPP::ArraySource _1(static_cast<const CryptoPP::byte*>(_data), _size, true,
new CryptoPP::HexEncoder(
new CryptoPP::StringSink(result)
)

View File

@ -184,7 +184,7 @@ inline void Data::StoreToFile(const boost::filesystem::path &filepath) const {
}
inline void Data::StoreToStream(std::ostream &stream) const {
stream.write(static_cast<const char*>(_data), _size);
stream.write(static_cast<const char*>(_data), static_cast<std::streamsize>(_size));
}
inline Data Data::LoadFromStream(std::istream &stream) {

View File

@ -11,7 +11,7 @@ namespace cpputils {
val += 1442695040888963407;
serialize<unsigned long long int>(result.dataOffset(i*sizeof(unsigned long long int)), val);
}
uint64_t alreadyWritten = (size/sizeof(unsigned long long int))*sizeof(unsigned long long int);
const uint64_t alreadyWritten = (size/sizeof(unsigned long long int))*sizeof(unsigned long long int);
val *= 6364136223846793005L;
val += 1442695040888963407;
unsigned char *remainingBytes = reinterpret_cast<unsigned char*>(&val);

View File

@ -44,7 +44,7 @@ namespace cpputils {
}
inline bool Deserializer::readBool() {
uint8_t read = readUint8();
const uint8_t read = readUint8();
if (read == 1) {
return true;
} else if (read == 0) {
@ -98,7 +98,7 @@ namespace cpputils {
}
inline Data Deserializer::readData() {
uint64_t size = readUint64();
const uint64_t size = readUint64();
if (_pos + size > _source->size()) {
throw std::runtime_error("Deserialization failed - size overflow");
}
@ -106,7 +106,7 @@ namespace cpputils {
}
inline Data Deserializer::readTailData() {
uint64_t size = _source->size() - _pos;
const uint64_t size = _source->size() - _pos;
return _readData(size);
}
@ -134,7 +134,7 @@ namespace cpputils {
if (nullbytepos == nullptr) {
throw std::runtime_error("Deserialization failed - missing nullbyte for string termination");
}
uint64_t size = static_cast<const uint8_t*>(nullbytepos) - static_cast<const uint8_t*>(_source->dataOffset(_pos));
const uint64_t size = static_cast<const uint8_t*>(nullbytepos) - static_cast<const uint8_t*>(_source->dataOffset(_pos));
std::string result(static_cast<const char*>(_source->dataOffset(_pos)), size);
_pos += size + 1;
return result;

View File

@ -61,7 +61,7 @@ FixedSizeData<SIZE> FixedSizeData<SIZE>::FromString(const std::string &data) {
ASSERT(data.size() == STRING_LENGTH, "Wrong string size for parsing FixedSizeData");
FixedSizeData<SIZE> result;
{
CryptoPP::StringSource _1(data, true,
const CryptoPP::StringSource _1(data, true,
new CryptoPP::HexDecoder(
new CryptoPP::ArraySink(result._data.data(), BINARY_LENGTH)
)
@ -73,7 +73,7 @@ FixedSizeData<SIZE> FixedSizeData<SIZE>::FromString(const std::string &data) {
template<size_t SIZE>
std::string FixedSizeData<SIZE>::ToString() const {
std::string result;
CryptoPP::ArraySource(_data.data(), BINARY_LENGTH, true,
const CryptoPP::ArraySource _1(_data.data(), BINARY_LENGTH, true,
new CryptoPP::HexEncoder(
new CryptoPP::StringSink(result)
)

View File

@ -71,7 +71,6 @@ namespace cpputils
#endif
using cpputils::make_unique_ref;
namespace cpputils
{

View File

@ -99,7 +99,7 @@ namespace cpputils {
this->d_condition.wait(lock);
}
if (&this->d_tmp[0] != this->d_current) {
std::streamsize size(this->d_current - &this->d_tmp[0]);
const std::streamsize size(this->d_current - &this->d_tmp[0]);
traits_type::copy(this->eback(), &this->d_tmp[0],
this->d_current - &this->d_tmp[0]);
this->setg(this->eback(), this->eback(), this->eback() + size);
@ -134,14 +134,14 @@ namespace cpputils {
this->d_condition.wait(lock);
}
if (this->d_current != end) {
std::streamsize size(std::min(end - d_current,
const std::streamsize size(std::min(end - d_current,
this->pptr() - this->pbase()));
traits_type::copy(d_current, this->pbase(), size);
this->d_current += size;
std::streamsize remain((this->pptr() - this->pbase()) - size);
const std::streamsize remain((this->pptr() - this->pbase()) - size);
traits_type::move(this->pbase(), this->pptr(), remain);
this->setp(this->pbase(), this->epptr());
this->pbump(remain);
this->pbump(static_cast<int>(remain));
this->d_condition.notify_one();
return 0;
}

View File

@ -26,7 +26,7 @@ namespace cpputils {
}
void release() {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
_triggered = true;
_cv.notify_all();
}

View File

@ -79,7 +79,7 @@ namespace cpputils {
template<class LockName>
inline void LockPool<LockName>::release(const LockName &lockName) {
std::unique_lock<std::mutex> mutexLock(_mutex);
const std::unique_lock<std::mutex> mutexLock(_mutex);
auto found = std::find(_lockedLocks.begin(), _lockedLocks.end(), lockName);
ASSERT(found != _lockedLocks.end(), "Lock given to release() was not locked");
_lockedLocks.erase(found);

View File

@ -2,7 +2,6 @@
using std::string;
using boost::optional;
using boost::none;
namespace cpputils {
FakeHttpClient::FakeHttpClient(): _sites() {

View File

@ -161,7 +161,8 @@ inline bool operator!=(const unique_ref<T, D> &lhs, const unique_ref<T, D> &rhs)
}
namespace std { // NOLINT (intentional change of namespace std)
// NOLINTBEGIN(cert-dcl58-cpp) -- intentional change of namespace std
namespace std {
template<class T, class D>
inline void swap(cpputils::unique_ref<T, D>& lhs, cpputils::unique_ref<T, D>& rhs) noexcept {
lhs.swap(rhs);
@ -191,5 +192,6 @@ namespace std { // NOLINT (intentional change of namespace std)
}
};
}
// NOLINTEND(cert-dcl58-cpp)
#endif

View File

@ -123,7 +123,7 @@ SignalCatcher::SignalCatcher(std::initializer_list<int> signals)
// - the _signal_occurred flag will not be destructed as long as the signal handler might be called (i.e. as long as _impls lives)
_impls.reserve(signals.size());
for (int signal : signals) {
for (const int signal : signals) {
_impls.emplace_back(make_unique<details::SignalCatcherImpl>(signal, &_signal_occurred));
}
}

View File

@ -29,7 +29,7 @@ public:
std::memset(&new_signal_handler, 0, sizeof(new_signal_handler));
new_signal_handler.sa_handler = handler; // NOLINT(cppcoreguidelines-pro-type-union-access)
new_signal_handler.sa_flags = SA_RESTART;
int error = sigfillset(&new_signal_handler.sa_mask); // block all signals while signal handler is running
const int error = sigfillset(&new_signal_handler.sa_mask); // block all signals while signal handler is running
if (0 != error) {
throw std::runtime_error("Error calling sigfillset. Errno: " + std::to_string(errno));
}
@ -47,7 +47,7 @@ public:
private:
static void _sigaction(int signal, struct sigaction *new_handler, struct sigaction *old_handler) {
int error = sigaction(signal, new_handler, old_handler);
const int error = sigaction(signal, new_handler, old_handler);
if (0 != error) {
throw std::runtime_error("Error calling sigaction. Errno: " + std::to_string(errno));
}

View File

@ -21,7 +21,7 @@ using namespace cpputils::logging;
namespace cpputils {
void daemonize() {
pid_t pid = fork();
const pid_t pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
@ -34,7 +34,7 @@ void daemonize() {
umask(0);
// Create a new SID for the child process
pid_t sid = setsid();
const pid_t sid = setsid();
if (sid < 0) {
LOG(ERR, "Failed to get SID for daemon process");
exit(EXIT_FAILURE);

View File

@ -1,10 +1,11 @@
#include "subprocess.h"
#include <array>
#include <boost/asio.hpp>
#include <boost/process.hpp>
#include <cerrno>
#include <cstddef>
#include <cstdio>
#include <stdexcept>
#include <cerrno>
#include <array>
#include <boost/process.hpp>
#include <boost/asio.hpp>
using std::string;
using std::vector;

View File

@ -2,10 +2,11 @@
#ifndef MESSMER_CPPUTILS_RANDOM_PSEUDORANDOMPOOL_H
#define MESSMER_CPPUTILS_RANDOM_PSEUDORANDOMPOOL_H
#include <boost/thread.hpp>
#include "RandomGenerator.h"
#include "ThreadsafeRandomDataBuffer.h"
#include "RandomGeneratorThread.h"
#include "ThreadsafeRandomDataBuffer.h"
#include <boost/thread.hpp>
#include <cstddef>
#include <mutex>
namespace cpputils {

View File

@ -12,13 +12,13 @@ namespace cpputils {
class Random final {
public:
static PseudoRandomPool &PseudoRandom() {
std::unique_lock <std::mutex> lock(_mutex);
const std::unique_lock <std::mutex> lock(_mutex);
static PseudoRandomPool random;
return random;
}
static OSRandomGenerator &OSRandom() {
std::unique_lock <std::mutex> lock(_mutex);
const std::unique_lock <std::mutex> lock(_mutex);
static OSRandomGenerator random;
return random;
}

View File

@ -39,7 +39,7 @@ namespace cpputils {
inline void RandomDataBuffer::add(const Data& newData) {
// Concatenate old and new random data
size_t oldSize = size();
const size_t oldSize = size();
Data combined(oldSize + newData.size());
get(combined.data(), oldSize);
std::memcpy(combined.dataOffset(oldSize), newData.data(), newData.size());

View File

@ -8,6 +8,7 @@ namespace cpputils {
class RandomGenerator {
public:
RandomGenerator();
virtual ~RandomGenerator() = default;
template<size_t SIZE> FixedSizeData<SIZE> getFixedSize();
Data get(size_t size);

View File

@ -17,9 +17,9 @@ namespace cpputils {
bool RandomGeneratorThread::_loopIteration() {
_buffer->waitUntilSizeIsLessThan(_minSize);
size_t neededRandomDataSize = _maxSize - _buffer->size();
const size_t neededRandomDataSize = _maxSize - _buffer->size();
ASSERT(_maxSize > _buffer->size(), "This could theoretically fail if another thread refilled the buffer. But we should be the only refilling thread.");
Data randomData = _generateRandomData(neededRandomDataSize);
const Data randomData = _generateRandomData(neededRandomDataSize);
_buffer->add(randomData);
return true; // Run another iteration (don't terminate thread)
}

View File

@ -39,14 +39,14 @@ namespace cpputils {
}
inline size_t ThreadsafeRandomDataBuffer::size() const {
boost::unique_lock<boost::mutex> lock(_mutex);
const boost::unique_lock<boost::mutex> lock(_mutex);
return _buffer.size();
}
inline void ThreadsafeRandomDataBuffer::get(void *target, size_t numBytes) {
size_t alreadyGotten = 0;
while (alreadyGotten < numBytes) {
size_t got = _get(static_cast<uint8_t*>(target)+alreadyGotten, numBytes);
const size_t got = _get(static_cast<uint8_t*>(target)+alreadyGotten, numBytes);
alreadyGotten += got;
ASSERT(alreadyGotten <= numBytes, "Got too many bytes");
}
@ -57,14 +57,14 @@ namespace cpputils {
_dataAddedCv.wait(lock, [this] {
return _buffer.size() > 0;
});
size_t gettableBytes = (std::min)(_buffer.size(), numBytes);
const size_t gettableBytes = (std::min)(_buffer.size(), numBytes);
_buffer.get(target, gettableBytes);
_dataGottenCv.notify_all();
return gettableBytes;
}
inline void ThreadsafeRandomDataBuffer::add(const Data& data) {
boost::unique_lock<boost::mutex> lock(_mutex);
const boost::unique_lock<boost::mutex> lock(_mutex);
_buffer.add(data);
_dataAddedCv.notify_all();
}

View File

@ -11,7 +11,7 @@ namespace cpputils {
uint64_t free_disk_space_in_bytes(const bf::path& location) {
struct statvfs stat {};
int result = ::statvfs(location.string().c_str(), &stat);
const int result = ::statvfs(location.string().c_str(), &stat);
if (0 != result) {
throw std::runtime_error("Error calling statvfs(). Errno: " + std::to_string(errno));
}

View File

@ -10,14 +10,14 @@
namespace cpputils {
void setenv(const char* key, const char* value) {
int retval = ::setenv(key, value, 1);
const int retval = ::setenv(key, value, 1);
if (0 != retval) {
throw std::runtime_error("Error setting environment variable. Errno: " + std::to_string(errno));
}
}
void unsetenv(const char* key) {
int retval = ::unsetenv(key);
const int retval = ::unsetenv(key);
if (0 != retval) {
throw std::runtime_error("Error unsetting environment variable. Errno: " + std::to_string(errno));
}
@ -34,7 +34,7 @@ namespace cpputils {
void setenv(const char* key, const char* value) {
std::ostringstream command;
command << key << "=" << value;
int retval = _putenv(command.str().c_str());
const int retval = _putenv(command.str().c_str());
if (0 != retval) {
throw std::runtime_error("Error setting environment variable. Errno: " + std::to_string(errno));
}

View File

@ -14,7 +14,7 @@ int set_filetime(const char *filepath, timespec lastAccessTime, timespec lastMod
std::array<struct timeval, 2> casted_times{};
TIMESPEC_TO_TIMEVAL(&casted_times[0], &lastAccessTime);
TIMESPEC_TO_TIMEVAL(&casted_times[1], &lastModificationTime);
int retval = ::utimes(filepath, casted_times.data());
const int retval = ::utimes(filepath, casted_times.data());
if (0 == retval) {
return 0;
} else {
@ -24,7 +24,7 @@ int set_filetime(const char *filepath, timespec lastAccessTime, timespec lastMod
int get_filetime(const char *filepath, timespec* lastAccessTime, timespec* lastModificationTime) {
struct ::stat attrib{};
int retval = ::stat(filepath, &attrib);
const int retval = ::stat(filepath, &attrib);
if (retval != 0) {
return errno;
}

View File

@ -28,8 +28,8 @@ namespace cpputils {
namespace cpputils {
namespace system {
uint64_t get_total_memory() {
long numRAMPages = sysconf(_SC_PHYS_PAGES);
long pageSize = sysconf(_SC_PAGESIZE);
const long numRAMPages = sysconf(_SC_PHYS_PAGES);
const long pageSize = sysconf(_SC_PAGESIZE);
return numRAMPages * pageSize;
}
}

View File

@ -11,7 +11,7 @@ namespace cpputils {
TempFile::TempFile(const bf::path &path, bool create)
: _path(path) {
if (create) {
ofstream file(_path.string().c_str());
const ofstream file(_path.string().c_str());
if (!file.good()) {
throw std::runtime_error("Could not create tempfile");
}

View File

@ -11,8 +11,8 @@ namespace cpputils {
class CaptureStderrRAII final {
public:
CaptureStderrRAII() {
_oldBuffer = std::cerr.rdbuf();
CaptureStderrRAII() : _oldBuffer(std::cerr.rdbuf()) {
// Capture stderr to _buffer
std::cerr.rdbuf(_buffer.rdbuf());

View File

@ -38,7 +38,7 @@ public:
// wait until any potentially running writers are finished
{
std::unique_lock<std::mutex> lock(_writeMutex);
const std::unique_lock<std::mutex> lock(_writeMutex);
}
// wait until any potentially running readers are finished
@ -49,7 +49,7 @@ public:
template <typename F>
auto read(F&& readFunc) const {
detail::IncrementRAII _increment_counter(&_counters[_foregroundCounterIndex.load()]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
const detail::IncrementRAII _increment_counter(&_counters[_foregroundCounterIndex.load()]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
if(_inDestruction.load()) {
throw std::logic_error("Issued LeftRight::read() after the destructor started running");
@ -62,7 +62,7 @@ public:
// depending on if the first or the second call to writeFunc threw.
template <typename F>
auto write(F&& writeFunc) {
std::unique_lock<std::mutex> lock(_writeMutex);
const std::unique_lock<std::mutex> lock(_writeMutex);
if(_inDestruction.load()) {
throw std::logic_error("Issued LeftRight::read() after the destructor started running");

View File

@ -24,7 +24,7 @@ namespace cpputils {
}
ThreadSystem::Handle ThreadSystem::start(function<bool()> loopIteration, string threadName) {
boost::unique_lock<boost::mutex> lock(_mutex);
const boost::unique_lock<boost::mutex> lock(_mutex);
auto thread = _startThread(loopIteration, threadName);
_runningThreads.push_back(RunningThread{std::move(threadName), std::move(loopIteration), std::move(thread)});
return std::prev(_runningThreads.end());

View File

@ -28,9 +28,9 @@ void set_thread_name(const char* name) {
name_.resize(MAX_NAME_LEN - 1);
}
#if defined(__APPLE__)
int result = pthread_setname_np(name_.c_str());
const int result = pthread_setname_np(name_.c_str());
#else
int result = pthread_setname_np(pthread_self(), name_.c_str());
const int result = pthread_setname_np(pthread_self(), name_.c_str());
#endif
if (0 != result) {
throw std::runtime_error("Error setting thread name with pthread_setname_np. Code: " + std::to_string(result));
@ -75,9 +75,9 @@ int pthread_getname_np_gcompat(pthread_t thread, char *name, size_t len) {
std::string get_thread_name(pthread_t thread) {
std::array<char, MAX_NAME_LEN> name{};
#if defined(__GLIBC__) || defined(__APPLE__)
int result = pthread_getname_np(thread, name.data(), MAX_NAME_LEN);
const int result = pthread_getname_np(thread, name.data(), MAX_NAME_LEN);
#else
int result = pthread_getname_np_gcompat(thread, name.data(), MAX_NAME_LEN);
const int result = pthread_getname_np_gcompat(thread, name.data(), MAX_NAME_LEN);
#endif
if (0 != result) {
throw std::runtime_error("Error getting thread name with pthread_getname_np. Code: " + std::to_string(result));

View File

@ -32,7 +32,7 @@ namespace cryfs_cli {
}
inline void CallAfterTimeout::resetTimer() {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
_start = boost::chrono::steady_clock::now();
}
@ -42,12 +42,12 @@ namespace cryfs_cli {
}
inline boost::chrono::time_point<boost::chrono::steady_clock> CallAfterTimeout::_targetTime() {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
return _start + _timeout;
}
inline bool CallAfterTimeout::_callCallbackIfTimeout() {
std::unique_lock<std::mutex> lock(_mutex);
const std::unique_lock<std::mutex> lock(_mutex);
if (boost::chrono::steady_clock::now() >= _start + _timeout) {
_callback();
return false; // Stop thread

View File

@ -126,7 +126,7 @@ namespace cryfs_cli {
cpputils::set_thread_name("cryfs");
try {
_sanityChecks(options);
LocalStateDir localStateDir(options.localStateDir());
const LocalStateDir localStateDir(options.localStateDir());
auto blockStore = make_unique_ref<OnDiskBlockStore2>(options.baseDir());
auto config = _loadOrCreateConfig(options, localStateDir, credentials);
fspp::fuse::Fuse* fuse = nullptr;

View File

@ -46,7 +46,7 @@ namespace cryfs_cli {
}
optional<ptree> VersionChecker::_getVersionInfo(HttpClient* httpClient) {
long timeoutMsec = 2000;
const long timeoutMsec = 2000;
string response;
try {
response = httpClient->get("https://www.cryfs.org/version_info.json", timeoutMsec);

View File

@ -12,7 +12,7 @@ namespace cryfs_cli {
namespace program_options {
pair<vector<string>, vector<string>> splitAtDoubleDash(const vector<string> &options) {
auto doubleDashIterator = std::find(options.begin(), options.end(), string("--"));
vector<string> beforeDoubleDash(options.begin(), doubleDashIterator);
const vector<string> beforeDoubleDash(options.begin(), doubleDashIterator);
vector<string> afterDoubleDash;
if (doubleDashIterator != options.end() && doubleDashIterator + 1 != options.end()) {
afterDoubleDash.reserve(options.size() - beforeDoubleDash.size() - 1);

View File

@ -36,6 +36,7 @@ set(LIB_SOURCES
impl/filesystem/parallelaccessfsblobstore/FsBlobRef.cpp
impl/filesystem/parallelaccessfsblobstore/FileBlobRef.cpp
impl/filesystem/parallelaccessfsblobstore/SymlinkBlobRef.cpp
impl/filesystem/entry_helper.cpp
impl/filesystem/CrySymlink.cpp
impl/filesystem/CryDir.cpp
impl/filesystem/cachingfsblobstore/DirBlobRef.cpp

View File

@ -100,6 +100,6 @@ vector<string> CryCiphers::_buildSupportedCipherNames() {
}
const vector<string>& CryCiphers::supportedCipherNames() {
static vector<string> supportedCipherNames = _buildSupportedCipherNames();
static const vector<string> supportedCipherNames = _buildSupportedCipherNames();
return supportedCipherNames;
}

View File

@ -30,7 +30,7 @@ namespace cryfs {
config.SetFilesystemId(_generateFilesystemID());
auto encryptionKey = _generateEncKey(config.Cipher());
auto localState = LocalStateMetadata::loadOrGenerate(_localStateDir.forFilesystemId(config.FilesystemId()), cpputils::Data::FromString(encryptionKey), allowReplacedFilesystem);
uint32_t myClientId = localState.myClientId();
const uint32_t myClientId = localState.myClientId();
config.SetEncryptionKey(std::move(encryptionKey));
config.SetExclusiveClientId(_generateExclusiveClientId(missingBlockIsIntegrityViolationFromCommandLine, myClientId));
#ifndef CRYFS_NO_COMPATIBILITY

View File

@ -74,7 +74,7 @@ void CryConfigFile::save() const {
if (_access == Access::ReadOnly) {
throw std::logic_error("Tried to save the cryfs.config file while being in read only mode");
}
Data configData = _config.save();
const Data configData = _config.save();
auto encrypted = _encryptor->encrypt(configData, _config.Cipher());
encrypted.StoreToFile(_path);
}

View File

@ -19,7 +19,6 @@ using boost::none;
using std::shared_ptr;
using std::string;
using std::shared_ptr;
using gitversion::VersionCompare;
using namespace cpputils::logging;
namespace cryfs {
@ -58,7 +57,7 @@ either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> CryConfigLoa
}
_checkCipher(*config.right()->config());
auto localState = LocalStateMetadata::loadOrGenerate(_localStateDir.forFilesystemId(config.right()->config()->FilesystemId()), cpputils::Data::FromString(config.right()->config()->EncryptionKey()), allowReplacedFilesystem);
uint32_t myClientId = localState.myClientId();
const uint32_t myClientId = localState.myClientId();
_checkMissingBlocksAreIntegrityViolations(config.right().get(), myClientId);
return ConfigLoadResult {std::move(oldConfig), std::move(config.right()), myClientId};
}

View File

@ -19,9 +19,9 @@ namespace cryfs {
}
Data CryConfigEncryptor::encrypt(const Data &plaintext, const string &cipherName) const {
InnerConfig innerConfig = _innerEncryptor(cipherName)->encrypt(plaintext);
Data serializedInnerConfig = innerConfig.serialize();
OuterConfig outerConfig = _outerEncryptor()->encrypt(serializedInnerConfig);
const InnerConfig innerConfig = _innerEncryptor(cipherName)->encrypt(plaintext);
const Data serializedInnerConfig = innerConfig.serialize();
const OuterConfig outerConfig = _outerEncryptor()->encrypt(serializedInnerConfig);
return outerConfig.serialize();
}

View File

@ -32,7 +32,7 @@ namespace cryfs {
Deserializer deserializer(&data);
try {
_checkHeader(&deserializer);
string cipherName = deserializer.readString();
const string cipherName = deserializer.readString();
auto result = deserializer.readTailData();
deserializer.finished();
return InnerConfig {cipherName, std::move(result)};
@ -43,7 +43,7 @@ namespace cryfs {
}
void InnerConfig::_checkHeader(Deserializer *deserializer) {
string header = deserializer->readString();
const string header = deserializer->readString();
if (header != HEADER) {
throw std::runtime_error("Invalid header. Maybe this filesystem was created with a different version of CryFS?");
}

View File

@ -18,7 +18,7 @@ namespace cryfs {
const string OuterConfig::HEADER = "cryfs.config;1;scrypt";
void OuterConfig::_checkHeader(Deserializer *deserializer) {
string header = deserializer->readString();
const string header = deserializer->readString();
if (header != HEADER) {
throw std::runtime_error("Invalid header");
}
@ -47,7 +47,7 @@ namespace cryfs {
Deserializer deserializer(&data);
try {
#ifndef CRYFS_NO_COMPATIBILITY
string header = deserializer.readString();
const string header = deserializer.readString();
if (header == OLD_HEADER) {
return _deserializeOldFormat(&deserializer);
} else if (header == HEADER) {

View File

@ -78,7 +78,7 @@ unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CryDevice::Crea
#ifndef CRYFS_NO_COMPATIBILITY
unique_ref<fsblobstore::FsBlobStore> CryDevice::MigrateOrCreateFsBlobStore(unique_ref<BlobStore> blobStore, CryConfigFile *configFile) {
string rootBlobId = configFile->config()->RootBlob();
const string rootBlobId = configFile->config()->RootBlob();
if ("" == rootBlobId) {
return make_unique_ref<FsBlobStore>(std::move(blobStore));
}
@ -194,9 +194,12 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
return optional<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, none, none, _rootBlobId));
}
auto parentWithGrandparent = LoadDirBlobWithParent(path.parent_path());
auto parent = std::move(parentWithGrandparent.blob);
auto grandparent = std::move(parentWithGrandparent.parent);
auto parentWithAncestors = LoadDirBlobWithAncestors(path.parent_path(), [](const BlockId&){});
if (parentWithAncestors == none) {
return none;
}
auto parent = std::move(parentWithAncestors->blob);
auto grandparent = std::move(parentWithAncestors->parent);
auto optEntry = parent->GetChild(path.filename().string());
if (optEntry == boost::none) {
@ -215,16 +218,19 @@ optional<unique_ref<fspp::Node>> CryDevice::Load(const bf::path &path) {
ASSERT(false, "Switch/case not exhaustive");
}
CryDevice::DirBlobWithParent CryDevice::LoadDirBlobWithParent(const bf::path &path) {
auto blob = LoadBlobWithParent(path);
auto dir = dynamic_pointer_move<DirBlobRef>(blob.blob);
optional<CryDevice::DirBlobWithAncestors> CryDevice::LoadDirBlobWithAncestors(const bf::path &path, std::function<void (const blockstore::BlockId&)> ancestor_callback) {
auto blob = LoadBlobWithAncestors(path, std::move(ancestor_callback));
if (blob == none) {
return none;
}
auto dir = dynamic_pointer_move<DirBlobRef>(blob->blob);
if (dir == none) {
throw FuseErrnoException(ENOTDIR); // Loaded blob is not a directory
}
return DirBlobWithParent{std::move(*dir), std::move(blob.parent)};
return DirBlobWithAncestors{std::move(*dir), std::move(blob->parent)};
}
CryDevice::BlobWithParent CryDevice::LoadBlobWithParent(const bf::path &path) {
optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf::path &path, std::function<void (const blockstore::BlockId&)> ancestor_callback) {
optional<unique_ref<DirBlobRef>> parentBlob = none;
optional<unique_ref<FsBlobRef>> currentBlobOpt = _fsBlobStore->load(_rootBlobId);
if (currentBlobOpt == none) {
@ -235,6 +241,7 @@ CryDevice::BlobWithParent CryDevice::LoadBlobWithParent(const bf::path &path) {
ASSERT(currentBlob->parentPointer() == BlockId::Null(), "Root Blob should have a nullptr as parent");
for (const bf::path &component : path.relative_path()) {
ancestor_callback(currentBlob->blockId());
auto currentDir = dynamic_pointer_move<DirBlobRef>(currentBlob);
if (currentDir == none) {
throw FuseErrnoException(ENOTDIR); // Path component is not a dir
@ -242,19 +249,20 @@ CryDevice::BlobWithParent CryDevice::LoadBlobWithParent(const bf::path &path) {
auto childOpt = (*currentDir)->GetChild(component.string());
if (childOpt == boost::none) {
throw FuseErrnoException(ENOENT); // Child entry in directory not found
// Child entry in directory not found
return none;
}
BlockId childId = childOpt->blockId();
const BlockId childId = childOpt->blockId();
auto nextBlob = _fsBlobStore->load(childId);
if (nextBlob == none) {
throw FuseErrnoException(ENOENT); // Blob for directory entry not found
throw FuseErrnoException(EIO); // Blob for directory entry not found
}
parentBlob = std::move(*currentDir);
currentBlob = std::move(*nextBlob);
ASSERT(currentBlob->parentPointer() == (*parentBlob)->blockId(), "Blob has wrong parent pointer");
}
return BlobWithParent{std::move(currentBlob), std::move(parentBlob)};
return BlobWithAncestors{std::move(currentBlob), std::move(parentBlob)};
//TODO (I think this is resolved, but I should test it)
// Running the python script, waiting for "Create files in sequential order...", then going into dir ~/tmp/cryfs-mount-.../Bonnie.../ and calling "ls"
@ -265,8 +273,8 @@ CryDevice::BlobWithParent CryDevice::LoadBlobWithParent(const bf::path &path) {
CryDevice::statvfs CryDevice::statfs() {
callFsActionCallbacks();
uint64_t numUsedBlocks = _fsBlobStore->numBlocks();
uint64_t numFreeBlocks = _fsBlobStore->estimateSpaceForNumBlocksLeft();
const uint64_t numUsedBlocks = _fsBlobStore->numBlocks();
const uint64_t numFreeBlocks = _fsBlobStore->estimateSpaceForNumBlocksLeft();
statvfs result;
result.max_filename_length = 255; // We theoretically support unlimited file name length, but this is default for many Linux file systems, so probably also makes sense for CryFS.
@ -314,7 +322,7 @@ void CryDevice::RemoveBlob(const blockstore::BlockId &blockId) {
}
BlockId CryDevice::GetOrCreateRootBlobId(CryConfigFile *configFile) {
string root_blockId = configFile->config()->RootBlob();
const string root_blockId = configFile->config()->RootBlob();
if (root_blockId == "") { // NOLINT (workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82481 )
auto new_blockId = CreateRootBlobAndReturnId();
configFile->config()->SetRootBlob(new_blockId.ToString());

View File

@ -28,11 +28,11 @@ public:
cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> CreateDirBlob(const blockstore::BlockId &parent);
cpputils::unique_ref<parallelaccessfsblobstore::SymlinkBlobRef> CreateSymlinkBlob(const boost::filesystem::path &target, const blockstore::BlockId &parent);
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> LoadBlob(const blockstore::BlockId &blockId);
struct DirBlobWithParent {
cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> blob;
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
struct DirBlobWithAncestors {
cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef> blob;
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
};
DirBlobWithParent LoadDirBlobWithParent(const boost::filesystem::path &path);
boost::optional<DirBlobWithAncestors> LoadDirBlobWithAncestors(const boost::filesystem::path &path, std::function<void (const blockstore::BlockId&)> ancestor_callback);
void RemoveBlob(const blockstore::BlockId &blockId);
void onFsAction(std::function<void()> callback);
@ -65,11 +65,11 @@ private:
static cpputils::unique_ref<blockstore::BlockStore2> CreateIntegrityEncryptedBlockStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, const LocalStateDir& localStateDir, CryConfigFile *configFile, uint32_t myClientId, bool allowIntegrityViolations, bool missingBlockIsIntegrityViolation, std::function<void()> onIntegrityViolation);
static cpputils::unique_ref<blockstore::BlockStore2> CreateEncryptedBlockStore(const CryConfig &config, cpputils::unique_ref<blockstore::BlockStore2> baseBlockStore);
struct BlobWithParent {
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> blob;
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
struct BlobWithAncestors {
cpputils::unique_ref<parallelaccessfsblobstore::FsBlobRef> blob;
boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent;
};
BlobWithParent LoadBlobWithParent(const boost::filesystem::path &path);
boost::optional<BlobWithAncestors> LoadBlobWithAncestors(const boost::filesystem::path &path, std::function<void (const blockstore::BlockId&)> ancestor_callback);
DISALLOW_COPY_AND_ASSIGN(CryDevice);
};

View File

@ -81,6 +81,11 @@ vector<fspp::Dir::Entry> CryDir::children() {
return children;
}
size_t CryDir::numChildren() {
auto blob = LoadBlob();
return blob->NumChildren();
}
fspp::Dir::EntryType CryDir::getType() const {
device()->callFsActionCallbacks();
return fspp::Dir::EntryType::DIR;

View File

@ -11,7 +11,7 @@ namespace cryfs {
class CryDir final: public fspp::Dir, public CryNode {
public:
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() override;
//TODO return type variance to CryFile/CryDir?
cpputils::unique_ref<fspp::OpenFile> createAndOpenFile(const std::string &name, fspp::mode_t mode, fspp::uid_t uid, fspp::gid_t gid) override;
@ -20,6 +20,7 @@ public:
//TODO Make Entry a public class instead of hidden in DirBlob (which is not publicly visible)
std::vector<fspp::Dir::Entry> children() override;
size_t numChildren();
fspp::Dir::EntryType getType() const override;

View File

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

View File

@ -8,11 +8,13 @@
#include <cpp-utils/system/time.h>
#include <cpp-utils/system/stat.h>
#include <cpp-utils/logging/logging.h>
#include "entry_helper.h"
namespace bf = boost::filesystem;
using blockstore::BlockId;
using cpputils::unique_ref;
using cpputils::dynamic_pointer_move;
using boost::optional;
using boost::none;
using std::shared_ptr;
@ -77,32 +79,69 @@ fspp::TimestampUpdateBehavior CryNode::timestampUpdateBehavior() const {
void CryNode::rename(const bf::path &to) {
device()->callFsActionCallbacks();
if (_parent == none) {
//We are the root direcory.
// We are the root direcory.
throw FuseErrnoException(EBUSY);
}
auto targetDirWithParent = _device->LoadDirBlobWithParent(to.parent_path());
auto targetDir = std::move(targetDirWithParent.blob);
auto targetDirParent = std::move(targetDirWithParent.parent);
if (!to.has_parent_path()) {
// Target is the root directory
throw FuseErrnoException(EBUSY);
}
auto targetParentAndAncestors = _device->LoadDirBlobWithAncestors(to.parent_path(), [&] (const BlockId& ancestorId) {
if (ancestorId == _blockId) {
// We are trying to move a node into one of its subdirectories. This is not allowed.
throw FuseErrnoException(EINVAL);
}
});
if (targetParentAndAncestors == none) {
// Target parent directory doesn't exist
throw FuseErrnoException(ENOENT);
}
auto targetParent = std::move(targetParentAndAncestors->blob);
auto targetGrandparent = std::move(targetParentAndAncestors->parent);
if (targetParent->blockId() == _blockId) {
// We are trying to move a node into one of its subdirectories. This is not allowed.
throw FuseErrnoException(EINVAL);
}
auto old = (*_parent)->GetChild(_blockId);
if (old == boost::none) {
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.
const 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::BlockId &blockId) {
device()->RemoveBlob(blockId);
};
_updateParentModificationTimestamp();
if (targetDir->blockId() == (*_parent)->blockId()) {
targetDir->RenameChild(oldEntry.blockId(), to.filename().string(), onOverwritten);
if (targetParent->blockId() == (*_parent)->blockId()) {
_updateParentModificationTimestamp();
targetParent->RenameChild(oldEntry.blockId(), to.filename().string(), onOverwritten);
} else {
_updateTargetDirModificationTimestamp(*targetDir, std::move(targetDirParent));
targetDir->AddOrOverwriteChild(to.filename().string(), oldEntry.blockId(), oldEntry.type(), oldEntry.mode(), oldEntry.uid(), oldEntry.gid(),
oldEntry.lastAccessTime(), oldEntry.lastModificationTime(), onOverwritten);
auto preexistingTargetEntry = targetParent->GetChild(to.filename().string());
if (preexistingTargetEntry != boost::none && preexistingTargetEntry->type() == fspp::Dir::EntryType::DIR) {
if (getType() != fspp::Dir::EntryType::DIR) {
// A directory cannot be overwritten with a non-directory
throw FuseErrnoException(EISDIR);
}
auto preexistingTarget = device()->LoadBlob(preexistingTargetEntry->blockId());
auto preexistingTargetDir = dynamic_pointer_move<DirBlobRef>(preexistingTarget);
if (preexistingTargetDir == none) {
LOG(ERR, "Preexisting target is not a directory. But its parent dir entry says it's a directory");
throw FuseErrnoException(EIO);
}
if ((*preexistingTargetDir)->NumChildren() > 0) {
// Cannot overwrite a non-empty dir with a rename operation.
throw FuseErrnoException(ENOTEMPTY);
}
}
_updateParentModificationTimestamp();
_updateTargetDirModificationTimestamp(*targetParent, std::move(targetGrandparent));
targetParent->AddOrOverwriteChild(to.filename().string(), oldEntry.blockId(), oldEntry.type(), oldEntry.mode(), oldEntry.uid(), oldEntry.gid(),
oldEntry.lastAccessTime(), oldEntry.lastModificationTime(), onOverwritten);
(*_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.
LoadBlob()->setParentPointer(targetDir->blockId());
_parent = std::move(targetDir);
// targetParent is now the new parent for this node. Adapt to it, so we can call further operations on this node object.
LoadBlob()->setParentPointer(targetParent->blockId());
_parent = std::move(targetParent);
}
}
@ -179,13 +218,17 @@ CryNode::stat_info CryNode::stat() const {
result.size = fsblobstore::DirBlob::DIR_LSTAT_SIZE;
//TODO If possible without performance loss, then for a directory, st_nlink should return number of dir entries (including "." and "..")
result.nlink = 1;
struct timespec now = cpputils::time::now();
const struct timespec now = cpputils::time::now();
result.atime = now;
result.mtime = now;
result.ctime = now;
return result;
} else {
return (*_parent)->statChild(_blockId);
auto childOpt = (*_parent)->GetChild(_blockId);
if (childOpt == boost::none) {
throw fspp::fuse::FuseErrnoException(ENOENT);
}
return dirEntryToStatInfo(*childOpt, LoadBlob()->lstat_size());
}
}

View File

@ -12,7 +12,7 @@ namespace cryfs {
class CryNode: public fspp::Node {
public:
virtual ~CryNode();
~CryNode() override;
// 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::BlockId &blockId);

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