diff options
| author | Dan Engelbrecht <[email protected]> | 2022-03-25 12:04:59 +0100 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2022-03-31 11:29:27 +0200 |
| commit | 6a166635b5c1d12aae5e58a04fbe423cf9995f6f (patch) | |
| tree | d8ae7df19316397dd2e22a939c003a0b1da589d9 /zenstore/compactcas.cpp | |
| parent | Migration now works in larger disk IO chunks (diff) | |
| download | zen-6a166635b5c1d12aae5e58a04fbe423cf9995f6f.tar.xz zen-6a166635b5c1d12aae5e58a04fbe423cf9995f6f.zip | |
incremental migration with optional clean of source
add more fine-grained access modes for BasicFile
Diffstat (limited to 'zenstore/compactcas.cpp')
| -rw-r--r-- | zenstore/compactcas.cpp | 349 |
1 files changed, 182 insertions, 167 deletions
diff --git a/zenstore/compactcas.cpp b/zenstore/compactcas.cpp index 9d0f72442..e389adb84 100644 --- a/zenstore/compactcas.cpp +++ b/zenstore/compactcas.cpp @@ -61,34 +61,39 @@ namespace { const char* LogExtension = ".ulog"; const char* DataExtension = ".ucas"; + std::filesystem::path GetBasePath(const std::filesystem::path& RootPath, const std::string& ContainerBaseName) + { + return RootPath / ContainerBaseName; + } + std::filesystem::path GetIndexPath(const std::filesystem::path& RootPath, const std::string& ContainerBaseName) { - return RootPath / ContainerBaseName / (ContainerBaseName + IndexExtension); + return GetBasePath(RootPath, ContainerBaseName) / (ContainerBaseName + IndexExtension); } std::filesystem::path GetTempIndexPath(const std::filesystem::path& RootPath, const std::string& ContainerBaseName) { - return RootPath / ContainerBaseName / (ContainerBaseName + ".tmp" + LogExtension); + return GetBasePath(RootPath, ContainerBaseName) / (ContainerBaseName + ".tmp" + LogExtension); } std::filesystem::path GetLogPath(const std::filesystem::path& RootPath, const std::string& ContainerBaseName) { - return RootPath / ContainerBaseName / (ContainerBaseName + LogExtension); + return GetBasePath(RootPath, ContainerBaseName) / (ContainerBaseName + LogExtension); } std::filesystem::path GetTempLogPath(const std::filesystem::path& RootPath, const std::string& ContainerBaseName) { - return RootPath / ContainerBaseName / (ContainerBaseName + ".tmp" + LogExtension); + return GetBasePath(RootPath, ContainerBaseName) / (ContainerBaseName + ".tmp" + LogExtension); } std::filesystem::path GetRecoverLogPath(const std::filesystem::path& RootPath, const std::string& ContainerBaseName) { - return RootPath / ContainerBaseName / (ContainerBaseName + ".recover" + LogExtension); + return GetBasePath(RootPath, ContainerBaseName) / (ContainerBaseName + ".recover" + LogExtension); } std::filesystem::path GetBlocksBasePath(const std::filesystem::path& RootPath, const std::string& ContainerBaseName) { - return RootPath / ContainerBaseName / "blocks"; + return GetBasePath(RootPath, ContainerBaseName) / "blocks"; } std::filesystem::path GetBlockPath(const std::filesystem::path& BlocksBasePath, const uint32_t BlockIndex) @@ -109,7 +114,7 @@ namespace { std::filesystem::path GetGCReservePath(const std::filesystem::path& RootPath, const std::string& ContainerBaseName) { - return RootPath / ContainerBaseName / (ContainerBaseName + ".gc.reserve" + DataExtension); + return GetBasePath(RootPath, ContainerBaseName) / (ContainerBaseName + ".gc.reserve" + DataExtension); } std::filesystem::path GetLegacyLogPath(const std::filesystem::path& RootPath, const std::string& ContainerBaseName) @@ -164,12 +169,63 @@ namespace { uint8_t Flags = 0; }; - void Migrate(const std::filesystem::path& RootPath, - const std::string& ContainerBaseName, - uint64_t MaxBlockSize, - uint64_t PayloadAlignment, - bool Destructive, - bool Overwrite) + bool ReadIndex(const std::filesystem::path& RootDirectory, + const std::string& ContainerBaseName, + uint64_t& InOutPayloadAlignment, + std::unordered_map<IoHash, BlockStoreDiskLocation, IoHash::Hasher>& OutLocationMap) + { + std::filesystem::path SidxPath = GetIndexPath(RootDirectory, ContainerBaseName); + if (std::filesystem::is_regular_file(SidxPath)) + { + BasicFile ObjectIndexFile; + ObjectIndexFile.Open(SidxPath, BasicFile::EMode::kRead); + uint64_t Size = ObjectIndexFile.FileSize(); + if (Size >= sizeof(CasDiskIndexHeader)) + { + uint64_t ExpectedEntryCount = (Size - sizeof(sizeof(CasDiskIndexHeader))) / sizeof(CasDiskIndexEntry); + CasDiskIndexHeader Header; + ObjectIndexFile.Read(&Header, sizeof(Header), 0); + if (Header.Magic == CasDiskIndexHeader::ExpectedMagic && Header.Version == CasDiskIndexHeader::CurrentVersion && + Header.PayloadAlignment > 0 && Header.EntryCount == ExpectedEntryCount) + { + std::vector<CasDiskIndexEntry> Entries{Header.EntryCount}; + ObjectIndexFile.Read(Entries.data(), Header.EntryCount * sizeof(CasDiskIndexEntry), sizeof(CasDiskIndexHeader)); + for (const auto& Entry : Entries) + { + OutLocationMap[Entry.Key] = Entry.Location; + } + InOutPayloadAlignment = Header.PayloadAlignment; + } + } + } + + bool AddedFromCasLog = false; + TCasLogFile<CasDiskIndexEntry> CasLog; + std::filesystem::path SlogPath = GetLogPath(RootDirectory, ContainerBaseName); + if (std::filesystem::is_regular_file(SlogPath)) + { + CasLog.Open(SlogPath, CasLogFile::EMode::kRead); + CasLog.Replay([&](const CasDiskIndexEntry& Record) { + if (Record.Flags & CasDiskIndexEntry::kTombstone) + { + OutLocationMap.erase(Record.Key); + } + else + { + OutLocationMap[Record.Key] = Record.Location; + } + AddedFromCasLog = true; + }); + } + return AddedFromCasLog; + } + + uint64_t MigrateLegacyData(const std::filesystem::path& RootPath, + const std::string& ContainerBaseName, + uint64_t MaxBlockSize, + uint64_t PayloadAlignment, + bool CleanSource, + std::unordered_map<IoHash, BlockStoreDiskLocation, IoHash::Hasher>& InOutLocationMap) { std::filesystem::path BlocksBasePath = GetBlocksBasePath(RootPath, ContainerBaseName); std::filesystem::path LegacyLogPath = GetLegacyLogPath(RootPath, ContainerBaseName); @@ -177,17 +233,7 @@ namespace { if (!std::filesystem::is_regular_file(LegacyLogPath) || !std::filesystem::is_regular_file(LegacySobsPath)) { ZEN_DEBUG("migrate of {} SKIPPED, no legacy data found", RootPath / ContainerBaseName); - return; - } - - std::filesystem::path SlogPath = GetLogPath(RootPath, ContainerBaseName); - if (std::filesystem::is_directory(SlogPath.parent_path())) - { - if (!Overwrite) - { - ZEN_WARN("migrate of {} SKIPPED, new content already exists", RootPath / ContainerBaseName); - return; - } + return 0; } uint32_t NewBlockIndex = 0; @@ -201,12 +247,18 @@ namespace { NiceBytes(TotalSize)); }); + uint32_t WriteBlockIndex = 0; + while (std::filesystem::exists(GetBlockPath(BlocksBasePath, WriteBlockIndex))) + { + ++WriteBlockIndex; + } + std::error_code Error; DiskSpace Space = DiskSpaceInfo(RootPath, Error); if (Error) { ZEN_ERROR("get disk space in {} FAILED, reason '{}'", ContainerBaseName, Error.message()); - return; + return 0; } if (Space.Free < MaxBlockSize) @@ -215,7 +267,7 @@ namespace { RootPath / ContainerBaseName, MaxBlockSize, NiceBytes(Space.Free)); - return; + return 0; } BasicFile BlockFile; @@ -225,7 +277,7 @@ namespace { std::unordered_map<IoHash, LegacyCasDiskIndexEntry, IoHash::Hasher> LegacyDiskIndex; TCasLogFile<LegacyCasDiskIndexEntry> LegacyCasLog; - LegacyCasLog.Open(LegacyLogPath, CasLogFile::EMode::kRead); + LegacyCasLog.Open(LegacyLogPath, CleanSource ? CasLogFile::EMode::kWrite : CasLogFile::EMode::kRead); LegacyCasLog.Replay([&](const LegacyCasDiskIndexEntry& Record) { if (Record.Flags & LegacyCasDiskIndexEntry::kTombstone) { @@ -237,9 +289,18 @@ namespace { { return; } + if (InOutLocationMap.contains(Record.Key)) + { + return; + } LegacyDiskIndex[Record.Key] = Record; }); + if (LegacyDiskIndex.empty()) + { + return 0; + } + uint64_t MaxUsedSize = 0; for (const auto& Entry : LegacyDiskIndex) { @@ -260,9 +321,10 @@ namespace { RootPath / ContainerBaseName, MaxRequiredBlockCount, BlockStoreDiskLocation::MaxBlockIndex); - return; + return 0; } - if (Destructive) + + if (CleanSource) { if (Space.Free < (MaxBlockSize + (1 << 28))) { @@ -271,7 +333,7 @@ namespace { NewBlockIndex + 1, NiceBytes(MaxBlockSize + (1 << 28)), NiceBytes(Space.Free)); - return; + return 0; } } else @@ -283,15 +345,18 @@ namespace { NewBlockIndex + 1, NiceBytes(RequiredDiskSpace + (1 << 28)), NiceBytes(Space.Free)); - return; + return 0; } } + std::filesystem::path SlogPath = GetLogPath(RootPath, ContainerBaseName); CreateDirectories(SlogPath.parent_path()); TCasLogFile<CasDiskIndexEntry> CasLog; - CasLog.Open(SlogPath, CasLogFile::EMode::kTruncate); + CasLog.Open(SlogPath, CasLogFile::EMode::kWrite); - if (Destructive && (MaxRequiredBlockCount < 2)) + uint64_t MovedCount = 0; + + if (CleanSource && (MaxRequiredBlockCount < 2)) { std::vector<CasDiskIndexEntry> LogEntries; LogEntries.reserve(LegacyDiskIndex.size()); @@ -301,16 +366,18 @@ namespace { { const LegacyCasDiskIndexEntry& Record(Entry.second); - BlockStoreLocation NewChunkLocation(0, Record.Location.GetOffset(), Record.Location.GetSize()); - LogEntries.push_back({.Key = Entry.second.Key, - .Location = BlockStoreDiskLocation(NewChunkLocation, PayloadAlignment), - .ContentType = Record.ContentType, - .Flags = Record.Flags}); + BlockStoreLocation NewChunkLocation(WriteBlockIndex, Record.Location.GetOffset(), Record.Location.GetSize()); + BlockStoreDiskLocation NewLocation(NewChunkLocation, PayloadAlignment); + LogEntries.push_back( + {.Key = Entry.second.Key, .Location = NewLocation, .ContentType = Record.ContentType, .Flags = Record.Flags}); + InOutLocationMap[Entry.second.Key] = NewLocation; } - auto BlockPath = GetBlockPath(BlocksBasePath, 0); + auto BlockPath = GetBlockPath(BlocksBasePath, WriteBlockIndex); CreateDirectories(BlockPath.parent_path()); BlockFile.Close(); std::filesystem::rename(LegacySobsPath, BlockPath); + CasLog.Append(LogEntries); + MovedCount = LogEntries.size(); } else { @@ -329,7 +396,6 @@ namespace { uint64_t BlockSize = 0; uint64_t BlockOffset = 0; - uint32_t BlockIndex = 0; std::vector<BlockStoreLocation> NewLocations; struct BlockData { @@ -350,44 +416,33 @@ namespace { uint64_t ChunkOffset = LegacyChunkLocation.GetOffset(); uint64_t ChunkSize = LegacyChunkLocation.GetSize(); - #if 0 - { - std::vector<uint8_t> Data(ChunkSize); - BlockFile.Read(Data.data(), ChunkSize, ChunkOffset); - const IoHash ComputedHash = IoHash::HashBuffer(Data.data(), ChunkSize); - if (ComputedHash != ChunkHash) - { - ZEN_ERROR("migrating store {}, invalid hash for chunk {}. Got {}", - RootPath / ContainerBaseName, - ChunkHash, - ComputedHash); - } - } - #endif // 0 - if (BlockSize == 0) { BlockOffset = ChunkOffset; } if ((BlockSize + ChunkSize) > MaxBlockSize) { - BlockData BlockRange{.BlockOffset = BlockOffset, .BlockSize = BlockSize, .BlockIndex = BlockIndex}; + BlockData BlockRange{.BlockOffset = BlockOffset, .BlockSize = BlockSize, .BlockIndex = WriteBlockIndex}; BlockRange.Chunks.swap(Chunks); BlockRanges.push_back(BlockRange); - BlockIndex++; + WriteBlockIndex++; + while (std::filesystem::exists(GetBlockPath(BlocksBasePath, WriteBlockIndex))) + { + ++WriteBlockIndex; + } BlockOffset = ChunkOffset; BlockSize = 0; } BlockSize = RoundUp(BlockSize, PayloadAlignment); - BlockStoreLocation ChunkLocation = {.BlockIndex = BlockIndex, .Offset = BlockSize, .Size = ChunkSize}; + BlockStoreLocation ChunkLocation = {.BlockIndex = WriteBlockIndex, .Offset = BlockSize, .Size = ChunkSize}; Chunks.push_back({ChunkHash, ChunkLocation}); BlockSize += ChunkSize; } if (BlockSize > 0) { BlockRanges.push_back( - {.Chunks = std::move(Chunks), .BlockOffset = BlockOffset, .BlockSize = BlockSize, .BlockIndex = BlockIndex}); + {.Chunks = std::move(Chunks), .BlockOffset = BlockOffset, .BlockSize = BlockSize, .BlockIndex = WriteBlockIndex}); } std::reverse(BlockRanges.begin(), BlockRanges.end()); @@ -428,25 +483,12 @@ namespace { BlockStoreDiskLocation Location(Entry.second, PayloadAlignment); LogEntries.push_back( {.Key = Entry.first, .Location = Location, .ContentType = LegacyEntry.ContentType, .Flags = LegacyEntry.Flags}); + InOutLocationMap[Entry.first] = Location; } CasLog.Append(LogEntries); - #if 0 - for (const CasDiskIndexEntry& Entry : LogEntries) - { - std::vector<uint8_t> Data(Entry.Location.GetSize()); - ChunkBlock.Read(Data.data(), Entry.Location.GetSize(), Entry.Location.GetOffset(PayloadAlignment)); - const IoHash ComputedHash = IoHash::HashBuffer(Data.data(), Entry.Location.GetSize()); - if (ComputedHash != Entry.Key) - { - ZEN_ERROR("migrating store {}, invalid hash for chunk {}. Got {}", - RootPath / ContainerBaseName, - Entry.Key, - ComputedHash); - } - } - #endif // 0 + MovedCount += LogEntries.size(); - if (Destructive) + if (CleanSource) { std::vector<LegacyCasDiskIndexEntry> LegacyLogEntries; LegacyLogEntries.reserve(BlockRange.Chunks.size()); @@ -462,10 +504,13 @@ namespace { LegacyCasLog.Close(); CasLog.Close(); - if (Destructive) + if (CleanSource) { std::filesystem::remove(LegacyLogPath); + BlockFile.Close(); + std::filesystem::remove(LegacySobsPath); } + return MovedCount; } } // namespace @@ -1244,84 +1289,32 @@ CasContainerStrategy::OpenContainer(bool IsNewStore) m_LocationMap.clear(); - std::filesystem::path SidxPath = GetIndexPath(m_Config.RootDirectory, m_ContainerBaseName); - std::filesystem::path SlogPath = GetLogPath(m_Config.RootDirectory, m_ContainerBaseName); - std::filesystem::path LegacyLogPath = GetLegacyLogPath(m_Config.RootDirectory, m_ContainerBaseName); - std::filesystem::path LegacySobsPath = GetLegacyUcasPath(m_Config.RootDirectory, m_ContainerBaseName); - - bool CasLogEmpty = true; + std::filesystem::path BasePath = GetBasePath(m_Config.RootDirectory, m_ContainerBaseName); if (IsNewStore) { - if (std::filesystem::is_regular_file(LegacyLogPath)) - { - std::filesystem::remove(LegacyLogPath); - } - if (std::filesystem::is_regular_file(LegacySobsPath)) - { - std::filesystem::remove(LegacySobsPath); - } - if (std::filesystem::is_regular_file(SlogPath)) - { - std::filesystem::remove(SlogPath); - } - if (std::filesystem::is_regular_file(SidxPath)) - { - std::filesystem::remove(SidxPath); - } - CreateDirectories(SlogPath.parent_path()); - m_CasLog.Open(SlogPath, CasLogFile::EMode::kTruncate); + std::filesystem::path LegacyLogPath = GetLegacyLogPath(m_Config.RootDirectory, m_ContainerBaseName); + std::filesystem::path LegacySobsPath = GetLegacyUcasPath(m_Config.RootDirectory, m_ContainerBaseName); + std::filesystem::remove(LegacyLogPath); + std::filesystem::remove(LegacySobsPath); + std::filesystem::remove_all(BasePath); } - else - { - // Keep the old cache intact for now - Migrate(m_Config.RootDirectory, m_ContainerBaseName, m_MaxBlockSize, m_PayloadAlignment, false, true); - if (std::filesystem::is_regular_file(SidxPath)) - { - BasicFile ObjectIndexFile; - ObjectIndexFile.Open(SidxPath, BasicFile::EMode::kRead); - uint64_t Size = ObjectIndexFile.FileSize(); - if (Size >= sizeof(CasDiskIndexHeader)) - { - uint64_t ExpectedEntryCount = (Size - sizeof(sizeof(CasDiskIndexHeader))) / sizeof(CasDiskIndexEntry); - CasDiskIndexHeader Header; - ObjectIndexFile.Read(&Header, sizeof(Header), 0); - if (Header.Magic == CasDiskIndexHeader::ExpectedMagic && Header.Version == CasDiskIndexHeader::CurrentVersion && - Header.PayloadAlignment > 0 && Header.EntryCount == ExpectedEntryCount) - { - std::vector<CasDiskIndexEntry> Entries{Header.EntryCount}; - ObjectIndexFile.Read(Entries.data(), Header.EntryCount * sizeof(CasDiskIndexEntry), sizeof(CasDiskIndexHeader)); - ObjectIndexFile.Close(); - for (const auto& Entry : Entries) - { - m_LocationMap[Entry.Key] = Entry.Location; - } - m_PayloadAlignment = Header.PayloadAlignment; - } - } - } + bool AddedFromCasLog = ReadIndex(m_Config.RootDirectory, m_ContainerBaseName, m_PayloadAlignment, m_LocationMap); - m_CasLog.Open(SlogPath, CasLogFile::EMode::kWrite); - m_CasLog.Replay([&](const CasDiskIndexEntry& Record) { - if (Record.Flags & CasDiskIndexEntry::kTombstone) - { - m_LocationMap.erase(Record.Key); - } - else - { - m_LocationMap[Record.Key] = Record.Location; - } - CasLogEmpty = false; - }); - } + MigrateLegacyData(m_Config.RootDirectory, m_ContainerBaseName, m_MaxBlockSize, m_PayloadAlignment, false, m_LocationMap); + + CreateDirectories(BasePath); + + std::filesystem::path SlogPath = GetLogPath(m_Config.RootDirectory, m_ContainerBaseName); + m_CasLog.Open(SlogPath, CasLogFile::EMode::kWrite); - std::unordered_set<uint32_t> BlockUsage; + std::unordered_set<uint32_t> KnownBlocks; for (const auto& Entry : m_LocationMap) { const BlockStoreDiskLocation& Location = Entry.second; m_TotalSize.fetch_add(Location.GetSize(), std::memory_order_release); - BlockUsage.insert(Location.GetBlockIndex()); + KnownBlocks.insert(Location.GetBlockIndex()); } if (std::filesystem::is_directory(m_BlocksBasePath)) @@ -1357,7 +1350,7 @@ CasContainerStrategy::OpenContainer(bool IsNewStore) { continue; } - if (!BlockUsage.contains(BlockIndex)) + if (!KnownBlocks.contains(BlockIndex)) { // Clear out unused blocks std::filesystem::remove(Path); @@ -1388,38 +1381,39 @@ CasContainerStrategy::OpenContainer(bool IsNewStore) { GCReserveFile.Open(GCReservePath, BasicFile::EMode::kWrite); std::uint64_t CurrentSize = GCReserveFile.FileSize(); - if (CurrentSize != m_MaxBlockSize) + if ((Space.Free - CurrentSize) >= m_MaxBlockSize) { - if (CurrentSize > m_MaxBlockSize) - { - GCReserveFile.SetFileSize(m_MaxBlockSize); - } - else - { - std::uint64_t ExtraSpace = m_MaxBlockSize - CurrentSize; - if (Space.Free >= ExtraSpace) - { - GCReserveFile.SetFileSize(m_MaxBlockSize); - } - else - { - // We need it to be the proper size if we are to use it - std::filesystem::remove(GCReservePath); - } - } + GCReserveFile.SetFileSize(m_MaxBlockSize); + } + else + { + // We need it to be the proper size if we are to use it + ZEN_WARN("removing gc reserve {}, not enough space free on drive, need {}, have {} ", + m_Config.RootDirectory / m_ContainerBaseName, + NiceBytes(m_MaxBlockSize), + NiceBytes(Space.Free)); + + std::filesystem::remove(GCReservePath); } } else { - if (Space.Free > m_MaxBlockSize) + if (Space.Free >= m_MaxBlockSize) { CreateDirectories(GCReservePath.parent_path()); GCReserveFile.Open(GCReservePath, BasicFile::EMode::kTruncate); GCReserveFile.SetFileSize(m_MaxBlockSize); } + else + { + ZEN_WARN("can't create gc reserve {}, not enough space free on drive, need {}, have {} ", + m_Config.RootDirectory / m_ContainerBaseName, + NiceBytes(m_MaxBlockSize), + NiceBytes(Space.Free)); + } } - if (!CasLogEmpty) + if (AddedFromCasLog) { MakeIndexSnapshot(); } @@ -2319,9 +2313,30 @@ TEST_CASE("compactcas.threadedinsert") // * doctest::skip(true)) TEST_CASE("compactcas.migrate.large.data" * doctest::skip(true)) { - const char* BigDataPath = "D:\\zen-data\\dc4-zen-cache-t\\cas"; - Migrate(BigDataPath, "tobs", 1u << 28, 16, false, true); - Migrate(BigDataPath, "sobs", 1u << 30, 4096, false, true); + const char* BigDataPath = "D:\\zen-data\\dc4-zen-cache-t\\cas"; + std::filesystem::path TobsBasePath = GetBasePath(BigDataPath, "tobs"); + std::filesystem::path SobsBasePath = GetBasePath(BigDataPath, "sobs"); + std::filesystem::remove_all(TobsBasePath); + std::filesystem::remove_all(SobsBasePath); + uint64_t TobsPayloadAlignment = 16; + uint64_t TobsBlockSize = 1u << 28; + std::unordered_map<IoHash, BlockStoreDiskLocation, IoHash::Hasher> TobsLocationMap; + uint64_t MigratedTobsCount = MigrateLegacyData(BigDataPath, "tobs", TobsBlockSize, TobsPayloadAlignment, false, TobsLocationMap); + CHECK(MigratedTobsCount > 0); + TobsLocationMap.clear(); + ReadIndex(BigDataPath, "tobs", TobsPayloadAlignment, TobsLocationMap); + uint64_t MigratedTobsCount2 = MigrateLegacyData(BigDataPath, "tobs", TobsBlockSize, TobsPayloadAlignment, false, TobsLocationMap); + CHECK(MigratedTobsCount2 == 0); + + uint64_t SobsPayloadAlignment = 4096; + uint64_t SobsBlockSize = 1u << 30; + std::unordered_map<IoHash, BlockStoreDiskLocation, IoHash::Hasher> SobsLocationMap; + uint64_t MigratedSobsCount = MigrateLegacyData(BigDataPath, "sobs", SobsBlockSize, SobsPayloadAlignment, false, SobsLocationMap); + CHECK(MigratedSobsCount > 0); + SobsLocationMap.clear(); + ReadIndex(BigDataPath, "sobs", SobsPayloadAlignment, SobsLocationMap); + uint64_t MigratedSobsCount2 = MigrateLegacyData(BigDataPath, "sobs", SobsBlockSize, SobsPayloadAlignment, false, SobsLocationMap); + CHECK(MigratedSobsCount2 == 0); CasStoreConfiguration CasConfig; CasConfig.RootDirectory = BigDataPath; |