From 12058b79d7ba17902b90c3e777b10a8c4403fe5e Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Tue, 9 May 2023 14:50:41 +0200 Subject: Validate that entries points inside valid blocks at startup (#280) * Separate initialization of block store from pruning of unknown blocks * Validate that entries points inside valid blocks --- src/zenserver/cache/structuredcachestore.cpp | 48 +++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'src/zenserver/cache/structuredcachestore.cpp') diff --git a/src/zenserver/cache/structuredcachestore.cpp b/src/zenserver/cache/structuredcachestore.cpp index 26e970073..99ca23407 100644 --- a/src/zenserver/cache/structuredcachestore.cpp +++ b/src/zenserver/cache/structuredcachestore.cpp @@ -1002,6 +1002,11 @@ ZenCacheDiskLayer::CacheBucket::OpenLog(const bool IsNew) fs::remove_all(m_BlocksBasePath); } + CreateDirectories(m_BucketDir); + + std::unordered_map BlockSizes = + m_BlockStore.Initialize(m_BlocksBasePath, MaxBlockSize, BlockStoreDiskLocation::MaxBlockIndex + 1); + uint64_t LogEntryCount = 0; { uint32_t IndexVersion = 0; @@ -1023,12 +1028,11 @@ ZenCacheDiskLayer::CacheBucket::OpenLog(const bool IsNew) } } - CreateDirectories(m_BucketDir); - m_SlogFile.Open(LogPath, CasLogFile::Mode::kWrite); std::vector KnownLocations; KnownLocations.reserve(m_Index.size()); + std::vector BadEntries; for (const auto& Entry : m_Index) { size_t EntryIndex = Entry.second; @@ -1041,10 +1045,46 @@ ZenCacheDiskLayer::CacheBucket::OpenLog(const bool IsNew) continue; } const BlockStoreLocation& BlockLocation = Location.GetBlockLocation(m_PayloadAlignment); - KnownLocations.push_back(BlockLocation); + + auto BlockIt = BlockSizes.find(BlockLocation.BlockIndex); + if (BlockIt == BlockSizes.end()) + { + ZEN_WARN("Unknown block {} for entry {}", BlockLocation.BlockIndex, Entry.first.ToHexString()); + } + else + { + uint64_t BlockSize = BlockIt->second; + if (BlockLocation.Offset + BlockLocation.Size > BlockSize) + { + ZEN_WARN("Range is outside of block {} for entry {}", BlockLocation.BlockIndex, Entry.first.ToHexString()); + } + else + { + KnownLocations.push_back(BlockLocation); + continue; + } + } + + DiskLocation NewLocation = Payload.Location; + NewLocation.Flags |= DiskLocation::kTombStone; + BadEntries.push_back(DiskIndexEntry{.Key = Entry.first, .Location = NewLocation}); } - m_BlockStore.Initialize(m_BlocksBasePath, MaxBlockSize, BlockStoreDiskLocation::MaxBlockIndex + 1, KnownLocations); + if (!BadEntries.empty()) + { + m_SlogFile.Append(BadEntries); + m_SlogFile.Flush(); + + LogEntryCount += BadEntries.size(); + + for (const DiskIndexEntry& BadEntry : BadEntries) + { + m_Index.erase(BadEntry.Key); + } + } + + m_BlockStore.Prune(KnownLocations); + if (IsNew || LogEntryCount > 0) { MakeIndexSnapshot(); -- cgit v1.2.3