aboutsummaryrefslogtreecommitdiff
path: root/zenstore/compactcas.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-03-27 20:13:54 +0200
committerDan Engelbrecht <[email protected]>2022-03-31 11:29:28 +0200
commit1ed438c250114e1f5ffb7355429862383ffa505d (patch)
tree9e2ce7cfdd6091a3651d5330455965587c3510f9 /zenstore/compactcas.cpp
parentfix cas log parsing (diff)
downloadzen-1ed438c250114e1f5ffb7355429862383ffa505d.tar.xz
zen-1ed438c250114e1f5ffb7355429862383ffa505d.zip
keep all block files open from start
Diffstat (limited to 'zenstore/compactcas.cpp')
-rw-r--r--zenstore/compactcas.cpp21
1 files changed, 14 insertions, 7 deletions
diff --git a/zenstore/compactcas.cpp b/zenstore/compactcas.cpp
index 2bf96ce9d..f7cfed47b 100644
--- a/zenstore/compactcas.cpp
+++ b/zenstore/compactcas.cpp
@@ -623,15 +623,22 @@ CasContainerStrategy::InsertChunk(const void* ChunkData, size_t ChunkSize, const
m_CurrentInsertOffset = 0;
m_WriteBlock->Create(m_MaxBlockSize);
}
- else
- {
- m_WriteBlock->Open();
- }
InsertOffset = m_CurrentInsertOffset;
m_CurrentInsertOffset = RoundUp(InsertOffset + ChunkSize, m_PayloadAlignment);
WriteBlock = m_WriteBlock;
}
+ // We can end up in a situation that two InsertChunk writes the same chunk
+ // data in different locations.
+ // We release the insert lock once we have the correct WriteBlock ready and we know
+ // where to write the data. If a new InsertChunk requests comes in before we update
+ // m_LocationMap below we will have a race.
+ // The outcome of that is that we will occupy space more than once but the hash will
+ // only point to one of the chunks. We will in that case waste space until the next
+ // GC operation.
+ // This would be a rare occasion and the current flow reduces the time we block for
+ // reads, insert and GC.
+
BlockStoreDiskLocation Location({.BlockIndex = WriteBlockIndex, .Offset = InsertOffset, .Size = ChunkSize}, m_PayloadAlignment);
const CasDiskIndexEntry IndexEntry{.Key = ChunkHash, .Location = Location};
@@ -1052,8 +1059,6 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx)
continue;
}
- OldBlockFile->Open();
-
std::vector<uint8_t> Chunk;
for (const IoHash& ChunkHash : KeepMap)
{
@@ -1067,6 +1072,7 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx)
uint32_t NextBlockIndex = m_WriteBlockIndex.load(std::memory_order::memory_order_relaxed);
auto LogEntries = MakeCasDiskEntries(MovedBlockChunks, {});
m_CasLog.Append(LogEntries);
+
{
RwLock::ExclusiveLockScope __(m_LocationMapLock);
Stopwatch Timer;
@@ -1098,7 +1104,6 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx)
ZEN_ERROR("get disk space in {} FAILED, reason '{}'", m_ContainerBaseName, Error.message());
return;
}
-
if (Space.Free < m_MaxBlockSize)
{
std::filesystem::path GCReservePath = GetGCReservePath(m_Config.RootDirectory, m_ContainerBaseName);
@@ -1130,6 +1135,7 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx)
WriteOffset = 0;
}
+
NewBlockFile->Write(Chunk.data(), Chunk.size(), WriteOffset);
MovedBlockChunks.emplace(
ChunkHash,
@@ -1435,6 +1441,7 @@ CasContainerStrategy::OpenContainer(bool IsNewStore)
}
auto BlockPath = GetBlockPath(m_BlocksBasePath, BlockIndex);
auto BlockFile = std::make_shared<BlockStoreFile>(BlockPath);
+ BlockFile->Open();
m_ChunkBlocks[BlockIndex] = BlockFile;
}
}