- Switch some CI jobs to clang 15

- Fix clang-tidy warnings from Clang 15
This commit is contained in:
Sebastian Messmer 2023-07-08 14:48:59 -07:00
parent 764f46dc33
commit 9ccb006f61
282 changed files with 1435 additions and 1398 deletions

View File

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

View File

@ -180,9 +180,9 @@ jobs:
- name: Local dependencies - name: Local dependencies
os: ubuntu-22.04 os: ubuntu-22.04
compiler: compiler:
cxx: clang++-11 cxx: clang++-15
cc: clang-11 cc: clang-15
apt_package: clang-11 libomp5-11 libomp-11-dev apt_package: clang-15 libomp5-15 libomp-15-dev
build_type: RelWithDebInfo build_type: RelWithDebInfo
extra_cmake_flags: -DDEPENDENCY_CONFIG=../cmake-utils/DependenciesFromLocalSystem.cmake extra_cmake_flags: -DDEPENDENCY_CONFIG=../cmake-utils/DependenciesFromLocalSystem.cmake
extra_cxxflags: "" extra_cxxflags: ""
@ -193,9 +193,9 @@ jobs:
- name: Local dependencies - name: Local dependencies
os: ubuntu-22.04 os: ubuntu-22.04
compiler: compiler:
cxx: clang++-11 cxx: clang++-15
cc: clang-11 cc: clang-15
apt_package: clang-11 libomp5-11 libomp-11-dev apt_package: clang-15 libomp5-15 libomp-15-dev
build_type: RelWithDebInfo build_type: RelWithDebInfo
extra_cmake_flags: -DDEPENDENCY_CONFIG=../cmake-utils/DependenciesFromLocalSystem.cmake extra_cmake_flags: -DDEPENDENCY_CONFIG=../cmake-utils/DependenciesFromLocalSystem.cmake
extra_cxxflags: "" extra_cxxflags: ""
@ -218,9 +218,9 @@ jobs:
- name: Werror clang - name: Werror clang
os: ubuntu-22.04 os: ubuntu-22.04
compiler: compiler:
cxx: clang++-11 cxx: clang++-15
cc: clang-11 cc: clang-15
apt_package: clang-11 libomp5-11 libomp-11-dev apt_package: clang-15 libomp5-15 libomp-15-dev
build_type: RelWithDebInfo build_type: RelWithDebInfo
extra_cmake_flags: -DUSE_WERROR=on extra_cmake_flags: -DUSE_WERROR=on
extra_cxxflags: "" extra_cxxflags: ""
@ -230,9 +230,9 @@ jobs:
- name: No compatibility - name: No compatibility
os: ubuntu-22.04 os: ubuntu-22.04
compiler: compiler:
cxx: clang++-11 cxx: clang++-15
cc: clang-11 cc: clang-15
apt_package: clang-11 libomp5-11 libomp-11-dev apt_package: clang-15 libomp5-15 libomp-15-dev
build_type: RelWithDebInfo build_type: RelWithDebInfo
extra_cmake_flags: "" extra_cmake_flags: ""
extra_cxxflags: "-DCRYFS_NO_COMPATIBILITY" extra_cxxflags: "-DCRYFS_NO_COMPATIBILITY"
@ -241,12 +241,11 @@ jobs:
run_build: true run_build: true
run_tests: true run_tests: true
- name: ASAN - name: ASAN
# TODO Update to ubuntu-22.04 os: ubuntu-22.04
os: ubuntu-20.04
compiler: compiler:
cxx: clang++-11 cxx: clang++-15
cc: clang-11 cc: clang-15
apt_package: clang-11 libomp5-11 libomp-11-dev apt_package: clang-15 libomp5-15 libomp-15-dev
build_type: Debug build_type: Debug
# OpenMP crashes under asan. Disable OpenMP. # OpenMP crashes under asan. Disable OpenMP.
# TODO is it enough to replace this with omp_num_threads: 1 ? # TODO is it enough to replace this with omp_num_threads: 1 ?
@ -257,12 +256,11 @@ jobs:
run_build: true run_build: true
run_tests: true run_tests: true
- name: UBSAN - name: UBSAN
# TODO Update to ubuntu-22.04 os: ubuntu-22.04
os: ubuntu-20.04
compiler: compiler:
cxx: clang++-11 cxx: clang++-15
cc: clang-11 cc: clang-15
apt_package: clang-11 libomp5-11 libomp-11-dev apt_package: clang-15 libomp5-15 libomp-15-dev
build_type: Debug build_type: Debug
# OpenMP crashes under ubsan. Disable OpenMP. # OpenMP crashes under ubsan. Disable OpenMP.
# TODO is it enough to replace this with omp_num_threads: 1 ? # TODO is it enough to replace this with omp_num_threads: 1 ?
@ -273,12 +271,11 @@ jobs:
run_build: true run_build: true
run_tests: true run_tests: true
- name: TSAN - name: TSAN
# TODO Update to ubuntu-22.04 os: ubuntu-22.04
os: ubuntu-20.04
compiler: compiler:
cxx: clang++-11 cxx: clang++-15
cc: clang-11 cc: clang-15
apt_package: clang-11 libomp5-11 libomp-11-dev apt_package: clang-15 libomp5-15 libomp-15-dev
build_type: Debug build_type: Debug
extra_cmake_flags: "" extra_cmake_flags: ""
extra_cxxflags: "-O2 -fsanitize=thread -fno-omit-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-common" extra_cxxflags: "-O2 -fsanitize=thread -fno-omit-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-common"
@ -290,9 +287,9 @@ jobs:
- name: clang-tidy - name: clang-tidy
os: ubuntu-22.04 os: ubuntu-22.04
compiler: compiler:
cxx: clang++-11 cxx: clang++-15
cc: clang-11 cc: clang-15
apt_package: clang-11 clang-tidy-11 libomp5-11 libomp-11-dev apt_package: clang-15 clang-tidy-15 libomp5-15 libomp-15-dev
build_type: RelWithDebInfo build_type: RelWithDebInfo
extra_cmake_flags: "" extra_cmake_flags: ""
extra_cxxflags: "" extra_cxxflags: ""

View File

@ -8,9 +8,9 @@
set -e set -e
CXX=clang++-11 CXX=clang++-15
CC=clang-11 CC=clang-15
SCRIPT=run-clang-tidy-11.py SCRIPT=run-clang-tidy-15.py
export NUMCORES=`nproc` && if [ ! -n "$NUMCORES" ]; then export NUMCORES=`sysctl -n hw.ncpu`; fi export NUMCORES=`nproc` && if [ ! -n "$NUMCORES" ]; then export NUMCORES=`sysctl -n hw.ncpu`; fi
echo Using ${NUMCORES} cores echo Using ${NUMCORES} cores

View File

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

View File

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

View File

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

View File

@ -26,13 +26,13 @@ DataLeafNode::~DataLeafNode() {
unique_ref<DataLeafNode> DataLeafNode::CreateNewNode(BlockStore *blockStore, const DataNodeLayout &layout, Data data) { 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."); 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))); 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) { unique_ref<DataLeafNode> DataLeafNode::OverwriteNode(BlockStore *blockStore, const DataNodeLayout &layout, const BlockId &blockId, Data data) {
ASSERT(data.size() == layout.maxBytesPerLeaf(), "Data passed in is too large for one leaf."); ASSERT(data.size() == layout.maxBytesPerLeaf(), "Data passed in is too large for one leaf.");
uint32_t size = data.size(); 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))); 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) { void DataLeafNode::resize(uint32_t new_size) {
ASSERT(new_size <= maxStoreableBytes(), "Trying to resize to a size larger than the maximal 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) { if (new_size < old_size) {
fillDataWithZeroesFromTo(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); static cpputils::unique_ref<DataLeafNode> OverwriteNode(blockstore::BlockStore *blockStore, const DataNodeLayout &layout, const blockstore::BlockId &blockId, cpputils::Data data);
DataLeafNode(DataNodeView block); DataLeafNode(DataNodeView block);
~DataLeafNode(); ~DataLeafNode() override;
//Returning uint64_t, because calculations handling this probably need to be done in 64bit to support >4GB blobs. //Returning uint64_t, because calculations handling this probably need to be done in 64bit to support >4GB blobs.
uint64_t maxStoreableBytes() const; uint64_t maxStoreableBytes() const;

View File

@ -80,7 +80,7 @@ unique_ref<DataNode> DataNodeStore::overwriteNodeWith(unique_ref<DataNode> targe
} }
void DataNodeStore::remove(unique_ref<DataNode> node) { void DataNodeStore::remove(unique_ref<DataNode> node) {
BlockId blockId = node->blockId(); const BlockId blockId = node->blockId();
cpputils::destruct(std::move(node)); cpputils::destruct(std::move(node));
remove(blockId); remove(blockId);
} }

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) { 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"); 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"); ASSERT(serialized.size() == layout.blocksizeBytes(), "Wrong block size");
auto block = blockStore->create(serialized); auto block = blockStore->create(serialized);
return DataNodeView(std::move(block)); return DataNodeView(std::move(block));

View File

@ -51,7 +51,7 @@ const BlockId &DataTree::blockId() const {
void DataTree::flush() const { void DataTree::flush() const {
// By grabbing a lock, we ensure that all modifying functions don't run currently and are therefore flushed. // 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. // 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 // We also have to flush the root node
_rootNode->flush(); _rootNode->flush();
} }
@ -59,7 +59,7 @@ void DataTree::flush() const {
unique_ref<DataNode> DataTree::releaseRootNode() { unique_ref<DataNode> DataTree::releaseRootNode() {
// Lock also ensures that the root node is currently set (traversing unsets it temporarily) // 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. // 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); return std::move(_rootNode);
} }
@ -74,13 +74,13 @@ uint32_t DataTree::numNodes() const {
} }
uint32_t DataTree::numLeaves() const { uint32_t DataTree::numLeaves() const {
shared_lock<shared_mutex> lock(_treeStructureMutex); const shared_lock<shared_mutex> lock(_treeStructureMutex);
return _getOrComputeSizeCache().numLeaves; return _getOrComputeSizeCache().numLeaves;
} }
uint64_t DataTree::numBytes() const { uint64_t DataTree::numBytes() const {
shared_lock<shared_mutex> lock(_treeStructureMutex); const shared_lock<shared_mutex> lock(_treeStructureMutex);
return _numBytes(); return _numBytes();
} }
@ -107,11 +107,11 @@ DataTree::SizeCache DataTree::_computeSizeCache(const DataNode &node) const {
} }
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(node); const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(node);
uint32_t numLeavesInLeftChildren = static_cast<uint32_t>(inner.numChildren()-1) * _leavesPerFullChild(inner); const uint32_t numLeavesInLeftChildren = static_cast<uint32_t>(inner.numChildren()-1) * _leavesPerFullChild(inner);
uint64_t numBytesInLeftChildren = numLeavesInLeftChildren * _nodeStore->layout().maxBytesPerLeaf(); const uint64_t numBytesInLeftChildren = numLeavesInLeftChildren * _nodeStore->layout().maxBytesPerLeaf();
auto lastChild = _nodeStore->load(inner.readLastChild().blockId()); auto lastChild = _nodeStore->load(inner.readLastChild().blockId());
ASSERT(lastChild != none, "Couldn't load last child"); ASSERT(lastChild != none, "Couldn't load last child");
SizeCache sizeInRightChild = _computeSizeCache(**lastChild); const SizeCache sizeInRightChild = _computeSizeCache(**lastChild);
return SizeCache { return SizeCache {
numLeavesInLeftChildren + sizeInRightChild.numLeaves, numLeavesInLeftChildren + sizeInRightChild.numLeaves,
@ -136,16 +136,16 @@ void DataTree::_traverseLeavesByByteIndices(uint64_t beginByte, uint64_t sizeByt
return; return;
} }
uint64_t endByte = beginByte + sizeBytes; const uint64_t endByte = beginByte + sizeBytes;
uint64_t _maxBytesPerLeaf = maxBytesPerLeaf(); const uint64_t _maxBytesPerLeaf = maxBytesPerLeaf();
uint32_t firstLeaf = beginByte / _maxBytesPerLeaf; const uint32_t firstLeaf = beginByte / _maxBytesPerLeaf;
uint32_t endLeaf = utils::ceilDivision(endByte, _maxBytesPerLeaf); const uint32_t endLeaf = utils::ceilDivision(endByte, _maxBytesPerLeaf);
bool blobIsGrowingFromThisTraversal = false; bool blobIsGrowingFromThisTraversal = false;
auto _onExistingLeaf = [&onExistingLeaf, beginByte, endByte, endLeaf, _maxBytesPerLeaf, &blobIsGrowingFromThisTraversal] (uint32_t leafIndex, bool isRightBorderLeaf, LeafHandle leafHandle) { 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"); ASSERT(endByte > indexOfFirstLeafByte, "Traversal went too far right");
uint32_t dataBegin = utils::maxZeroSubtraction(beginByte, indexOfFirstLeafByte); const uint32_t dataBegin = utils::maxZeroSubtraction(beginByte, indexOfFirstLeafByte);
uint32_t dataEnd = std::min(_maxBytesPerLeaf, endByte - 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 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) { if (isRightBorderLeaf) {
ASSERT(leafIndex == endLeaf-1, "If we traversed further right, this wouldn't be the right border leaf."); ASSERT(leafIndex == endLeaf-1, "If we traversed further right, this wouldn't be the right border leaf.");
@ -160,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 { auto _onCreateLeaf = [&onCreateLeaf, _maxBytesPerLeaf, beginByte, firstLeaf, endByte, endLeaf, &blobIsGrowingFromThisTraversal, readOnlyTraversal] (uint32_t leafIndex) -> Data {
ASSERT(!readOnlyTraversal, "Cannot create leaves in a read-only traversal"); ASSERT(!readOnlyTraversal, "Cannot create leaves in a read-only traversal");
blobIsGrowingFromThisTraversal = true; blobIsGrowingFromThisTraversal = true;
uint64_t indexOfFirstLeafByte = leafIndex * _maxBytesPerLeaf; const uint64_t indexOfFirstLeafByte = leafIndex * _maxBytesPerLeaf;
ASSERT(endByte > indexOfFirstLeafByte, "Traversal went too far right"); ASSERT(endByte > indexOfFirstLeafByte, "Traversal went too far right");
uint32_t dataBegin = utils::maxZeroSubtraction(beginByte, indexOfFirstLeafByte); const uint32_t dataBegin = utils::maxZeroSubtraction(beginByte, indexOfFirstLeafByte);
uint32_t dataEnd = std::min(_maxBytesPerLeaf, endByte - 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 == 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"); ASSERT(leafIndex == endLeaf-1 || dataEnd == _maxBytesPerLeaf, "Only the rightmost leaf can have a gap on the right");
Data data = onCreateLeaf(indexOfFirstLeafByte + dataBegin, dataEnd-dataBegin); Data data = onCreateLeaf(indexOfFirstLeafByte + dataBegin, dataEnd-dataBegin);
@ -195,11 +195,11 @@ uint32_t DataTree::_leavesPerFullChild(const DataInnerNode &root) const {
} }
void DataTree::resizeNumBytes(uint64_t newNumBytes) { 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())); const uint32_t newNumLeaves = std::max(UINT64_C(1), utils::ceilDivision(newNumBytes, _nodeStore->layout().maxBytesPerLeaf()));
uint32_t newLastLeafSize = newNumBytes - (newNumLeaves-1) * _nodeStore->layout().maxBytesPerLeaf(); const uint32_t newLastLeafSize = newNumBytes - (newNumLeaves-1) * _nodeStore->layout().maxBytesPerLeaf();
uint32_t maxChildrenPerInnerNode = _nodeStore->layout().maxChildrenPerInnerNode(); const uint32_t maxChildrenPerInnerNode = _nodeStore->layout().maxChildrenPerInnerNode();
auto onExistingLeaf = [newLastLeafSize] (uint32_t /*index*/, bool /*isRightBorderLeaf*/, LeafHandle leafHandle) { auto onExistingLeaf = [newLastLeafSize] (uint32_t /*index*/, bool /*isRightBorderLeaf*/, LeafHandle leafHandle) {
auto leaf = leafHandle.node(); auto leaf = leafHandle.node();
// This is only called, if the new last leaf was already existing // This is only called, if the new last leaf was already existing
@ -214,10 +214,10 @@ void DataTree::resizeNumBytes(uint64_t newNumBytes) {
auto onBacktrackFromSubtree = [this, newNumLeaves, maxChildrenPerInnerNode] (DataInnerNode* node) { auto onBacktrackFromSubtree = [this, newNumLeaves, maxChildrenPerInnerNode] (DataInnerNode* node) {
// This is only called for the right border nodes of the new tree. // 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. // 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)); const uint32_t maxLeavesPerChild = utils::intPow(static_cast<uint64_t>(maxChildrenPerInnerNode), (static_cast<uint64_t>(node->depth())-1));
uint32_t neededNodesOnChildLevel = utils::ceilDivision(newNumLeaves, maxLeavesPerChild); const uint32_t neededNodesOnChildLevel = utils::ceilDivision(newNumLeaves, maxLeavesPerChild);
uint32_t neededSiblings = utils::ceilDivision(neededNodesOnChildLevel, maxChildrenPerInnerNode); const uint32_t neededSiblings = utils::ceilDivision(neededNodesOnChildLevel, maxChildrenPerInnerNode);
uint32_t neededChildrenForRightBorderNode = neededNodesOnChildLevel - (neededSiblings-1) * maxChildrenPerInnerNode; const uint32_t neededChildrenForRightBorderNode = neededNodesOnChildLevel - (neededSiblings-1) * maxChildrenPerInnerNode;
ASSERT(neededChildrenForRightBorderNode <= node->numChildren(), "Node has too few children"); ASSERT(neededChildrenForRightBorderNode <= node->numChildren(), "Node has too few children");
// All children to the right of the new right-border-node are removed including their subtree. // All children to the right of the new right-border-node are removed including their subtree.
while(node->numChildren() > neededChildrenForRightBorderNode) { while(node->numChildren() > neededChildrenForRightBorderNode) {
@ -238,12 +238,12 @@ uint64_t DataTree::maxBytesPerLeaf() const {
} }
uint8_t DataTree::depth() const { uint8_t DataTree::depth() const {
shared_lock<shared_mutex> lock(_treeStructureMutex); const shared_lock<shared_mutex> lock(_treeStructureMutex);
return _rootNode->depth(); return _rootNode->depth();
} }
void DataTree::readBytes(void *target, uint64_t offset, uint64_t count) const { 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(); const uint64_t _size = _numBytes();
if(offset > _size || offset + count > _size) { if(offset > _size || offset + count > _size) {
@ -256,10 +256,10 @@ void DataTree::readBytes(void *target, uint64_t offset, uint64_t count) const {
} }
Data DataTree::readAllBytes() 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()? //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); Data result(count);
_doReadBytes(result.data(), 0, count); _doReadBytes(result.data(), 0, count);
@ -267,7 +267,7 @@ Data DataTree::readAllBytes() const {
} }
uint64_t DataTree::tryReadBytes(void *target, uint64_t offset, uint64_t count) 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); auto result = _tryReadBytes(target, offset, count);
return result; return result;
} }
@ -294,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) { 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) { 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"); 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) { T getOrCompute(std::function<T ()> compute) {
boost::upgrade_lock<boost::shared_mutex> readLock(_mutex); boost::upgrade_lock<boost::shared_mutex> readLock(_mutex);
if (_cache == boost::none) { 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(); _cache = compute();
} }
return *_cache; return *_cache;
} }
void update(std::function<void (boost::optional<T>*)> func) { 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); func(&_cache);
} }

View File

@ -37,8 +37,8 @@ namespace blobstore {
// beginIndex<numLeaves<endIndex, beginIndex=numLeaves<endIndex, // beginIndex<numLeaves<endIndex, beginIndex=numLeaves<endIndex,
// numLeaves<beginIndex<endIndex, numLeaves<beginIndex=endIndex // numLeaves<beginIndex<endIndex, numLeaves<beginIndex=endIndex
uint32_t maxLeavesForDepth = _maxLeavesForTreeDepth((*root)->depth()); const uint32_t maxLeavesForDepth = _maxLeavesForTreeDepth((*root)->depth());
bool increaseTreeDepth = endIndex > maxLeavesForDepth; const bool increaseTreeDepth = endIndex > maxLeavesForDepth;
ASSERT(!_readOnlyTraversal || !increaseTreeDepth, "Tried to grow a tree on a read only traversal"); ASSERT(!_readOnlyTraversal || !increaseTreeDepth, "Tried to grow a tree on a read only traversal");
if ((*root)->depth() == 0) { if ((*root)->depth() == 0) {
@ -49,7 +49,7 @@ namespace blobstore {
leaf->resize(_nodeStore->layout().maxBytesPerLeaf()); leaf->resize(_nodeStore->layout().maxBytesPerLeaf());
} }
if (beginIndex == 0 && endIndex >= 1) { if (beginIndex == 0 && endIndex >= 1) {
bool isRightBorderLeaf = (endIndex == 1); const bool isRightBorderLeaf = (endIndex == 1);
onExistingLeaf(0, isRightBorderLeaf, LeafHandle(_nodeStore, leaf)); onExistingLeaf(0, isRightBorderLeaf, LeafHandle(_nodeStore, leaf));
} }
} else { } else {
@ -119,21 +119,21 @@ namespace blobstore {
//TODO Call callbacks for different leaves in parallel. //TODO Call callbacks for different leaves in parallel.
uint32_t leavesPerChild = _maxLeavesForTreeDepth(root->depth()-1); const uint32_t leavesPerChild = _maxLeavesForTreeDepth(root->depth()-1);
uint32_t beginChild = beginIndex/leavesPerChild; const uint32_t beginChild = beginIndex/leavesPerChild;
uint32_t endChild = utils::ceilDivision(endIndex, 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."); 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(!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"); 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), // 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. // we still have to descend to the last old child to fill it with leaves and grow the last old leaf.
if (isLeftBorderOfTraversal && beginChild >= numChildren) { if (isLeftBorderOfTraversal && beginChild >= numChildren) {
ASSERT(numChildren > 0, "Node doesn't have children."); ASSERT(numChildren > 0, "Node doesn't have children.");
auto childBlockId = root->readLastChild().blockId(); 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, _traverseExistingSubtree(childBlockId, root->depth()-1, leavesPerChild, leavesPerChild, childOffset, true, false, true,
[] (uint32_t /*index*/, bool /*isRightBorderNode*/, LeafHandle /*leaf*/) {ASSERT(false, "We don't actually traverse any leaves.");}, [] (uint32_t /*index*/, bool /*isRightBorderNode*/, LeafHandle /*leaf*/) {ASSERT(false, "We don't actually traverse any leaves.");},
[] (uint32_t /*index*/) -> Data {ASSERT(false, "We don't actually traverse any leaves.");}, [] (uint32_t /*index*/) -> Data {ASSERT(false, "We don't actually traverse any leaves.");},
@ -143,12 +143,12 @@ namespace blobstore {
// Traverse existing children // Traverse existing children
for (uint32_t childIndex = beginChild; childIndex < std::min(endChild, numChildren); ++childIndex) { for (uint32_t childIndex = beginChild; childIndex < std::min(endChild, numChildren); ++childIndex) {
auto childBlockId = root->readChild(childIndex).blockId(); auto childBlockId = root->readChild(childIndex).blockId();
uint32_t childOffset = childIndex * leavesPerChild; const uint32_t childOffset = childIndex * leavesPerChild;
uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset); const uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset);
uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset); const uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
bool isFirstChild = (childIndex == beginChild); const bool isFirstChild = (childIndex == beginChild);
bool isLastExistingChild = (childIndex == numChildren - 1); const bool isLastExistingChild = (childIndex == numChildren - 1);
bool isLastChild = isLastExistingChild && (numChildren == endChild); 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."); 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, _traverseExistingSubtree(childBlockId, root->depth()-1, localBeginIndex, localEndIndex, leafOffset + childOffset, isLeftBorderOfTraversal && isFirstChild,
isRightBorderNode && isLastChild, shouldGrowLastExistingLeaf && isLastExistingChild, onExistingLeaf, onCreateLeaf, onBacktrackFromSubtree); isRightBorderNode && isLastChild, shouldGrowLastExistingLeaf && isLastExistingChild, onExistingLeaf, onCreateLeaf, onBacktrackFromSubtree);
@ -158,9 +158,9 @@ namespace blobstore {
for (uint32_t childIndex = numChildren; childIndex < endChild; ++childIndex) { for (uint32_t childIndex = numChildren; childIndex < endChild; ++childIndex) {
ASSERT(!_readOnlyTraversal, "Can't create new children in a read-only traversal"); ASSERT(!_readOnlyTraversal, "Can't create new children in a read-only traversal");
uint32_t childOffset = childIndex * leavesPerChild; const uint32_t childOffset = childIndex * leavesPerChild;
uint32_t localBeginIndex = std::min(leavesPerChild, utils::maxZeroSubtraction(beginIndex, childOffset)); const uint32_t localBeginIndex = std::min(leavesPerChild, utils::maxZeroSubtraction(beginIndex, childOffset));
uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset); const uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
auto leafCreator = (childIndex >= beginChild) ? onCreateLeaf : _createMaxSizeLeaf(); auto leafCreator = (childIndex >= beginChild) ? onCreateLeaf : _createMaxSizeLeaf();
auto child = _createNewSubtree(localBeginIndex, localEndIndex, leafOffset + childOffset, root->depth() - 1, leafCreator, onBacktrackFromSubtree); auto child = _createNewSubtree(localBeginIndex, localEndIndex, leafOffset + childOffset, root->depth() - 1, leafCreator, onBacktrackFromSubtree);
root->addChild(*child); root->addChild(*child);
@ -184,18 +184,18 @@ namespace blobstore {
return _nodeStore->createNewLeafNode(leafCreator(leafOffset)); 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."); ASSERT(depth >= minNeededDepth, "Given tree depth doesn't fit given number of leaves to create.");
uint32_t leavesPerChild = _maxLeavesForTreeDepth(depth-1); const uint32_t leavesPerChild = _maxLeavesForTreeDepth(depth-1);
uint32_t beginChild = beginIndex/leavesPerChild; const uint32_t beginChild = beginIndex/leavesPerChild;
uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild); const uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild);
vector<blockstore::BlockId> children; vector<blockstore::BlockId> children;
children.reserve(endChild); children.reserve(endChild);
// TODO Remove redundancy of following two for loops by using min/max for calculating the parameters of the recursive call. // TODO Remove redundancy of following two for loops by using min/max for calculating the parameters of the recursive call.
// Create gap children (i.e. children before the traversal but after the current size) // Create gap children (i.e. children before the traversal but after the current size)
for (uint32_t childIndex = 0; childIndex < beginChild; ++childIndex) { 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, 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.");}, [] (uint32_t /*index*/)->Data {ASSERT(false, "We're only creating gap leaves here, not traversing any.");},
[] (DataInnerNode* /*node*/) {}); [] (DataInnerNode* /*node*/) {});
@ -204,9 +204,9 @@ namespace blobstore {
} }
// Create new children that are traversed // Create new children that are traversed
for(uint32_t childIndex = beginChild; childIndex < endChild; ++childIndex) { for(uint32_t childIndex = beginChild; childIndex < endChild; ++childIndex) {
uint32_t childOffset = childIndex * leavesPerChild; const uint32_t childOffset = childIndex * leavesPerChild;
uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset); const uint32_t localBeginIndex = utils::maxZeroSubtraction(beginIndex, childOffset);
uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset); const uint32_t localEndIndex = std::min(leavesPerChild, endIndex - childOffset);
auto child = _createNewSubtree(localBeginIndex, localEndIndex, leafOffset + childOffset, depth - 1, onCreateLeaf, onBacktrackFromSubtree); auto child = _createNewSubtree(localBeginIndex, localEndIndex, leafOffset + childOffset, depth - 1, onCreateLeaf, onBacktrackFromSubtree);
ASSERT(child->depth() == depth-1, "Created child node has wrong depth"); ASSERT(child->depth() == depth-1, "Created child node has wrong depth");
children.push_back(child->blockId()); children.push_back(child->blockId());
@ -229,7 +229,7 @@ namespace blobstore {
function<Data (uint32_t index)> LeafTraverser::_createMaxSizeLeaf() const { function<Data (uint32_t index)> LeafTraverser::_createMaxSizeLeaf() const {
ASSERT(!_readOnlyTraversal, "Can't create a new leaf in a read-only traversal"); 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 [maxBytesPerLeaf] (uint32_t /*index*/) -> Data {
return Data(maxBytesPerLeaf).FillWithZeroes(); return Data(maxBytesPerLeaf).FillWithZeroes();
}; };

View File

@ -31,12 +31,12 @@ optional<unique_ref<DataTreeRef>> ParallelAccessDataTreeStore::load(const blocks
unique_ref<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() { unique_ref<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() {
auto dataTree = _dataTreeStore->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 ) 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) { void ParallelAccessDataTreeStore::remove(unique_ref<DataTreeRef> tree) {
BlockId blockId = tree->blockId(); const BlockId blockId = tree->blockId();
return _parallelAccessStore.remove(blockId, std::move(tree)); return _parallelAccessStore.remove(blockId, std::move(tree));
} }

View File

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

View File

@ -71,7 +71,7 @@ Cache<Key, Value, MAX_ENTRIES>::~Cache() {
template<class Key, class Value, uint32_t MAX_ENTRIES> template<class Key, class Value, uint32_t MAX_ENTRIES>
boost::optional<Value> Cache<Key, Value, MAX_ENTRIES>::pop(const Key &key) { boost::optional<Value> Cache<Key, Value, MAX_ENTRIES>::pop(const Key &key) {
std::unique_lock<std::mutex> lock(_mutex); 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); auto found = _cachedBlocks.pop(key);
if (!found) { if (!found) {
@ -132,7 +132,7 @@ void Cache<Key, Value, MAX_ENTRIES>::_deleteOldEntriesParallel() {
template<class Key, class Value, uint32_t MAX_ENTRIES> template<class Key, class Value, uint32_t MAX_ENTRIES>
void Cache<Key, Value, MAX_ENTRIES>::_deleteMatchingEntriesAtBeginningParallel(std::function<bool (const CacheEntry<Key, Value> &)> matches) { 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 // 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; std::vector<std::future<void>> waitHandles;
for (unsigned int i = 0; i < numThreads; ++i) { for (unsigned int i = 0; i < numThreads; ++i) {
waitHandles.push_back(std::async(std::launch::async, [this, matches] { 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); static cpputils::unique_ref<CompressedBlock> Decompress(cpputils::unique_ref<Block> baseBlock);
CompressedBlock(cpputils::unique_ref<Block> baseBlock, cpputils::Data decompressedData); CompressedBlock(cpputils::unique_ref<Block> baseBlock, cpputils::Data decompressedData);
~CompressedBlock(); ~CompressedBlock() override;
const void *data() const override; const void *data() const override;
void write(const void *source, uint64_t offset, uint64_t size) 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> template<class Compressor>
CompressedBlock<Compressor>::~CompressedBlock() { CompressedBlock<Compressor>::~CompressedBlock() {
std::unique_lock<std::mutex> lock(_mutex); const std::unique_lock<std::mutex> lock(_mutex);
_compressToBaseBlock(); _compressToBaseBlock();
} }
@ -97,7 +97,7 @@ void CompressedBlock<Compressor>::write(const void *source, uint64_t offset, uin
template<class Compressor> template<class Compressor>
void CompressedBlock<Compressor>::flush() { void CompressedBlock<Compressor>::flush() {
std::unique_lock<std::mutex> lock(_mutex); const std::unique_lock<std::mutex> lock(_mutex);
_compressToBaseBlock(); _compressToBaseBlock();
return _baseBlock->flush(); return _baseBlock->flush();
} }

View File

@ -12,7 +12,7 @@ template<class Compressor>
class CompressingBlockStore final: public BlockStore { class CompressingBlockStore final: public BlockStore {
public: public:
CompressingBlockStore(cpputils::unique_ref<BlockStore> baseBlockStore); CompressingBlockStore(cpputils::unique_ref<BlockStore> baseBlockStore);
~CompressingBlockStore(); ~CompressingBlockStore() override;
BlockId createBlockId() override; BlockId createBlockId() override;
boost::optional<cpputils::unique_ref<Block>> tryCreate(const BlockId &blockId, cpputils::Data data) 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) { Data RunLengthEncoding::_extractData(ostringstream *stream) {
string str = stream->str(); const string str = stream->str();
Data data(str.size()); Data data(str.size());
std::memcpy(data.data(), str.c_str(), str.size()); std::memcpy(data.data(), str.c_str(), str.size());
return data; return data;

View File

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

View File

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

View File

@ -51,8 +51,8 @@ void IntegrityBlockStore2::_checkFormatHeader(const Data &data) const {
} }
bool IntegrityBlockStore2::_checkVersionHeader(const BlockId &blockId, const Data &data) const { bool IntegrityBlockStore2::_checkVersionHeader(const BlockId &blockId, const Data &data) const {
uint32_t clientId = _readClientId(data); const uint32_t clientId = _readClientId(data);
uint64_t version = _readVersion(data); const uint64_t version = _readVersion(data);
if(!_knownBlockVersions.checkAndUpdateVersion(clientId, blockId, version)) { if(!_knownBlockVersions.checkAndUpdateVersion(clientId, blockId, version)) {
integrityViolationDetected("The block version number is too low. Did an attacker try to roll back the block or to re-introduce a deleted block?"); integrityViolationDetected("The block version number is too low. Did an attacker try to roll back the block or to re-introduce a deleted block?");
@ -65,7 +65,7 @@ bool IntegrityBlockStore2::_checkVersionHeader(const BlockId &blockId, const Dat
bool IntegrityBlockStore2::_checkIdHeader(const BlockId &expectedBlockId, const Data &data) const { 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 // 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 // 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) { if (expectedBlockId != actualBlockId) {
integrityViolationDetected("The block id is wrong. Did an attacker try to rename some blocks?"); integrityViolationDetected("The block id is wrong. Did an attacker try to rename some blocks?");
return false; return false;
@ -111,8 +111,8 @@ IntegrityBlockStore2::IntegrityBlockStore2(unique_ref<BlockStore2> baseBlockStor
} }
bool IntegrityBlockStore2::tryCreate(const BlockId &blockId, const Data &data) { bool IntegrityBlockStore2::tryCreate(const BlockId &blockId, const Data &data) {
uint64_t version = _knownBlockVersions.incrementVersion(blockId); const uint64_t version = _knownBlockVersions.incrementVersion(blockId);
Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data); const Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data);
return _baseBlockStore->tryCreate(blockId, dataWithHeader); return _baseBlockStore->tryCreate(blockId, dataWithHeader);
} }
@ -131,11 +131,11 @@ optional<Data> IntegrityBlockStore2::load(const BlockId &blockId) const {
} }
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
if (FORMAT_VERSION_HEADER_OLD == _readFormatHeader(*loaded)) { if (FORMAT_VERSION_HEADER_OLD == _readFormatHeader(*loaded)) {
Data migrated = _migrateBlock(blockId, *loaded); const Data migrated = _migrateBlock(blockId, *loaded);
if (!_checkHeader(blockId, migrated) && !_allowIntegrityViolations) { if (!_checkHeader(blockId, migrated) && !_allowIntegrityViolations) {
return optional<Data>(none); return optional<Data>(none);
} }
Data content = _removeHeader(migrated); const Data content = _removeHeader(migrated);
const_cast<IntegrityBlockStore2*>(this)->store(blockId, content); const_cast<IntegrityBlockStore2*>(this)->store(blockId, content);
return optional<Data>(_removeHeader(migrated)); return optional<Data>(_removeHeader(migrated));
} }
@ -158,8 +158,8 @@ Data IntegrityBlockStore2::_migrateBlock(const BlockId &blockId, const Data &dat
#endif #endif
void IntegrityBlockStore2::store(const BlockId &blockId, const Data &data) { void IntegrityBlockStore2::store(const BlockId &blockId, const Data &data) {
uint64_t version = _knownBlockVersions.incrementVersion(blockId); const uint64_t version = _knownBlockVersions.incrementVersion(blockId);
Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data); const Data dataWithHeader = _prependHeaderToData(blockId, _knownBlockVersions.myClientId(), version, data);
return _baseBlockStore->store(blockId, dataWithHeader); return _baseBlockStore->store(blockId, dataWithHeader);
} }
@ -172,7 +172,7 @@ uint64_t IntegrityBlockStore2::estimateNumFreeBytes() const {
} }
uint64_t IntegrityBlockStore2::blockSizeFromPhysicalBlockSize(uint64_t blockSize) 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) { if (baseBlockSize <= HEADER_LENGTH) {
return 0; return 0;
} }
@ -225,9 +225,9 @@ void IntegrityBlockStore2::migrateBlockFromBlockstoreWithoutVersionNumbers(block
return; return;
} }
uint64_t version = knownBlockVersions->incrementVersion(blockId); const uint64_t version = knownBlockVersions->incrementVersion(blockId);
cpputils::Data data = std::move(*data_); const cpputils::Data data = std::move(*data_);
cpputils::Data dataWithHeader = _prependHeaderToData(blockId, knownBlockVersions->myClientId(), version, data); const cpputils::Data dataWithHeader = _prependHeaderToData(blockId, knownBlockVersions->myClientId(), version, data);
baseBlockStore->store(blockId, dataWithHeader); baseBlockStore->store(blockId, dataWithHeader);
} }
#endif #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) KnownBlockVersions::KnownBlockVersions(const bf::path &stateFilePath, uint32_t myClientId)
:_integrityViolationOnPreviousRun(false), _knownVersions(), _lastUpdateClientId(), _stateFilePath(stateFilePath), _myClientId(myClientId), _mutex(), _valid(true) { :_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"); ASSERT(_myClientId != CLIENT_ID_FOR_DELETED_BLOCK, "This is not a valid client id");
_loadStateFile(); _loadStateFile();
} }
KnownBlockVersions::KnownBlockVersions(KnownBlockVersions &&rhs) // NOLINT (intentionally not noexcept) KnownBlockVersions::KnownBlockVersions(KnownBlockVersions &&rhs) // NOLINT (intentionally not noexcept)
: _integrityViolationOnPreviousRun(false), _knownVersions(), _lastUpdateClientId(), _stateFilePath(), _myClientId(0), _mutex(), _valid(true) { : _integrityViolationOnPreviousRun(false), _knownVersions(), _lastUpdateClientId(), _stateFilePath(), _myClientId(0), _mutex(), _valid(true) {
unique_lock<mutex> rhsLock(rhs._mutex); const unique_lock<mutex> rhsLock(rhs._mutex);
unique_lock<mutex> lock(_mutex); const unique_lock<mutex> lock(_mutex);
// NOLINTBEGIN(cppcoreguidelines-prefer-member-initializer) -- we need to initialize those within the mutexes
_integrityViolationOnPreviousRun = rhs._integrityViolationOnPreviousRun; _integrityViolationOnPreviousRun = rhs._integrityViolationOnPreviousRun;
_knownVersions = std::move(rhs._knownVersions); _knownVersions = std::move(rhs._knownVersions);
_lastUpdateClientId = std::move(rhs._lastUpdateClientId); _lastUpdateClientId = std::move(rhs._lastUpdateClientId);
_stateFilePath = std::move(rhs._stateFilePath); _stateFilePath = std::move(rhs._stateFilePath);
_myClientId = rhs._myClientId; _myClientId = rhs._myClientId;
rhs._valid = false; rhs._valid = false;
// NOLINTEND(cppcoreguidelines-prefer-member-initializer)
} }
KnownBlockVersions::~KnownBlockVersions() { KnownBlockVersions::~KnownBlockVersions() {
unique_lock<mutex> lock(_mutex); const unique_lock<mutex> lock(_mutex);
if (_valid) { if (_valid) {
_saveStateFile(); _saveStateFile();
} }
@ -56,7 +58,7 @@ bool KnownBlockVersions::integrityViolationOnPreviousRun() const {
} }
bool KnownBlockVersions::checkAndUpdateVersion(uint32_t clientId, const BlockId &blockId, uint64_t version) { 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(clientId != CLIENT_ID_FOR_DELETED_BLOCK, "This is not a valid client id");
ASSERT(version > 0, "Version has to be >0"); // Otherwise we wouldn't handle notexisting entries correctly. ASSERT(version > 0, "Version has to be >0"); // Otherwise we wouldn't handle notexisting entries correctly.
@ -81,9 +83,9 @@ bool KnownBlockVersions::checkAndUpdateVersion(uint32_t clientId, const BlockId
} }
uint64_t KnownBlockVersions::incrementVersion(const BlockId &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 &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()) { if (newVersion == std::numeric_limits<uint64_t>::max()) {
// It's *very* unlikely we ever run out of version numbers in 64bit...but just to be sure... // It's *very* unlikely we ever run out of version numbers in 64bit...but just to be sure...
throw std::runtime_error("Version overflow"); throw std::runtime_error("Version overflow");
@ -138,7 +140,7 @@ void KnownBlockVersions::_saveStateFile() const {
} }
std::unordered_map<ClientIdAndBlockId, uint64_t> KnownBlockVersions::_deserializeKnownVersions(Deserializer *deserializer) { 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; 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. 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) { 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) { 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); serializer->writeUint64(numEntries);
for (const auto &entry : knownVersions) { for (const auto &entry : knownVersions) {
@ -159,9 +161,9 @@ void KnownBlockVersions::_serializeKnownVersions(Serializer *serializer, const s
} }
pair<ClientIdAndBlockId, uint64_t> KnownBlockVersions::_deserializeKnownVersionsEntry(Deserializer *deserializer) { pair<ClientIdAndBlockId, uint64_t> KnownBlockVersions::_deserializeKnownVersionsEntry(Deserializer *deserializer) {
uint32_t clientId = deserializer->readUint32(); const uint32_t clientId = deserializer->readUint32();
BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>()); const BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>());
uint64_t version = deserializer->readUint64(); const uint64_t version = deserializer->readUint64();
return {{clientId, blockId}, version}; return {{clientId, blockId}, version};
}; };
@ -173,7 +175,7 @@ void KnownBlockVersions::_serializeKnownVersionsEntry(Serializer *serializer, co
} }
std::unordered_map<BlockId, uint32_t> KnownBlockVersions::_deserializeLastUpdateClientIds(Deserializer *deserializer) { 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; 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. 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) { 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) { 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); serializer->writeUint64(numEntries);
for (const auto &entry : lastUpdateClientId) { for (const auto &entry : lastUpdateClientId) {
@ -193,8 +195,8 @@ void KnownBlockVersions::_serializeLastUpdateClientIds(Serializer *serializer, c
} }
pair<BlockId, uint32_t> KnownBlockVersions::_deserializeLastUpdateClientIdEntry(Deserializer *deserializer) { pair<BlockId, uint32_t> KnownBlockVersions::_deserializeLastUpdateClientIdEntry(Deserializer *deserializer) {
BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>()); const BlockId blockId(deserializer->readFixedSizeData<BlockId::BINARY_LENGTH>());
uint32_t clientId = deserializer->readUint32(); const uint32_t clientId = deserializer->readUint32();
return {blockId, clientId}; return {blockId, clientId};
}; };
@ -209,7 +211,7 @@ uint32_t KnownBlockVersions::myClientId() const {
} }
uint64_t KnownBlockVersions::getBlockVersion(uint32_t clientId, const BlockId &blockId) 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}); return _knownVersions.at({clientId, blockId});
} }

View File

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

View File

@ -28,7 +28,7 @@ public:
static boost::optional<cpputils::unique_ref<LowToHighLevelBlock>> Load(BlockStore2 *baseBlockStore, const BlockId &blockId); static boost::optional<cpputils::unique_ref<LowToHighLevelBlock>> Load(BlockStore2 *baseBlockStore, const BlockId &blockId);
LowToHighLevelBlock(const BlockId &blockId, cpputils::Data data, BlockStore2 *baseBlockStore); LowToHighLevelBlock(const BlockId &blockId, cpputils::Data data, BlockStore2 *baseBlockStore);
~LowToHighLevelBlock(); ~LowToHighLevelBlock() override;
const void *data() const override; const void *data() const override;
void write(const void *source, uint64_t offset, uint64_t count) 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) { void LowToHighLevelBlockStore::remove(const BlockId &blockId) {
bool success = _baseBlockStore->remove(blockId); const bool success = _baseBlockStore->remove(blockId);
if (!success) { if (!success) {
throw std::runtime_error("Couldn't delete block with id " + blockId.ToString()); throw std::runtime_error("Couldn't delete block with id " + blockId.ToString());
} }

View File

@ -113,27 +113,27 @@ namespace blockstore {
private: private:
void _increaseNumCreatedBlocks() { void _increaseNumCreatedBlocks() {
std::unique_lock<std::mutex> lock(_mutex); const std::unique_lock<std::mutex> lock(_mutex);
_createdBlocks += 1; _createdBlocks += 1;
} }
void _increaseNumLoadedBlocks(const BlockId &blockId) { void _increaseNumLoadedBlocks(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); const std::unique_lock<std::mutex> lock(_mutex);
_loadedBlocks.push_back(blockId); _loadedBlocks.push_back(blockId);
} }
void _increaseNumRemovedBlocks(const BlockId &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); _removedBlocks.push_back(blockId);
} }
void _increaseNumResizedBlocks(const BlockId &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); _resizedBlocks.push_back(blockId);
} }
void _increaseNumWrittenBlocks(const BlockId &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); _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 { 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); 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? if (!boost::filesystem::is_regular_file(filepath)) { // TODO Is this branch necessary?
return false; return false;
} }
bool retval = boost::filesystem::remove(filepath); const bool retval = boost::filesystem::remove(filepath);
if (!retval) { if (!retval) {
cpputils::logging::LOG(cpputils::logging::ERR, "Couldn't find block {} to remove", blockId.ToString()); cpputils::logging::LOG(cpputils::logging::ERR, "Couldn't find block {} to remove", blockId.ToString());
return false; return false;
@ -121,14 +121,14 @@ void OnDiskBlockStore2::forEachBlock(std::function<void (const BlockId &)> callb
continue; 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)) { if (blockIdPrefix.size() != PREFIX_LENGTH || std::string::npos != blockIdPrefix.find_first_not_of(ALLOWED_BLOCKID_CHARACTERS)) {
// directory has wrong length or an invalid character // directory has wrong length or an invalid character
continue; continue;
} }
for (auto block = boost::filesystem::directory_iterator(prefixDir->path()); block != boost::filesystem::directory_iterator(); ++block) { for (auto block = boost::filesystem::directory_iterator(prefixDir->path()); block != boost::filesystem::directory_iterator(); ++block) {
std::string 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)) { if (blockIdPostfix.size() != POSTFIX_LENGTH || std::string::npos != blockIdPostfix.find_first_not_of(ALLOWED_BLOCKID_CHARACTERS)) {
// filename has wrong length or an invalid character // filename has wrong length or an invalid character
continue; continue;

View File

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

View File

@ -14,7 +14,7 @@ class FakeBlockStore;
class FakeBlock final: public Block { class FakeBlock final: public Block {
public: public:
FakeBlock(FakeBlockStore *store, const BlockId &blockId, std::shared_ptr<cpputils::Data> data, bool dirty); FakeBlock(FakeBlockStore *store, const BlockId &blockId, std::shared_ptr<cpputils::Data> data, bool dirty);
~FakeBlock(); ~FakeBlock() override;
const void *data() const override; const void *data() const override;
void write(const void *source, uint64_t offset, uint64_t size) 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) { 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)); auto insert_result = _blocks.emplace(blockId, std::move(data));
if (!insert_result.second) { 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) { 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()); auto insert_result = _blocks.emplace(blockId, data.copy());
if (!insert_result.second) { 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) { 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); return _load(blockId);
} }
@ -64,8 +64,8 @@ optional<unique_ref<Block>> FakeBlockStore::_load(const BlockId &blockId) {
} }
void FakeBlockStore::remove(const BlockId &blockId) { void FakeBlockStore::remove(const BlockId &blockId) {
std::unique_lock<std::mutex> lock(_mutex); const std::unique_lock<std::mutex> lock(_mutex);
int numRemoved = _blocks.erase(blockId); const size_t numRemoved = _blocks.erase(blockId);
ASSERT(numRemoved == 1, "Block not found"); 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) { 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); auto found = _blocks.find(blockId);
if (found == _blocks.end()) { if (found == _blocks.end()) {
auto insertResult = _blocks.emplace(blockId, data.copy()); 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 { uint64_t FakeBlockStore::numBlocks() const {
std::unique_lock<std::mutex> lock(_mutex); const std::unique_lock<std::mutex> lock(_mutex);
return _blocks.size(); return _blocks.size();
} }

View File

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

View File

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

View File

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

View File

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

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) // 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) // and destroyed on program exit (which will unregister the signal handler)
static SignalHandlerRAII<&sigsegv_handler> segv(SIGSEGV); static const SignalHandlerRAII<&sigsegv_handler> segv(SIGSEGV);
static SignalHandlerRAII<&sigabrt_handler> abrt(SIGABRT); static const SignalHandlerRAII<&sigabrt_handler> abrt(SIGABRT);
static SignalHandlerRAII<&sigill_handler> ill(SIGILL); static const SignalHandlerRAII<&sigill_handler> ill(SIGILL);
} }
} }

View File

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

View File

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

View File

@ -2,7 +2,6 @@
using std::istream; using std::istream;
using std::ostream; using std::ostream;
using cpputils::Data;
namespace cpputils { namespace cpputils {
Data SCryptParameters::serialize() const { Data SCryptParameters::serialize() const {
@ -20,9 +19,9 @@ namespace cpputils {
SCryptParameters SCryptParameters::deserialize(const cpputils::Data &data) { SCryptParameters SCryptParameters::deserialize(const cpputils::Data &data) {
Deserializer deserializer(&data); Deserializer deserializer(&data);
uint64_t n = deserializer.readUint64(); const uint64_t n = deserializer.readUint64();
uint32_t r = deserializer.readUint32(); const uint32_t r = deserializer.readUint32();
uint32_t p = deserializer.readUint32(); const uint32_t p = deserializer.readUint32();
Data salt = deserializer.readTailData(); Data salt = deserializer.readTailData();
deserializer.finished(); deserializer.finished();
return SCryptParameters(std::move(salt), n, r, p); return SCryptParameters(std::move(salt), n, r, p);
@ -30,9 +29,9 @@ namespace cpputils {
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
SCryptParameters SCryptParameters::deserializeOldFormat(Deserializer *source) { SCryptParameters SCryptParameters::deserializeOldFormat(Deserializer *source) {
uint64_t n = source->readUint64(); const uint64_t n = source->readUint64();
uint32_t r = source->readUint32(); const uint32_t r = source->readUint32();
uint32_t p = source->readUint32(); const uint32_t p = source->readUint32();
Data salt = source->readData(); Data salt = source->readData();
return SCryptParameters(std::move(salt), n, r, p); 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) { EncryptionKey _derive(size_t keySize, const std::string& password, const SCryptParameters& kdfParameters) {
auto result = EncryptionKey::Null(keySize); 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(), static_cast<uint8_t*>(result.data()), result.binaryLength(),
reinterpret_cast<const uint8_t*>(password.c_str()), password.size(), reinterpret_cast<const uint8_t*>(password.c_str()), password.size(),
static_cast<const uint8_t*>(kdfParameters.salt().data()), kdfParameters.salt().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) { 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); auto key = _derive(keySize, password, parameters);
return key; return key;
} }
SCrypt::KeyResult SCrypt::deriveNewKey(size_t keySize, const std::string& password) { 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); auto key = _derive(keySize, password, kdfParameters);
return SCrypt::KeyResult { return SCrypt::KeyResult {
key, key,

View File

@ -49,7 +49,7 @@ Data AEADCipher<CryptoPPCipher, KEYSIZE_, IV_SIZE_, TAG_SIZE_>::encrypt(const Cr
Data ciphertext(ciphertextSize(plaintextSize)); Data ciphertext(ciphertextSize(plaintextSize));
iv.ToBinary(ciphertext.data()); iv.ToBinary(ciphertext.data());
CryptoPP::ArraySource(plaintext, plaintextSize, true, const CryptoPP::ArraySource _1(plaintext, plaintextSize, true,
new CryptoPP::AuthenticatedEncryptionFilter(encryption, new CryptoPP::AuthenticatedEncryptionFilter(encryption,
new CryptoPP::ArraySink(static_cast<CryptoPP::byte*>(ciphertext.data()) + IV_SIZE, ciphertext.size() - IV_SIZE), new CryptoPP::ArraySink(static_cast<CryptoPP::byte*>(ciphertext.data()) + IV_SIZE, ciphertext.size() - IV_SIZE),
false, TAG_SIZE false, TAG_SIZE
@ -73,7 +73,7 @@ boost::optional<Data> AEADCipher<CryptoPPCipher, KEYSIZE_, IV_SIZE_, TAG_SIZE_>:
Data plaintext(plaintextSize(ciphertextSize)); Data plaintext(plaintextSize(ciphertextSize));
try { 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::AuthenticatedDecryptionFilter(decryption,
new CryptoPP::ArraySink(static_cast<CryptoPP::byte*>(plaintext.data()), plaintext.size()), new CryptoPP::ArraySink(static_cast<CryptoPP::byte*>(plaintext.data()), plaintext.size()),
CryptoPP::AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_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::plaintextSize(UINT32_C(5)));
same_type(UINT32_C(0), X::KEYSIZE); same_type(UINT32_C(0), X::KEYSIZE);
same_type(UINT32_C(0), X::STRING_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(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)); 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: private:

View File

@ -59,14 +59,14 @@ namespace cpputils {
Data result(ciphertextSize(plaintextSize)); Data result(ciphertextSize(plaintextSize));
//Add a random IV //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); serialize<uint64_t>(result.data(), iv);
//Use xor chiffre on plaintext //Use xor chiffre on plaintext
_xor(static_cast<CryptoPP::byte*>(result.dataOffset(sizeof(uint64_t))), plaintext, plaintextSize, encKey.value ^ iv); _xor(static_cast<CryptoPP::byte*>(result.dataOffset(sizeof(uint64_t))), plaintext, plaintextSize, encKey.value ^ iv);
//Add checksum information //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); serialize<uint64_t>(result.dataOffset(plaintextSize + sizeof(uint64_t)), checksum);
return result; return result;
@ -80,14 +80,14 @@ namespace cpputils {
} }
//Check checksum //Check checksum
uint64_t expectedParity = _checksum(ciphertext, encKey, plaintextSize(ciphertextSize) + sizeof(uint64_t)); const 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 actualParity = deserialize<uint64_t>(ciphertext + plaintextSize(ciphertextSize) + sizeof(uint64_t));
if (expectedParity != actualParity) { if (expectedParity != actualParity) {
return boost::none; return boost::none;
} }
//Decrypt xor chiffre from ciphertext //Decrypt xor chiffre from ciphertext
uint64_t iv = deserialize<uint64_t>(ciphertext); const uint64_t iv = deserialize<uint64_t>(ciphertext);
Data result(plaintextSize(ciphertextSize)); Data result(plaintextSize(ciphertextSize));
_xor(static_cast<CryptoPP::byte *>(result.data()), ciphertext + sizeof(uint64_t), plaintextSize(ciphertextSize), encKey.value ^ iv); _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 Data::LoadFromStream(istream &stream, size_t size) {
Data result(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; 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"); ASSERT(data.size() % 2 == 0, "hex encoded data cannot have odd number of characters");
Data result(data.size() / 2, std::move(allocator)); Data result(data.size() / 2, std::move(allocator));
{ {
CryptoPP::StringSource _1(data, true, const CryptoPP::StringSource _1(data, true,
new CryptoPP::HexDecoder( new CryptoPP::HexDecoder(
new CryptoPP::ArraySink(static_cast<CryptoPP::byte*>(result._data), result.size()) 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 Data::ToString() const {
std::string result; 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::HexEncoder(
new CryptoPP::StringSink(result) 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 { 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) { inline Data Data::LoadFromStream(std::istream &stream) {

View File

@ -11,7 +11,7 @@ namespace cpputils {
val += 1442695040888963407; val += 1442695040888963407;
serialize<unsigned long long int>(result.dataOffset(i*sizeof(unsigned long long int)), val); 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 *= 6364136223846793005L;
val += 1442695040888963407; val += 1442695040888963407;
unsigned char *remainingBytes = reinterpret_cast<unsigned char*>(&val); unsigned char *remainingBytes = reinterpret_cast<unsigned char*>(&val);

View File

@ -44,7 +44,7 @@ namespace cpputils {
} }
inline bool Deserializer::readBool() { inline bool Deserializer::readBool() {
uint8_t read = readUint8(); const uint8_t read = readUint8();
if (read == 1) { if (read == 1) {
return true; return true;
} else if (read == 0) { } else if (read == 0) {
@ -98,7 +98,7 @@ namespace cpputils {
} }
inline Data Deserializer::readData() { inline Data Deserializer::readData() {
uint64_t size = readUint64(); const uint64_t size = readUint64();
if (_pos + size > _source->size()) { if (_pos + size > _source->size()) {
throw std::runtime_error("Deserialization failed - size overflow"); throw std::runtime_error("Deserialization failed - size overflow");
} }
@ -106,7 +106,7 @@ namespace cpputils {
} }
inline Data Deserializer::readTailData() { inline Data Deserializer::readTailData() {
uint64_t size = _source->size() - _pos; const uint64_t size = _source->size() - _pos;
return _readData(size); return _readData(size);
} }
@ -134,7 +134,7 @@ namespace cpputils {
if (nullbytepos == nullptr) { if (nullbytepos == nullptr) {
throw std::runtime_error("Deserialization failed - missing nullbyte for string termination"); 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); std::string result(static_cast<const char*>(_source->dataOffset(_pos)), size);
_pos += size + 1; _pos += size + 1;
return result; 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"); ASSERT(data.size() == STRING_LENGTH, "Wrong string size for parsing FixedSizeData");
FixedSizeData<SIZE> result; FixedSizeData<SIZE> result;
{ {
CryptoPP::StringSource _1(data, true, const CryptoPP::StringSource _1(data, true,
new CryptoPP::HexDecoder( new CryptoPP::HexDecoder(
new CryptoPP::ArraySink(result._data.data(), BINARY_LENGTH) 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> template<size_t SIZE>
std::string FixedSizeData<SIZE>::ToString() const { std::string FixedSizeData<SIZE>::ToString() const {
std::string result; std::string result;
CryptoPP::ArraySource(_data.data(), BINARY_LENGTH, true, const CryptoPP::ArraySource _1(_data.data(), BINARY_LENGTH, true,
new CryptoPP::HexEncoder( new CryptoPP::HexEncoder(
new CryptoPP::StringSink(result) new CryptoPP::StringSink(result)
) )

View File

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

View File

@ -42,7 +42,7 @@ function<optional<unsigned int>(const string &input)> IOStreamConsole::_parseUIn
if (parsed == none) { if (parsed == none) {
return optional<unsigned int>(none); return optional<unsigned int>(none);
} }
unsigned int value = static_cast<unsigned int>(*parsed); const unsigned int value = static_cast<unsigned int>(*parsed);
if (value < min || value > max) { if (value < min || value > max) {
return optional<unsigned int>(none); return optional<unsigned int>(none);
} }
@ -70,7 +70,7 @@ unsigned int IOStreamConsole::ask(const string &question, const vector<string> &
for (size_t i = 0; i < options.size(); ++i) { for (size_t i = 0; i < options.size(); ++i) {
_output << " [" << (i+1) << "] " << options[i] << "\n"; _output << " [" << (i+1) << "] " << options[i] << "\n";
} }
int choice = _askForChoice("Your choice [1-" + std::to_string(options.size()) + "]: ", _parseUIntWithMinMax(1, options.size())); const int choice = _askForChoice("Your choice [1-" + std::to_string(options.size()) + "]: ", _parseUIntWithMinMax(1, options.size()));
return choice-1; return choice-1;
} }
@ -98,7 +98,7 @@ void IOStreamConsole::print(const string &output) {
} }
string IOStreamConsole::askPassword(const string &question) { string IOStreamConsole::askPassword(const string &question) {
DontEchoStdinToStdoutRAII _stdin_input_is_hidden_as_long_as_this_is_in_scope; const DontEchoStdinToStdoutRAII _stdin_input_is_hidden_as_long_as_this_is_in_scope;
_output << question << std::flush; _output << question << std::flush;
string result; string result;

View File

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

View File

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

View File

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

View File

@ -19,7 +19,7 @@ namespace cpputils {
uint32_t CurlHttpClient::CurlInitializerRAII::_refcount = 0; uint32_t CurlHttpClient::CurlInitializerRAII::_refcount = 0;
CurlHttpClient::CurlInitializerRAII::CurlInitializerRAII() { CurlHttpClient::CurlInitializerRAII::CurlInitializerRAII() {
unique_lock<mutex> lock(_mutex); const unique_lock<mutex> lock(_mutex);
if (0 == _refcount) { if (0 == _refcount) {
curl_global_init(CURL_GLOBAL_ALL); curl_global_init(CURL_GLOBAL_ALL);
} }
@ -27,7 +27,7 @@ namespace cpputils {
} }
CurlHttpClient::CurlInitializerRAII::~CurlInitializerRAII() { CurlHttpClient::CurlInitializerRAII::~CurlInitializerRAII() {
unique_lock<mutex> lock(_mutex); const unique_lock<mutex> lock(_mutex);
_refcount -= 1; _refcount -= 1;
if (0 == _refcount) { if (0 == _refcount) {
curl_global_cleanup(); curl_global_cleanup();
@ -39,8 +39,8 @@ namespace cpputils {
return size * nmemb; return size * nmemb;
} }
CurlHttpClient::CurlHttpClient(): curlInitializer(), curl() { CurlHttpClient::CurlHttpClient(): curlInitializer(), curl(curl_easy_init()) {
curl = curl_easy_init();
} }
CurlHttpClient::~CurlHttpClient() { CurlHttpClient::~CurlHttpClient() {
@ -60,7 +60,7 @@ namespace cpputils {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, *timeoutMsec); curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, *timeoutMsec);
} }
// Perform the request, res will get the return code // Perform the request, res will get the return code
CURLcode res = curl_easy_perform(curl); const CURLcode res = curl_easy_perform(curl);
// Check for errors // Check for errors
if (res != CURLE_OK) { if (res != CURLE_OK) {
throw std::runtime_error("Curl Error " + std::to_string(res) + ": " + curl_easy_strerror(res)); throw std::runtime_error("Curl Error " + std::to_string(res) + ": " + curl_easy_strerror(res));

View File

@ -15,7 +15,7 @@ namespace cpputils {
public: public:
CurlHttpClient(); CurlHttpClient();
~CurlHttpClient(); ~CurlHttpClient() override;
std::string get(const std::string &url, boost::optional<long> timeoutMsec = boost::none) override; std::string get(const std::string &url, boost::optional<long> timeoutMsec = boost::none) override;

View File

@ -2,7 +2,6 @@
using std::string; using std::string;
using boost::optional; using boost::optional;
using boost::none;
namespace cpputils { namespace cpputils {
FakeHttpClient::FakeHttpClient(): _sites() { 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> template<class T, class D>
inline void swap(cpputils::unique_ref<T, D>& lhs, cpputils::unique_ref<T, D>& rhs) noexcept { inline void swap(cpputils::unique_ref<T, D>& lhs, cpputils::unique_ref<T, D>& rhs) noexcept {
lhs.swap(rhs); lhs.swap(rhs);
@ -191,5 +192,6 @@ namespace std { // NOLINT (intentional change of namespace std)
} }
}; };
} }
// NOLINTEND(cert-dcl58-cpp)
#endif #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) // - 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()); _impls.reserve(signals.size());
for (int signal : signals) { for (const int signal : signals) {
_impls.emplace_back(make_unique<details::SignalCatcherImpl>(signal, &_signal_occurred)); _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)); 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_handler = handler; // NOLINT(cppcoreguidelines-pro-type-union-access)
new_signal_handler.sa_flags = SA_RESTART; 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) { if (0 != error) {
throw std::runtime_error("Error calling sigfillset. Errno: " + std::to_string(errno)); throw std::runtime_error("Error calling sigfillset. Errno: " + std::to_string(errno));
} }
@ -47,7 +47,7 @@ public:
private: private:
static void _sigaction(int signal, struct sigaction *new_handler, struct sigaction *old_handler) { 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) { if (0 != error) {
throw std::runtime_error("Error calling sigaction. Errno: " + std::to_string(errno)); throw std::runtime_error("Error calling sigaction. Errno: " + std::to_string(errno));
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,9 +17,9 @@ namespace cpputils {
bool RandomGeneratorThread::_loopIteration() { bool RandomGeneratorThread::_loopIteration() {
_buffer->waitUntilSizeIsLessThan(_minSize); _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."); 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); _buffer->add(randomData);
return true; // Run another iteration (don't terminate thread) return true; // Run another iteration (don't terminate thread)
} }

View File

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

View File

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

View File

@ -10,14 +10,14 @@
namespace cpputils { namespace cpputils {
void setenv(const char* key, const char* value) { void setenv(const char* key, const char* value) {
int retval = ::setenv(key, value, 1); const int retval = ::setenv(key, value, 1);
if (0 != retval) { if (0 != retval) {
throw std::runtime_error("Error setting environment variable. Errno: " + std::to_string(errno)); throw std::runtime_error("Error setting environment variable. Errno: " + std::to_string(errno));
} }
} }
void unsetenv(const char* key) { void unsetenv(const char* key) {
int retval = ::unsetenv(key); const int retval = ::unsetenv(key);
if (0 != retval) { if (0 != retval) {
throw std::runtime_error("Error unsetting environment variable. Errno: " + std::to_string(errno)); 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) { void setenv(const char* key, const char* value) {
std::ostringstream command; std::ostringstream command;
command << key << "=" << value; command << key << "=" << value;
int retval = _putenv(command.str().c_str()); const int retval = _putenv(command.str().c_str());
if (0 != retval) { if (0 != retval) {
throw std::runtime_error("Error setting environment variable. Errno: " + std::to_string(errno)); 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{}; std::array<struct timeval, 2> casted_times{};
TIMESPEC_TO_TIMEVAL(&casted_times[0], &lastAccessTime); TIMESPEC_TO_TIMEVAL(&casted_times[0], &lastAccessTime);
TIMESPEC_TO_TIMEVAL(&casted_times[1], &lastModificationTime); 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) { if (0 == retval) {
return 0; return 0;
} else { } 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) { int get_filetime(const char *filepath, timespec* lastAccessTime, timespec* lastModificationTime) {
struct ::stat attrib{}; struct ::stat attrib{};
int retval = ::stat(filepath, &attrib); const int retval = ::stat(filepath, &attrib);
if (retval != 0) { if (retval != 0) {
return errno; return errno;
} }

View File

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

View File

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

View File

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

View File

@ -38,7 +38,7 @@ public:
// wait until any potentially running writers are finished // 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 // wait until any potentially running readers are finished
@ -49,7 +49,7 @@ public:
template <typename F> template <typename F>
auto read(F&& readFunc) const { 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()) { if(_inDestruction.load()) {
throw std::logic_error("Issued LeftRight::read() after the destructor started running"); 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. // depending on if the first or the second call to writeFunc threw.
template <typename F> template <typename F>
auto write(F&& writeFunc) { auto write(F&& writeFunc) {
std::unique_lock<std::mutex> lock(_writeMutex); const std::unique_lock<std::mutex> lock(_writeMutex);
if(_inDestruction.load()) { if(_inDestruction.load()) {
throw std::logic_error("Issued LeftRight::read() after the destructor started running"); 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) { 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); auto thread = _startThread(loopIteration, threadName);
_runningThreads.push_back(RunningThread{std::move(threadName), std::move(loopIteration), std::move(thread)}); _runningThreads.push_back(RunningThread{std::move(threadName), std::move(loopIteration), std::move(thread)});
return std::prev(_runningThreads.end()); return std::prev(_runningThreads.end());

View File

@ -26,9 +26,9 @@ void set_thread_name(const char* name) {
name_.resize(MAX_NAME_LEN - 1); name_.resize(MAX_NAME_LEN - 1);
} }
#if defined(__APPLE__) #if defined(__APPLE__)
int result = pthread_setname_np(name_.c_str()); const int result = pthread_setname_np(name_.c_str());
#else #else
int result = pthread_setname_np(pthread_self(), name_.c_str()); const int result = pthread_setname_np(pthread_self(), name_.c_str());
#endif #endif
if (0 != result) { if (0 != result) {
throw std::runtime_error("Error setting thread name with pthread_setname_np. Code: " + std::to_string(result)); throw std::runtime_error("Error setting thread name with pthread_setname_np. Code: " + std::to_string(result));
@ -73,9 +73,9 @@ int pthread_getname_np_gcompat(pthread_t thread, char *name, size_t len) {
std::string get_thread_name(pthread_t thread) { std::string get_thread_name(pthread_t thread) {
std::array<char, MAX_NAME_LEN> name{}; std::array<char, MAX_NAME_LEN> name{};
#if defined(__GLIBC__) || defined(__APPLE__) #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 #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 #endif
if (0 != result) { if (0 != result) {
throw std::runtime_error("Error getting thread name with pthread_getname_np. Code: " + std::to_string(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() { 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(); _start = boost::chrono::steady_clock::now();
} }
@ -42,12 +42,12 @@ namespace cryfs_cli {
} }
inline boost::chrono::time_point<boost::chrono::steady_clock> CallAfterTimeout::_targetTime() { 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; return _start + _timeout;
} }
inline bool CallAfterTimeout::_callCallbackIfTimeout() { 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) { if (boost::chrono::steady_clock::now() >= _start + _timeout) {
_callback(); _callback();
return false; // Stop thread return false; // Stop thread

View File

@ -72,8 +72,8 @@ using gitversion::VersionCompare;
namespace cryfs_cli { namespace cryfs_cli {
Cli::Cli(RandomGenerator &keyGenerator, const SCryptSettings &scryptSettings, shared_ptr<Console> console): Cli::Cli(RandomGenerator &keyGenerator, const SCryptSettings &scryptSettings, shared_ptr<Console> console):
_keyGenerator(keyGenerator), _scryptSettings(scryptSettings), _console(), _noninteractive(false), _idleUnmounter(none), _device(none) { _keyGenerator(keyGenerator), _scryptSettings(scryptSettings), _console(), _noninteractive(Environment::isNoninteractive()), _idleUnmounter(none), _device(none) {
_noninteractive = Environment::isNoninteractive();
if (_noninteractive) { if (_noninteractive) {
_console = make_shared<NoninteractiveConsole>(console); _console = make_shared<NoninteractiveConsole>(console);
} else { } else {
@ -108,7 +108,7 @@ namespace cryfs_cli {
} }
void Cli::_checkForUpdates(unique_ref<HttpClient> httpClient) { void Cli::_checkForUpdates(unique_ref<HttpClient> httpClient) {
VersionChecker versionChecker(httpClient.get()); const VersionChecker versionChecker(httpClient.get());
optional<string> newestVersion = versionChecker.newestVersion(); optional<string> newestVersion = versionChecker.newestVersion();
if (newestVersion == none) { if (newestVersion == none) {
cout << "Could not check for updates." << endl; cout << "Could not check for updates." << endl;
@ -161,7 +161,7 @@ namespace cryfs_cli {
} }
bool Cli::_confirmPassword(cpputils::Console* console, const string &password) { bool Cli::_confirmPassword(cpputils::Console* console, const string &password) {
string confirmPassword = console->askPassword("Confirm Password: "); const string confirmPassword = console->askPassword("Confirm Password: ");
if (password != confirmPassword) { if (password != confirmPassword) {
std::cout << "Passwords don't match" << std::endl; std::cout << "Passwords don't match" << std::endl;
return false; return false;
@ -258,7 +258,7 @@ namespace cryfs_cli {
void Cli::_runFilesystem(const ProgramOptions &options, std::function<void()> onMounted) { void Cli::_runFilesystem(const ProgramOptions &options, std::function<void()> onMounted) {
try { try {
LocalStateDir localStateDir(Environment::localStateDir()); const LocalStateDir localStateDir(Environment::localStateDir());
auto blockStore = make_unique_ref<OnDiskBlockStore2>(options.baseDir()); auto blockStore = make_unique_ref<OnDiskBlockStore2>(options.baseDir());
auto config = _loadOrCreateConfig(options, localStateDir); auto config = _loadOrCreateConfig(options, localStateDir);
printConfig(config.oldConfig, *config.configFile->config()); printConfig(config.oldConfig, *config.configFile->config());
@ -340,7 +340,7 @@ namespace cryfs_cli {
if (minutes == none) { if (minutes == none) {
return none; return none;
} }
uint64_t millis = std::llround(60000 * (*minutes)); const uint64_t millis = std::llround(60000 * (*minutes));
return make_unique_ref<CallAfterTimeout>(milliseconds(millis), callback, "idlecallback"); return make_unique_ref<CallAfterTimeout>(milliseconds(millis), callback, "idlecallback");
} }
@ -407,7 +407,7 @@ namespace cryfs_cli {
ASSERT(bf::equivalent(dir, tempfile->path().parent_path()), "This function should be called with a file inside the directory"); ASSERT(bf::equivalent(dir, tempfile->path().parent_path()), "This function should be called with a file inside the directory");
try { try {
bool found = false; bool found = false;
bf::directory_iterator end; const bf::directory_iterator end;
for (auto iter = bf::directory_iterator(dir); iter != end; ++iter) { for (auto iter = bf::directory_iterator(dir); iter != end; ++iter) {
if (bf::equivalent(*iter, tempfile->path())) { if (bf::equivalent(*iter, tempfile->path())) {
found = true; found = true;
@ -429,7 +429,7 @@ namespace cryfs_cli {
} }
bool Cli::_pathContains(const bf::path &parent, const bf::path &child) { bool Cli::_pathContains(const bf::path &parent, const bf::path &child) {
bf::path absParent = bf::canonical(parent); const bf::path absParent = bf::canonical(parent);
bf::path current = bf::canonical(child); bf::path current = bf::canonical(child);
if (absParent.empty() && current.empty()) { if (absParent.empty() && current.empty()) {
return true; return true;
@ -449,7 +449,7 @@ namespace cryfs_cli {
try { try {
_showVersion(std::move(httpClient)); _showVersion(std::move(httpClient));
ProgramOptions options = program_options::Parser(argc, argv).parse(CryCiphers::supportedCipherNames()); const ProgramOptions options = program_options::Parser(argc, argv).parse(CryCiphers::supportedCipherNames());
_sanityChecks(options); _sanityChecks(options);
_runFilesystem(options, std::move(onMounted)); _runFilesystem(options, std::move(onMounted));
} catch (const CryfsException &e) { } catch (const CryfsException &e) {

View File

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

View File

@ -41,7 +41,7 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
LOG(WARN, "Passing fuse mount options after a double dash '--' is deprecated. Please pass them directly (e.g. 'cryfs basedir mountdir -o allow_other'"); LOG(WARN, "Passing fuse mount options after a double dash '--' is deprecated. Please pass them directly (e.g. 'cryfs basedir mountdir -o allow_other'");
} }
po::variables_map vm = _parseOptionsOrShowHelp(cryfsOptions, supportedCiphers); const po::variables_map vm = _parseOptionsOrShowHelp(cryfsOptions, supportedCiphers);
if (!vm.count("base-dir")) { if (!vm.count("base-dir")) {
_showHelpAndExit("Please specify a base directory.", ErrorCode::InvalidArguments); _showHelpAndExit("Please specify a base directory.", ErrorCode::InvalidArguments);
@ -55,11 +55,11 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
if (vm.count("config")) { if (vm.count("config")) {
configfile = bf::absolute(vm["config"].as<string>()); configfile = bf::absolute(vm["config"].as<string>());
} }
bool foreground = vm.count("foreground"); const bool foreground = vm.count("foreground");
bool allowFilesystemUpgrade = vm.count("allow-filesystem-upgrade"); const bool allowFilesystemUpgrade = vm.count("allow-filesystem-upgrade");
bool allowReplacedFilesystem = vm.count("allow-replaced-filesystem"); const bool allowReplacedFilesystem = vm.count("allow-replaced-filesystem");
bool createMissingBasedir = vm.count("create-missing-basedir"); const bool createMissingBasedir = vm.count("create-missing-basedir");
bool createMissingMountpoint = vm.count("create-missing-mountpoint"); const bool createMissingMountpoint = vm.count("create-missing-mountpoint");
optional<double> unmountAfterIdleMinutes = 0.0; // first setting to 0 and then to none is somehow needed to silence a GCC warning from -Wmaybe-uninitialized optional<double> unmountAfterIdleMinutes = 0.0; // first setting to 0 and then to none is somehow needed to silence a GCC warning from -Wmaybe-uninitialized
unmountAfterIdleMinutes = none; unmountAfterIdleMinutes = none;
if (vm.count("unmount-idle")) { if (vm.count("unmount-idle")) {
@ -78,7 +78,7 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
if (vm.count("blocksize")) { if (vm.count("blocksize")) {
blocksizeBytes = vm["blocksize"].as<uint32_t>(); blocksizeBytes = vm["blocksize"].as<uint32_t>();
} }
bool allowIntegrityViolations = vm.count("allow-integrity-violations"); const bool allowIntegrityViolations = vm.count("allow-integrity-violations");
optional<bool> missingBlockIsIntegrityViolation = none; optional<bool> missingBlockIsIntegrityViolation = none;
if (vm.count("missing-block-is-integrity-violation")) { if (vm.count("missing-block-is-integrity-violation")) {
missingBlockIsIntegrityViolation = vm["missing-block-is-integrity-violation"].as<bool>(); missingBlockIsIntegrityViolation = vm["missing-block-is-integrity-violation"].as<bool>();

View File

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

View File

@ -20,13 +20,13 @@ void _showVersion() {
void Cli::main(int argc, const char **argv) { void Cli::main(int argc, const char **argv) {
_showVersion(); _showVersion();
ProgramOptions options = Parser(argc, argv).parse(); const ProgramOptions options = Parser(argc, argv).parse();
if (!boost::filesystem::exists(options.mountDir())) { if (!boost::filesystem::exists(options.mountDir())) {
throw cryfs::CryfsException("Given mountdir doesn't exist", cryfs::ErrorCode::InaccessibleMountDir); throw cryfs::CryfsException("Given mountdir doesn't exist", cryfs::ErrorCode::InaccessibleMountDir);
} }
bool immediate = options.immediate(); bool immediate = options.immediate(); // NOLINT(misc-const-correctness) -- this cannot be const because it is modified in a platform-specific ifdef below
#if defined(__APPLE__) #if defined(__APPLE__)
if (options.immediate()) { if (options.immediate()) {
std::cerr << "Warning: OSX doesn't support the --immediate flag. Ignoring it."; std::cerr << "Warning: OSX doesn't support the --immediate flag. Ignoring it.";

View File

@ -8,7 +8,6 @@
#include <cpp-utils/assert/backtrace.h> #include <cpp-utils/assert/backtrace.h>
#include "Cli.h" #include "Cli.h"
using std::cerr;
using cryfs::ErrorCode; using cryfs::ErrorCode;
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {

View File

@ -30,13 +30,13 @@ vector<string> Parser::_argsToVector(int argc, const char **argv) {
} }
ProgramOptions Parser::parse() const { ProgramOptions Parser::parse() const {
po::variables_map vm = _parseOptionsOrShowHelp(_options); const po::variables_map vm = _parseOptionsOrShowHelp(_options);
if (!vm.count("mount-dir")) { if (!vm.count("mount-dir")) {
_showHelpAndExit("Please specify a mount directory.", ErrorCode::InvalidArguments); _showHelpAndExit("Please specify a mount directory.", ErrorCode::InvalidArguments);
} }
bf::path mountDir = vm["mount-dir"].as<string>(); bf::path mountDir = vm["mount-dir"].as<string>();
bool immediate = vm.count("immediate"); const bool immediate = vm.count("immediate");
return ProgramOptions(std::move(mountDir), immediate); return ProgramOptions(std::move(mountDir), immediate);
} }

View File

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

View File

@ -29,7 +29,7 @@ namespace cryfs {
bool askAgain = true; bool askAgain = true;
while(askAgain) { while(askAgain) {
_console->print("\n"); _console->print("\n");
unsigned int cipherIndex = _console->ask("Which block cipher do you want to use?", ciphers); const unsigned int cipherIndex = _console->ask("Which block cipher do you want to use?", ciphers);
cipherName = ciphers[cipherIndex]; cipherName = ciphers[cipherIndex];
askAgain = !_showWarningForCipherAndReturnIfOk(cipherName); askAgain = !_showWarningForCipherAndReturnIfOk(cipherName);
}; };
@ -53,8 +53,8 @@ namespace cryfs {
} }
uint32_t CryConfigConsole::_askBlocksizeBytes() const { uint32_t CryConfigConsole::_askBlocksizeBytes() const {
vector<string> sizes = {"4KB", "8KB", "16KB", "32KB", "64KB", "512KB", "1MB", "4MB"}; const vector<string> sizes = {"4KB", "8KB", "16KB", "32KB", "64KB", "512KB", "1MB", "4MB"};
unsigned int index = _console->ask("Which block size do you want to use?", sizes); const unsigned int index = _console->ask("Which block size do you want to use?", sizes);
switch(index) { switch(index) {
case 0: return 4*1024; case 0: return 4*1024;
case 1: return 8*1024; case 1: return 8*1024;

View File

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

View File

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

View File

@ -20,7 +20,6 @@ using boost::none;
using std::shared_ptr; using std::shared_ptr;
using std::string; using std::string;
using std::shared_ptr; using std::shared_ptr;
using gitversion::VersionCompare;
using namespace cpputils::logging; using namespace cpputils::logging;
namespace cryfs { namespace cryfs {
@ -59,7 +58,7 @@ either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> CryConfigLoa
} }
_checkCipher(*config.right()->config()); _checkCipher(*config.right()->config());
auto localState = LocalStateMetadata::loadOrGenerate(_localStateDir.forFilesystemId(config.right()->config()->FilesystemId()), cpputils::Data::FromString(config.right()->config()->EncryptionKey()), allowReplacedFilesystem); 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); _checkMissingBlocksAreIntegrityViolations(config.right().get(), myClientId);
return ConfigLoadResult {std::move(oldConfig), std::move(config.right()), 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 { Data CryConfigEncryptor::encrypt(const Data &plaintext, const string &cipherName) const {
InnerConfig innerConfig = _innerEncryptor(cipherName)->encrypt(plaintext); const InnerConfig innerConfig = _innerEncryptor(cipherName)->encrypt(plaintext);
Data serializedInnerConfig = innerConfig.serialize(); const Data serializedInnerConfig = innerConfig.serialize();
OuterConfig outerConfig = _outerEncryptor()->encrypt(serializedInnerConfig); const OuterConfig outerConfig = _outerEncryptor()->encrypt(serializedInnerConfig);
return outerConfig.serialize(); return outerConfig.serialize();
} }

View File

@ -32,7 +32,7 @@ namespace cryfs {
Deserializer deserializer(&data); Deserializer deserializer(&data);
try { try {
_checkHeader(&deserializer); _checkHeader(&deserializer);
string cipherName = deserializer.readString(); const string cipherName = deserializer.readString();
auto result = deserializer.readTailData(); auto result = deserializer.readTailData();
deserializer.finished(); deserializer.finished();
return InnerConfig {cipherName, std::move(result)}; return InnerConfig {cipherName, std::move(result)};
@ -43,7 +43,7 @@ namespace cryfs {
} }
void InnerConfig::_checkHeader(Deserializer *deserializer) { void InnerConfig::_checkHeader(Deserializer *deserializer) {
string header = deserializer->readString(); const string header = deserializer->readString();
if (header != HEADER) { if (header != HEADER) {
throw std::runtime_error("Invalid header. Maybe this filesystem was created with a different version of CryFS?"); 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"; const string OuterConfig::HEADER = "cryfs.config;1;scrypt";
void OuterConfig::_checkHeader(Deserializer *deserializer) { void OuterConfig::_checkHeader(Deserializer *deserializer) {
string header = deserializer->readString(); const string header = deserializer->readString();
if (header != HEADER) { if (header != HEADER) {
throw std::runtime_error("Invalid header"); throw std::runtime_error("Invalid header");
} }
@ -47,7 +47,7 @@ namespace cryfs {
Deserializer deserializer(&data); Deserializer deserializer(&data);
try { try {
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
string header = deserializer.readString(); const string header = deserializer.readString();
if (header == OLD_HEADER) { if (header == OLD_HEADER) {
return _deserializeOldFormat(&deserializer); return _deserializeOldFormat(&deserializer);
} else if (header == HEADER) { } else if (header == HEADER) {

View File

@ -78,7 +78,7 @@ unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CryDevice::Crea
#ifndef CRYFS_NO_COMPATIBILITY #ifndef CRYFS_NO_COMPATIBILITY
unique_ref<fsblobstore::FsBlobStore> CryDevice::MigrateOrCreateFsBlobStore(unique_ref<BlobStore> blobStore, CryConfigFile *configFile) { unique_ref<fsblobstore::FsBlobStore> CryDevice::MigrateOrCreateFsBlobStore(unique_ref<BlobStore> blobStore, CryConfigFile *configFile) {
string rootBlobId = configFile->config()->RootBlob(); const string rootBlobId = configFile->config()->RootBlob();
if ("" == rootBlobId) { if ("" == rootBlobId) {
return make_unique_ref<FsBlobStore>(std::move(blobStore)); return make_unique_ref<FsBlobStore>(std::move(blobStore));
} }
@ -252,7 +252,7 @@ optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf
// Child entry in directory not found // Child entry in directory not found
return none; return none;
} }
BlockId childId = childOpt->blockId(); const BlockId childId = childOpt->blockId();
auto nextBlob = _fsBlobStore->load(childId); auto nextBlob = _fsBlobStore->load(childId);
if (nextBlob == none) { if (nextBlob == none) {
throw FuseErrnoException(EIO); // Blob for directory entry not found throw FuseErrnoException(EIO); // Blob for directory entry not found
@ -273,8 +273,8 @@ optional<CryDevice::BlobWithAncestors> CryDevice::LoadBlobWithAncestors(const bf
CryDevice::statvfs CryDevice::statfs() { CryDevice::statvfs CryDevice::statfs() {
callFsActionCallbacks(); callFsActionCallbacks();
uint64_t numUsedBlocks = _fsBlobStore->numBlocks(); const uint64_t numUsedBlocks = _fsBlobStore->numBlocks();
uint64_t numFreeBlocks = _fsBlobStore->estimateSpaceForNumBlocksLeft(); const uint64_t numFreeBlocks = _fsBlobStore->estimateSpaceForNumBlocksLeft();
statvfs result; 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. 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.
@ -322,7 +322,7 @@ void CryDevice::RemoveBlob(const blockstore::BlockId &blockId) {
} }
BlockId CryDevice::GetOrCreateRootBlobId(CryConfigFile *configFile) { 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 ) if (root_blockId == "") { // NOLINT (workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82481 )
auto new_blockId = CreateRootBlobAndReturnId(); auto new_blockId = CreateRootBlobAndReturnId();
configFile->config()->SetRootBlob(new_blockId.ToString()); configFile->config()->SetRootBlob(new_blockId.ToString());

View File

@ -11,7 +11,7 @@ namespace cryfs {
class CryDir final: public fspp::Dir, public CryNode { class CryDir final: public fspp::Dir, public CryNode {
public: public:
CryDir(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId); 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? //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; cpputils::unique_ref<fspp::OpenFile> createAndOpenFile(const std::string &name, fspp::mode_t mode, fspp::uid_t uid, fspp::gid_t gid) override;

View File

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

View File

@ -108,7 +108,7 @@ void CryNode::rename(const bf::path &to) {
if (old == boost::none) { if (old == boost::none) {
throw FuseErrnoException(EIO); throw FuseErrnoException(EIO);
} }
fsblobstore::DirEntry oldEntry = *old; // Copying this (instead of only keeping the reference) is necessary, because the operations below (i.e. RenameChild()) might make a reference invalid. 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) { auto onOverwritten = [this] (const blockstore::BlockId &blockId) {
device()->RemoveBlob(blockId); device()->RemoveBlob(blockId);
}; };
@ -218,7 +218,7 @@ CryNode::stat_info CryNode::stat() const {
result.size = fsblobstore::DirBlob::DIR_LSTAT_SIZE; 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 "..") //TODO If possible without performance loss, then for a directory, st_nlink should return number of dir entries (including "." and "..")
result.nlink = 1; result.nlink = 1;
struct timespec now = cpputils::time::now(); const struct timespec now = cpputils::time::now();
result.atime = now; result.atime = now;
result.mtime = now; result.mtime = now;
result.ctime = now; result.ctime = now;

View File

@ -12,7 +12,7 @@ namespace cryfs {
class CryNode: public fspp::Node { class CryNode: public fspp::Node {
public: 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. // 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); CryNode(CryDevice *device, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> parent, boost::optional<cpputils::unique_ref<parallelaccessfsblobstore::DirBlobRef>> grandparent, const blockstore::BlockId &blockId);

View File

@ -12,7 +12,7 @@ class CryDevice;
class CryOpenFile final: public fspp::OpenFile { class CryOpenFile final: public fspp::OpenFile {
public: public:
explicit CryOpenFile(const CryDevice *device, std::shared_ptr<parallelaccessfsblobstore::DirBlobRef> parent, cpputils::unique_ref<parallelaccessfsblobstore::FileBlobRef> fileBlob); explicit CryOpenFile(const CryDevice *device, std::shared_ptr<parallelaccessfsblobstore::DirBlobRef> parent, cpputils::unique_ref<parallelaccessfsblobstore::FileBlobRef> fileBlob);
~CryOpenFile(); ~CryOpenFile() override;
stat_info stat() const override; stat_info stat() const override;
void truncate(fspp::num_bytes_t size) const override; void truncate(fspp::num_bytes_t size) const override;

View File

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

View File

@ -92,7 +92,7 @@ namespace cryfs {
} }
inline void CachingFsBlobStore::releaseForCache(cpputils::unique_ref<fsblobstore::FsBlob> baseBlob) { inline void CachingFsBlobStore::releaseForCache(cpputils::unique_ref<fsblobstore::FsBlob> baseBlob) {
blockstore::BlockId blockId = baseBlob->blockId(); const blockstore::BlockId blockId = baseBlob->blockId();
_cache.push(blockId, std::move(baseBlob)); _cache.push(blockId, std::move(baseBlob));
} }

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