diff --git a/src/blockstore/implementations/versioncounting/KnownBlockVersions.cpp b/src/blockstore/implementations/versioncounting/KnownBlockVersions.cpp index c810a0c8..18686995 100644 --- a/src/blockstore/implementations/versioncounting/KnownBlockVersions.cpp +++ b/src/blockstore/implementations/versioncounting/KnownBlockVersions.cpp @@ -19,6 +19,7 @@ namespace blockstore { namespace versioncounting { const string KnownBlockVersions::HEADER = "cryfs.integritydata.knownblockversions;0"; +constexpr uint32_t KnownBlockVersions::CLIENT_ID_FOR_DELETED_BLOCK; KnownBlockVersions::KnownBlockVersions(const bf::path &stateFilePath) :_knownVersions(), _lastUpdateClientId(), _stateFilePath(stateFilePath), _myClientId(0), _mutex(), _valid(true) { @@ -46,6 +47,7 @@ KnownBlockVersions::~KnownBlockVersions() { bool KnownBlockVersions::checkAndUpdateVersion(uint32_t clientId, const Key &key, uint64_t version) { unique_lock lock(_mutex); + ASSERT(clientId != CLIENT_ID_FOR_DELETED_BLOCK, "This is not a valid client id"); ASSERT(version > 0, "Version has to be >0"); // Otherwise we wouldn't handle notexisting entries correctly. ASSERT(_valid, "Object not valid due to a std::move"); @@ -85,7 +87,9 @@ void KnownBlockVersions::_loadStateFile() { optional file = Data::LoadFromFile(_stateFilePath); if (file == none) { // File doesn't exist means we loaded empty state. Assign a random client id. - _myClientId = *reinterpret_cast(Random::PseudoRandom().getFixedSize().data()); + do { + _myClientId = *reinterpret_cast(Random::PseudoRandom().getFixedSize().data()); + } while(_myClientId == CLIENT_ID_FOR_DELETED_BLOCK); // Safety check - CLIENT_ID_FOR_DELETED_BLOCK shouldn't be used by any valid client. return; } @@ -183,8 +187,13 @@ uint32_t KnownBlockVersions::myClientId() const { } uint64_t KnownBlockVersions::getBlockVersion(uint32_t clientId, const Key &key) const { + unique_lock lock(_mutex); return _knownVersions.at({clientId, key}); } +void KnownBlockVersions::markBlockAsDeleted(const Key &key) { + _lastUpdateClientId[key] = CLIENT_ID_FOR_DELETED_BLOCK; +} + } } diff --git a/src/blockstore/implementations/versioncounting/KnownBlockVersions.h b/src/blockstore/implementations/versioncounting/KnownBlockVersions.h index 795bda8a..f4b24b60 100644 --- a/src/blockstore/implementations/versioncounting/KnownBlockVersions.h +++ b/src/blockstore/implementations/versioncounting/KnownBlockVersions.h @@ -25,6 +25,8 @@ namespace blockstore { uint64_t incrementVersion(const Key &key, uint64_t lastVersion); + void markBlockAsDeleted(const Key &key); + uint64_t getBlockVersion(uint32_t clientId, const Key &key) const; uint32_t myClientId() const; @@ -38,6 +40,8 @@ namespace blockstore { mutable std::mutex _mutex; bool _valid; + static constexpr uint32_t CLIENT_ID_FOR_DELETED_BLOCK = 0; + static const std::string HEADER; void _loadStateFile(); diff --git a/src/blockstore/implementations/versioncounting/VersionCountingBlock.h b/src/blockstore/implementations/versioncounting/VersionCountingBlock.h index 531d8d9b..49264a3d 100644 --- a/src/blockstore/implementations/versioncounting/VersionCountingBlock.h +++ b/src/blockstore/implementations/versioncounting/VersionCountingBlock.h @@ -41,7 +41,6 @@ public: size_t size() const override; void resize(size_t newSize) override; - uint64_t version() const; cpputils::unique_ref releaseBlock(); #ifndef CRYFS_NO_COMPATIBILITY @@ -208,10 +207,6 @@ inline uint64_t VersionCountingBlock::blockSizeFromPhysicalBlockSize(uint64_t bl return blockSize - HEADER_LENGTH; } -inline uint64_t VersionCountingBlock::version() const { - return _version; -} - } } diff --git a/src/blockstore/implementations/versioncounting/VersionCountingBlockStore.h b/src/blockstore/implementations/versioncounting/VersionCountingBlockStore.h index f9c1cba1..82fb1961 100644 --- a/src/blockstore/implementations/versioncounting/VersionCountingBlockStore.h +++ b/src/blockstore/implementations/versioncounting/VersionCountingBlockStore.h @@ -66,7 +66,7 @@ inline void VersionCountingBlockStore::remove(cpputils::unique_ref block) Key key = block->key(); auto versionCountingBlock = cpputils::dynamic_pointer_move(block); ASSERT(versionCountingBlock != boost::none, "Block is not an VersionCountingBlock"); - _knownBlockVersions.incrementVersion(key, (*versionCountingBlock)->version()); + _knownBlockVersions.markBlockAsDeleted(key); auto baseBlock = (*versionCountingBlock)->releaseBlock(); _baseBlockStore->remove(std::move(baseBlock)); }