aboutsummaryrefslogtreecommitdiff
path: root/zenserver/cache/structuredcachestore.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-05-24 13:52:45 +0200
committerDan Engelbrecht <[email protected]>2022-05-24 18:54:04 +0200
commitba135d4a90746ed905a825f48fc3ccfe0641301e (patch)
tree51dca3f4f321392914dc7797582473f6f7ba650d /zenserver/cache/structuredcachestore.cpp
parentMake sure to hold exclusive lock over index and all shard locks. (diff)
downloadzen-ba135d4a90746ed905a825f48fc3ccfe0641301e.tar.xz
zen-ba135d4a90746ed905a825f48fc3ccfe0641301e.zip
Use rename/delete and keep pointer for dropped buckets
Diffstat (limited to 'zenserver/cache/structuredcachestore.cpp')
-rw-r--r--zenserver/cache/structuredcachestore.cpp157
1 files changed, 104 insertions, 53 deletions
diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp
index 1db99280e..be9e408b4 100644
--- a/zenserver/cache/structuredcachestore.cpp
+++ b/zenserver/cache/structuredcachestore.cpp
@@ -580,19 +580,6 @@ ZenCacheDiskLayer::CacheBucket::~CacheBucket()
{
}
-bool
-ZenCacheDiskLayer::CacheBucket::Delete(std::filesystem::path BucketDir)
-{
- if (std::filesystem::exists(BucketDir))
- {
- DeleteDirectories(BucketDir);
-
- return true;
- }
-
- return false;
-}
-
void
ZenCacheDiskLayer::CacheBucket::OpenOrCreate(std::filesystem::path BucketDir, bool AllowCreate)
{
@@ -1158,11 +1145,6 @@ ZenCacheDiskLayer::CacheBucket::GetStandaloneCacheValue(const DiskLocation& Loc,
bool
ZenCacheDiskLayer::CacheBucket::Get(const IoHash& HashKey, ZenCacheValue& OutValue)
{
- if (!m_IsOk)
- {
- return false;
- }
-
RwLock::SharedLockScope _(m_IndexLock);
auto It = m_Index.find(HashKey);
if (It == m_Index.end())
@@ -1184,11 +1166,6 @@ ZenCacheDiskLayer::CacheBucket::Get(const IoHash& HashKey, ZenCacheValue& OutVal
void
ZenCacheDiskLayer::CacheBucket::Put(const IoHash& HashKey, const ZenCacheValue& Value)
{
- if (!m_IsOk)
- {
- return;
- }
-
if (Value.Value.Size() >= m_LargeObjectThreshold)
{
return PutStandaloneCacheValue(HashKey, Value);
@@ -1196,10 +1173,43 @@ ZenCacheDiskLayer::CacheBucket::Put(const IoHash& HashKey, const ZenCacheValue&
PutInlineCacheValue(HashKey, Value);
}
+static bool
+DeleteBucketFromDisk(const std::filesystem::path& BucketDir, std::string_view BucketName)
+{
+ int dropIndex = 0;
+ do
+ {
+ if (!std::filesystem::exists(BucketDir))
+ {
+ return false;
+ }
+
+ std::string DroppedBucketName = fmt::format("[dropped]{}({})", BucketName, dropIndex);
+ std::filesystem::path DroppedBucketPath = BucketDir.parent_path() / DroppedBucketName;
+ if (std::filesystem::exists(DroppedBucketPath))
+ {
+ dropIndex++;
+ continue;
+ }
+
+ std::error_code Ec;
+ std::filesystem::rename(BucketDir, DroppedBucketPath, Ec);
+ if (!Ec)
+ {
+ DeleteDirectories(DroppedBucketPath);
+ return true;
+ }
+ // TODO: Do we need to bail at some point?
+ zen::Sleep(100);
+ } while (true);
+}
+
void
ZenCacheDiskLayer::CacheBucket::Drop()
{
- RwLock::ExclusiveLockScope _(m_IndexLock);
+ RwLock::ExclusiveLockScope _(m_IndexLock);
+ m_IsOk = false;
+
std::vector<std::unique_ptr<RwLock::ExclusiveLockScope>> ShardLocks;
ShardLocks.reserve(256);
for (RwLock& Lock : m_ShardedLocks)
@@ -1208,8 +1218,10 @@ ZenCacheDiskLayer::CacheBucket::Drop()
}
m_BlockStore.Close();
m_SlogFile.Close();
+
+ DeleteBucketFromDisk(m_BucketDir, m_BucketName);
+
m_Index.clear();
- DeleteDirectories(m_BucketDir);
}
void
@@ -1711,7 +1723,12 @@ ZenCacheDiskLayer::CollectGarbage(GcContext& GcCtx)
for (auto& Kv : m_Buckets)
{
- Kv.second.CollectGarbage(GcCtx);
+ CacheBucket& Bucket = *Kv.second;
+ if (!Bucket.IsOk())
+ {
+ continue;
+ }
+ Bucket.CollectGarbage(GcCtx);
}
}
@@ -1724,7 +1741,11 @@ ZenCacheDiskLayer::UpdateAccessTimes(const zen::access_tracking::AccessTimes& Ac
{
if (auto It = m_Buckets.find(Kv.first); It != m_Buckets.end())
{
- CacheBucket& Bucket = It->second;
+ CacheBucket& Bucket = *It->second;
+ if (!Bucket.IsOk())
+ {
+ continue;
+ }
Bucket.UpdateAccessTimes(Kv.second);
}
}
@@ -1937,7 +1958,11 @@ ZenCacheDiskLayer::Get(std::string_view InBucket, const IoHash& HashKey, ZenCach
if (it != m_Buckets.end())
{
- Bucket = &it->second;
+ Bucket = it->second.get();
+ if (!Bucket->IsOk())
+ {
+ return false;
+ }
}
}
@@ -1949,22 +1974,25 @@ ZenCacheDiskLayer::Get(std::string_view InBucket, const IoHash& HashKey, ZenCach
if (auto it = m_Buckets.find(BucketName); it != m_Buckets.end())
{
- Bucket = &it->second;
+ Bucket = it->second.get();
}
else
{
- auto It = m_Buckets.try_emplace(BucketName, BucketName);
- Bucket = &It.first->second;
+ auto InsertResult = m_Buckets.emplace(BucketName, std::make_unique<CacheBucket>(BucketName));
+ Bucket = InsertResult.first->second.get();
std::filesystem::path BucketPath = m_RootDir;
BucketPath /= BucketName;
Bucket->OpenOrCreate(BucketPath);
+ if (!Bucket->IsOk())
+ {
+ return false;
+ }
}
}
ZEN_ASSERT(Bucket != nullptr);
-
return Bucket->Get(HashKey, OutValue);
}
@@ -1981,7 +2009,11 @@ ZenCacheDiskLayer::Put(std::string_view InBucket, const IoHash& HashKey, const Z
if (it != m_Buckets.end())
{
- Bucket = &it->second;
+ Bucket = it->second.get();
+ if (!Bucket->IsOk())
+ {
+ return;
+ }
}
}
@@ -1993,26 +2025,27 @@ ZenCacheDiskLayer::Put(std::string_view InBucket, const IoHash& HashKey, const Z
if (auto it = m_Buckets.find(BucketName); it != m_Buckets.end())
{
- Bucket = &it->second;
+ Bucket = it->second.get();
}
else
{
- auto It = m_Buckets.try_emplace(BucketName, BucketName);
- Bucket = &It.first->second;
+ auto InsertResult = m_Buckets.emplace(BucketName, std::make_unique<CacheBucket>(BucketName));
+ Bucket = InsertResult.first->second.get();
std::filesystem::path BucketPath = m_RootDir;
BucketPath /= BucketName;
Bucket->OpenOrCreate(BucketPath);
+ if (!Bucket->IsOk())
+ {
+ return;
+ }
}
}
ZEN_ASSERT(Bucket != nullptr);
- if (Bucket->IsOk())
- {
- Bucket->Put(HashKey, Value);
- }
+ Bucket->Put(HashKey, Value);
}
void
@@ -2034,9 +2067,8 @@ ZenCacheDiskLayer::DiscoverBuckets()
}
else
{
- auto InsertResult = m_Buckets.try_emplace(BucketName, BucketName);
-
- CacheBucket& Bucket = InsertResult.first->second;
+ auto InsertResult = m_Buckets.emplace(BucketName, std::make_unique<CacheBucket>(BucketName));
+ CacheBucket& Bucket = *InsertResult.first->second;
Bucket.OpenOrCreate(BucketPath, /* AllowCreate */ false);
@@ -2063,19 +2095,23 @@ ZenCacheDiskLayer::DropBucket(std::string_view InBucket)
if (it != m_Buckets.end())
{
- CacheBucket* Bucket = &it->second;
-
- Bucket->Drop();
-
+ CacheBucket& Bucket = *it->second;
+ m_DroppedBuckets.push_back(std::move(it->second));
m_Buckets.erase(it);
+ if (!Bucket.IsOk())
+ {
+ return false;
+ }
+
+ Bucket.Drop();
return true;
}
+ // Make sure we remove the folder even if we don't know about the bucket
std::filesystem::path BucketPath = m_RootDir;
BucketPath /= std::string(InBucket);
-
- return CacheBucket::Delete(BucketPath);
+ return DeleteBucketFromDisk(BucketPath, InBucket);
}
void
@@ -2088,7 +2124,12 @@ ZenCacheDiskLayer::Flush()
Buckets.reserve(m_Buckets.size());
for (auto& Kv : m_Buckets)
{
- Buckets.push_back(&Kv.second);
+ CacheBucket* Bucket = Kv.second.get();
+ if (!Bucket->IsOk())
+ {
+ continue;
+ }
+ Buckets.push_back(Bucket);
}
}
@@ -2105,7 +2146,12 @@ ZenCacheDiskLayer::Scrub(ScrubContext& Ctx)
for (auto& Kv : m_Buckets)
{
- Kv.second.Scrub(Ctx);
+ CacheBucket& Bucket = *Kv.second;
+ if (!Bucket.IsOk())
+ {
+ continue;
+ }
+ Bucket.Scrub(Ctx);
}
}
@@ -2116,7 +2162,12 @@ ZenCacheDiskLayer::GatherReferences(GcContext& GcCtx)
for (auto& Kv : m_Buckets)
{
- Kv.second.GatherReferences(GcCtx);
+ CacheBucket& Bucket = *Kv.second;
+ if (!Bucket.IsOk())
+ {
+ continue;
+ }
+ Bucket.GatherReferences(GcCtx);
}
}
@@ -2128,7 +2179,7 @@ ZenCacheDiskLayer::TotalSize() const
for (auto& Kv : m_Buckets)
{
- TotalSize += Kv.second.TotalSize();
+ TotalSize += Kv.second->TotalSize();
}
return TotalSize;