aboutsummaryrefslogtreecommitdiff
path: root/src/zenstore/blockstore.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2023-10-05 16:03:14 +0200
committerGitHub <[email protected]>2023-10-05 16:03:14 +0200
commitba22ffd43e646fe035f8457f3a89500c1cb1c120 (patch)
tree87535bbcc78683c6eabaaf4d27b90da9aeb94077 /src/zenstore/blockstore.cpp
parentFix curruption of disk cache bucket index on GC (#448) (diff)
downloadzen-ba22ffd43e646fe035f8457f3a89500c1cb1c120.tar.xz
zen-ba22ffd43e646fe035f8457f3a89500c1cb1c120.zip
check that block does not exists on disk before starting write to it (#449)
* check that block does not exists on disk before starting write to it
Diffstat (limited to 'src/zenstore/blockstore.cpp')
-rw-r--r--src/zenstore/blockstore.cpp62
1 files changed, 44 insertions, 18 deletions
diff --git a/src/zenstore/blockstore.cpp b/src/zenstore/blockstore.cpp
index 968e919d6..12ea24752 100644
--- a/src/zenstore/blockstore.cpp
+++ b/src/zenstore/blockstore.cpp
@@ -266,6 +266,38 @@ BlockStore::Close()
m_BlocksBasePath.clear();
}
+uint32_t
+BlockStore::GetFreeBlockIndex(uint32_t ProbeIndex, RwLock::ExclusiveLockScope&, std::filesystem::path& OutBlockPath) const
+{
+ if (m_ChunkBlocks.size() == m_MaxBlockCount)
+ {
+ return (uint32_t)m_MaxBlockCount;
+ }
+
+ while (true)
+ {
+ if (!m_ChunkBlocks.contains(ProbeIndex))
+ {
+ OutBlockPath = GetBlockPath(m_BlocksBasePath, ProbeIndex);
+ std::error_code Ec;
+ bool Exists = std::filesystem::exists(OutBlockPath, Ec);
+ if (Ec)
+ {
+ ZEN_WARN("Failed to probe existence of file '{}' when trying to allocate a new block. Reason: '{}'",
+ OutBlockPath,
+ Ec.message());
+ return (uint32_t)m_MaxBlockCount;
+ }
+ if (!Exists)
+ {
+ return ProbeIndex;
+ }
+ }
+ ProbeIndex = (ProbeIndex + 1) & (m_MaxBlockCount - 1);
+ }
+ return ProbeIndex;
+}
+
void
BlockStore::WriteChunk(const void* Data, uint64_t Size, uint64_t Alignment, const WriteChunkCallback& Callback)
{
@@ -288,19 +320,14 @@ BlockStore::WriteChunk(const void* Data, uint64_t Size, uint64_t Alignment, cons
m_WriteBlock = nullptr;
}
- if (m_ChunkBlocks.size() == m_MaxBlockCount)
- {
- throw std::runtime_error(fmt::format("unable to allocate a new block in '{}'", m_BlocksBasePath));
- }
-
WriteBlockIndex += IsWriting ? 1 : 0;
- while (m_ChunkBlocks.contains(WriteBlockIndex))
+ std::filesystem::path BlockPath;
+ WriteBlockIndex = GetFreeBlockIndex(WriteBlockIndex, InsertLock, BlockPath);
+ if (WriteBlockIndex == (uint32_t)m_MaxBlockCount)
{
- WriteBlockIndex = (WriteBlockIndex + 1) & (m_MaxBlockCount - 1);
+ throw std::runtime_error(fmt::format("unable to allocate a new block in '{}'", m_BlocksBasePath));
}
- std::filesystem::path BlockPath = GetBlockPath(m_BlocksBasePath, WriteBlockIndex);
-
Ref<BlockStoreFile> NewBlockFile(new BlockStoreFile(BlockPath));
NewBlockFile->Create(m_MaxBlockSize);
@@ -616,27 +643,26 @@ BlockStore::ReclaimSpace(const ReclaimSnapshotState& Snapshot,
ChangeCallback(MovedChunks, {});
MovedCount += KeepMap.size();
MovedChunks.clear();
- RwLock::ExclusiveLockScope __(m_InsertLock);
+ RwLock::ExclusiveLockScope InsertLock(m_InsertLock);
Stopwatch Timer;
const auto ___ = MakeGuard([&] {
uint64_t ElapsedUs = Timer.GetElapsedTimeUs();
ReadBlockTimeUs += ElapsedUs;
ReadBlockLongestTimeUs = std::max(ElapsedUs, ReadBlockLongestTimeUs);
});
- if (m_ChunkBlocks.size() == m_MaxBlockCount)
+
+ std::filesystem::path NewBlockPath;
+ NextBlockIndex = GetFreeBlockIndex(NextBlockIndex, InsertLock, NewBlockPath);
+ if (NextBlockIndex == (uint32_t)m_MaxBlockCount)
{
ZEN_ERROR("unable to allocate a new block in '{}', count limit {} exeeded",
m_BlocksBasePath,
static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()) + 1);
return;
}
- while (m_ChunkBlocks.contains(NextBlockIndex))
- {
- NextBlockIndex = (NextBlockIndex + 1) & (m_MaxBlockCount - 1);
- }
- std::filesystem::path NewBlockPath = GetBlockPath(m_BlocksBasePath, NextBlockIndex);
- NewBlockFile = new BlockStoreFile(NewBlockPath);
- m_ChunkBlocks[NextBlockIndex] = NewBlockFile;
+
+ NewBlockFile = new BlockStoreFile(NewBlockPath);
+ m_ChunkBlocks[NextBlockIndex] = NewBlockFile;
}
std::error_code Error;