diff options
| author | Dan Engelbrecht <[email protected]> | 2025-03-31 10:24:39 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-03-31 10:24:39 +0200 |
| commit | fd2efb5af872a357dbc0f729f4101a330dcb4fda (patch) | |
| tree | 949e933156467113b861f4b0ca5862f9cdf10189 /src/zen/cmds/builds_cmd.cpp | |
| parent | check file from local track state during download (#329) (diff) | |
| download | archived-zen-fd2efb5af872a357dbc0f729f4101a330dcb4fda.tar.xz archived-zen-fd2efb5af872a357dbc0f729f4101a330dcb4fda.zip | |
long filename support (#330)
- Bugfix: Long file paths now works correctly on Windows
Diffstat (limited to 'src/zen/cmds/builds_cmd.cpp')
| -rw-r--r-- | src/zen/cmds/builds_cmd.cpp | 309 |
1 files changed, 185 insertions, 124 deletions
diff --git a/src/zen/cmds/builds_cmd.cpp b/src/zen/cmds/builds_cmd.cpp index e3dc20621..d2ba20e78 100644 --- a/src/zen/cmds/builds_cmd.cpp +++ b/src/zen/cmds/builds_cmd.cpp @@ -165,12 +165,11 @@ namespace { std::filesystem::path MakeSafeAbsolutePath(const std::string Path) { std::filesystem::path AbsolutePath = std::filesystem::absolute(StringToPath(Path)).make_preferred(); -#if ZEN_PLATFORM_WINDOWS && \ - 0 // TODO: We need UNC for long file names but we need to stop using std::filesystem for those paths - std::filesystem::* functions +#if ZEN_PLATFORM_WINDOWS && 1 const std::string_view Prefix = "\\\\?\\"; const std::u8string PrefixU8(Prefix.begin(), Prefix.end()); std::u8string PathString = AbsolutePath.u8string(); - if (!PathString.starts_with(PrefixU8)) + if (!PathString.empty() && !PathString.starts_with(PrefixU8)) { PathString.insert(0, PrefixU8); return std::filesystem::path(PathString); @@ -179,6 +178,82 @@ namespace { return AbsolutePath; } + void RenameFileWithRetry(const std::filesystem::path& SourcePath, const std::filesystem::path& TargetPath) + { + std::error_code Ec; + RenameFile(SourcePath, TargetPath, Ec); + for (size_t Retries = 0; Ec && Retries < 3; Retries++) + { + Sleep(100 + int(Retries * 50)); + RenameFile(SourcePath, TargetPath, Ec); + } + if (Ec) + { + zen::ThrowSystemError(Ec.value(), Ec.message()); + } + } + + bool SetFileReadOnlyWithRetry(const std::filesystem::path& Path, bool ReadOnly) + { + std::error_code Ec; + bool Result = SetFileReadOnly(Path, ReadOnly, Ec); + for (size_t Retries = 0; Ec && Retries < 3; Retries++) + { + Sleep(100 + int(Retries * 50)); + if (!IsFile(Path)) + { + return false; + } + Ec.clear(); + Result = SetFileReadOnly(Path, ReadOnly, Ec); + } + if (Ec) + { + zen::ThrowSystemError(Ec.value(), Ec.message()); + } + return Result; + } + + void RemoveFileWithRetry(const std::filesystem::path& Path) + { + std::error_code Ec; + RemoveFile(Path, Ec); + for (size_t Retries = 0; Ec && Retries < 3; Retries++) + { + Sleep(100 + int(Retries * 50)); + if (!IsFile(Path)) + { + return; + } + Ec.clear(); + RemoveFile(Path, Ec); + } + if (Ec) + { + zen::ThrowSystemError(Ec.value(), Ec.message()); + } + } + + void RemoveDirWithRetry(const std::filesystem::path& Path) + { + std::error_code Ec; + RemoveDir(Path, Ec); + for (size_t Retries = 0; Ec && Retries < 3; Retries++) + { + Sleep(100 + int(Retries * 50)); + if (!IsDir(Path)) + { + return; + } + Ec.clear(); + RemoveDir(Path, Ec); + } + if (Ec) + { + zen::ThrowSystemError(Ec.value(), Ec.message()); + } + } + uint32_t SetNativeFileAttributes(const std::filesystem::path FilePath, SourcePlatform SourcePlatform, uint32_t Attributes) { #if ZEN_PLATFORM_WINDOWS @@ -250,21 +325,8 @@ namespace { { try { - std::error_code Ec; - std::filesystem::remove(LocalFilePath, Ec); - if (Ec) - { - // DeleteOnClose files may be a bit slow in getting cleaned up, so pause amd retry one time - Ec.clear(); - if (std::filesystem::exists(LocalFilePath, Ec) || Ec) - { - Sleep(200); - if (std::filesystem::exists(LocalFilePath)) - { - std::filesystem::remove(LocalFilePath); - } - } - } + SetFileReadOnlyWithRetry(LocalFilePath, false); + RemoveFileWithRetry(LocalFilePath); } catch (const std::exception& Ex) { @@ -273,7 +335,7 @@ namespace { } } - for (const std::filesystem::path& LocalDirPath : LocalDirectoryContent.Directories) + for (std::filesystem::path& LocalDirPath : LocalDirectoryContent.Directories) { bool Leave = false; for (const std::string_view ExcludeDirectory : ExcludeDirectories) @@ -288,23 +350,27 @@ namespace { { try { - zen::CleanDirectory(LocalDirPath); - std::filesystem::remove(LocalDirPath); - } - catch (const std::exception&) - { - Sleep(200); - try + std::error_code Ec; + zen::CleanDirectory(LocalDirPath, true, Ec); + if (Ec) { - zen::CleanDirectory(LocalDirPath); - std::filesystem::remove(LocalDirPath); + Sleep(200); + zen::CleanDirectory(LocalDirPath, true); + Ec.clear(); } - catch (const std::exception& Ex) + + RemoveDir(LocalDirPath, Ec); + if (Ec) { - ZEN_WARN("Failed removing directory {}. Reason: {}", LocalDirPath, Ex.what()); - CleanWipe = false; + Sleep(200); + RemoveDir(LocalDirPath); } } + catch (const std::exception& Ex) + { + ZEN_WARN("Failed removing directory {}. Reason: {}", LocalDirPath, Ex.what()); + CleanWipe = false; + } } } return CleanWipe; @@ -312,7 +378,7 @@ namespace { std::string ReadAccessTokenFromFile(const std::filesystem::path& Path) { - if (!std::filesystem::is_regular_file(Path)) + if (!IsFile(Path)) { throw std::runtime_error(fmt::format("the file '{}' does not exist", Path)); } @@ -355,7 +421,7 @@ namespace { const IoHash& Hash, const std::string& Suffix = {}) { - std::filesystem::path TempFilePath = (TempFolderPath / (Hash.ToHexString() + Suffix)).make_preferred(); + std::filesystem::path TempFilePath = TempFolderPath / (Hash.ToHexString() + Suffix); return WriteToTempFile(std::move(Buffer), TempFilePath); } @@ -453,12 +519,12 @@ namespace { std::filesystem::path GetTempChunkedSequenceFileName(const std::filesystem::path& CacheFolderPath, const IoHash& RawHash) { - return (CacheFolderPath / (RawHash.ToHexString() + ".tmp")).make_preferred(); + return CacheFolderPath / (RawHash.ToHexString() + ".tmp"); } std::filesystem::path GetFinalChunkedSequenceFileName(const std::filesystem::path& CacheFolderPath, const IoHash& RawHash) { - return (CacheFolderPath / RawHash.ToHexString()).make_preferred(); + return CacheFolderPath / RawHash.ToHexString(); } ChunkedFolderContent ScanAndChunkFolder( @@ -1611,7 +1677,8 @@ namespace { auto __ = MakeGuard([&TempFolder]() { if (CleanDirectory(TempFolder, {})) { - std::filesystem::remove(TempFolder); + std::error_code DummyEc; + RemoveDir(TempFolder, DummyEc); } }); @@ -1888,7 +1955,7 @@ namespace { } ZEN_ASSERT_SLOW(IoHash::HashBuffer(RawSource) == ChunkHash); { - std::filesystem::path TempFilePath = (TempFolderPath / ChunkHash.ToHexString()).make_preferred(); + std::filesystem::path TempFilePath = TempFolderPath / ChunkHash.ToHexString(); BasicFile CompressedFile; std::error_code Ec; @@ -1930,7 +1997,7 @@ namespace { return Compressed.GetCompressed(); } CompressedFile.Close(); - std::filesystem::remove(TempFilePath, Ec); + RemoveFile(TempFilePath, Ec); ZEN_UNUSED(Ec); } @@ -2715,7 +2782,8 @@ namespace { auto _ = MakeGuard([&]() { if (CleanDirectory(ZenTempFolder, {})) { - std::filesystem::remove(ZenTempFolder); + std::error_code DummyEc; + RemoveDir(ZenTempFolder, DummyEc); } }); CreateDirectories(ZenTempBlockFolderPath(ZenFolderPath)); @@ -2861,7 +2929,7 @@ namespace { { std::filesystem::path ExcludeManifestPath = Path / ZenExcludeManifestName; tsl::robin_set<std::string> ExcludeAssetPaths; - if (std::filesystem::is_regular_file(ExcludeManifestPath)) + if (IsFile(ExcludeManifestPath)) { std::vector<std::filesystem::path> AssetPaths = ParseManifest(Path, ExcludeManifestPath); ExcludeAssetPaths.reserve(AssetPaths.size()); @@ -2904,12 +2972,13 @@ namespace { for (const std::filesystem::path& AssetPath : AssetPaths) { Content.Paths.push_back(AssetPath); - Content.RawSizes.push_back(std::filesystem::file_size(Path / AssetPath)); + const std::filesystem::path AssetFilePath = (Path / AssetPath).make_preferred(); + Content.RawSizes.push_back(FileSizeFromPath(AssetFilePath)); #if ZEN_PLATFORM_WINDOWS - Content.Attributes.push_back(GetFileAttributes(Path / AssetPath)); + Content.Attributes.push_back(GetFileAttributes(AssetFilePath)); #endif // ZEN_PLATFORM_WINDOWS #if ZEN_PLATFORM_MAC || ZEN_PLATFORM_LINUX - Content.Attributes.push_back(GetFileMode(Path / AssetPath)); + Content.Attributes.push_back(GetFileMode(AssetFilePath)); #endif // ZEN_PLATFORM_MAC || ZEN_PLATFORM_LINUX LocalFolderScanStats.AcceptedFileByteCount += Content.RawSizes.back(); LocalFolderScanStats.AcceptedFileCount++; @@ -2917,12 +2986,13 @@ namespace { if (ManifestPath.is_relative()) { Content.Paths.push_back(ManifestPath); - Content.RawSizes.push_back(std::filesystem::file_size(ManifestPath)); + const std::filesystem::path ManifestFilePath = (Path / ManifestPath).make_preferred(); + Content.RawSizes.push_back(FileSizeFromPath(ManifestFilePath)); #if ZEN_PLATFORM_WINDOWS - Content.Attributes.push_back(GetFileAttributes(ManifestPath)); + Content.Attributes.push_back(GetFileAttributes(ManifestFilePath)); #endif // ZEN_PLATFORM_WINDOWS #if ZEN_PLATFORM_MAC || ZEN_PLATFORM_LINUX - Content.Attributes.push_back(GetFileMode(ManifestPath)); + Content.Attributes.push_back(GetFileMode(ManifestFilePath)); #endif // ZEN_PLATFORM_MAC || ZEN_PLATFORM_LINUX LocalFolderScanStats.AcceptedFileByteCount += Content.RawSizes.back(); @@ -3751,7 +3821,7 @@ namespace { if (IsAcceptedFolder(TargetPath.parent_path().generic_string())) { const uint64_t ExpectedSize = Content.RawSizes[PathIndex]; - if (!std::filesystem::exists(TargetPath)) + if (!IsFile(TargetPath)) { ErrorLock.WithExclusiveLock([&]() { Errors.push_back(fmt::format("File {} with expected size {} does not exist", TargetPath, ExpectedSize)); @@ -3761,7 +3831,7 @@ namespace { else { std::error_code Ec; - uint64_t SizeOnDisk = gsl::narrow<uint64_t>(std::filesystem::file_size(TargetPath, Ec)); + uint64_t SizeOnDisk = gsl::narrow<uint64_t>(FileSizeFromPath(TargetPath, Ec)); if (Ec) { ErrorLock.WithExclusiveLock([&]() { @@ -3997,9 +4067,15 @@ namespace { void FinalizeChunkSequence(const std::filesystem::path& TargetFolder, const IoHash& SequenceRawHash) { ZEN_TRACE_CPU("FinalizeChunkSequence"); - ZEN_ASSERT_SLOW(!std::filesystem::exists(GetFinalChunkedSequenceFileName(TargetFolder, SequenceRawHash))); - std::filesystem::rename(GetTempChunkedSequenceFileName(TargetFolder, SequenceRawHash), - GetFinalChunkedSequenceFileName(TargetFolder, SequenceRawHash)); + ZEN_ASSERT_SLOW(!IsFile(GetFinalChunkedSequenceFileName(TargetFolder, SequenceRawHash))); + std::error_code Ec; + RenameFile(GetTempChunkedSequenceFileName(TargetFolder, SequenceRawHash), + GetFinalChunkedSequenceFileName(TargetFolder, SequenceRawHash), + Ec); + if (Ec) + { + throw std::system_error(Ec); + } } void FinalizeChunkSequences(const std::filesystem::path& TargetFolder, @@ -4646,7 +4722,7 @@ namespace { Payload.SetDeleteOnClose(false); Payload = {}; CompressedChunkPath = ZenTempDownloadFolderPath(ZenFolderPath) / ChunkHash.ToHexString(); - std::filesystem::rename(TempBlobPath, CompressedChunkPath, Ec); + RenameFile(TempBlobPath, CompressedChunkPath, Ec); if (Ec) { CompressedChunkPath = std::filesystem::path{}; @@ -4717,7 +4793,7 @@ namespace { FilteredWrittenBytesPerSecond.Stop(); } - std::filesystem::remove(CompressedChunkPath); + RemoveFile(CompressedChunkPath); std::vector<uint32_t> CompletedSequences = CompleteChunkTargets(ChunkTargetPtrs, SequenceIndexChunksLeftToWriteCounters); @@ -4823,13 +4899,13 @@ namespace { const std::filesystem::path CacheFilePath = GetFinalChunkedSequenceFileName(CacheFolderPath, RemoteContent.ChunkedContent.SequenceRawHashes[SequenceIndex]); - ZEN_ASSERT_SLOW(std::filesystem::is_regular_file(CacheFilePath)); + ZEN_ASSERT_SLOW(IsFile(CacheFilePath)); continue; } } } - std::filesystem::remove(CacheDirContent.Files[Index]); + RemoveFileWithRetry(CacheDirContent.Files[Index]); } } @@ -4875,7 +4951,7 @@ namespace { } } } - std::filesystem::remove(BlockDirContent.Files[Index]); + RemoveFileWithRetry(BlockDirContent.Files[Index]); } } @@ -4896,7 +4972,7 @@ namespace { // const uint32_t RemotePathIndex = GetFirstPathIndexForSeqeuenceIndex(RemoteLookup, RemoteSequenceIndex); // RemoteSequenceByteCountFoundInCache += RemoteContent.RawSizes[RemotePathIndex]; const std::filesystem::path CacheFilePath = GetFinalChunkedSequenceFileName(CacheFolderPath, RemoteSequenceRawHash); - ZEN_ASSERT_SLOW(std::filesystem::is_regular_file(CacheFilePath)); + ZEN_ASSERT_SLOW(IsFile(CacheFilePath)); } else if (auto CacheChunkIt = CachedChunkHashesFound.find(RemoteSequenceRawHash); CacheChunkIt != CachedChunkHashesFound.end()) @@ -4905,14 +4981,14 @@ namespace { // const uint32_t RemotePathIndex = GetFirstPathIndexForSeqeuenceIndex(RemoteLookup, RemoteSequenceIndex); // RemoteSequenceByteCountFoundInCache += RemoteContent.RawSizes[RemotePathIndex]; const std::filesystem::path CacheFilePath = GetFinalChunkedSequenceFileName(CacheFolderPath, RemoteSequenceRawHash); - ZEN_ASSERT_SLOW(std::filesystem::is_regular_file(CacheFilePath)); + ZEN_ASSERT_SLOW(IsFile(CacheFilePath)); } else if (auto It = LocalLookup.RawHashToSequenceIndex.find(RemoteSequenceRawHash); It != LocalLookup.RawHashToSequenceIndex.end()) { const uint32_t LocalSequenceIndex = It->second; const uint32_t LocalPathIndex = GetFirstPathIndexForSeqeuenceIndex(LocalLookup, LocalSequenceIndex); - ZEN_ASSERT_SLOW(std::filesystem::is_regular_file(Path / LocalContent.Paths[LocalPathIndex])); + ZEN_ASSERT_SLOW(IsFile((Path / LocalContent.Paths[LocalPathIndex]).make_preferred())); uint64_t RawSize = LocalContent.RawSizes[LocalPathIndex]; LocalPathIndexesMatchingSequenceIndexes.push_back(LocalPathIndex); CacheMappingStats.LocalPathsMatchingSequencesCount++; @@ -5181,7 +5257,7 @@ namespace { std::filesystem::path BlockPath = ZenTempBlockFolderPath(ZenFolderPath) / BlockDescription.BlockHash.ToHexString(); - if (std::filesystem::exists(BlockPath)) + if (IsFile(BlockPath)) { CachedChunkBlockIndexes.push_back(BlockIndex); UsingCachedBlock = true; @@ -5462,7 +5538,7 @@ namespace { const IoHash& ChunkHash = RemoteContent.ChunkedContent.ChunkHashes[RemoteChunkIndex]; std::filesystem::path CompressedChunkPath = ZenTempDownloadFolderPath(ZenFolderPath) / ChunkHash.ToHexString(); - if (std::filesystem::exists(CompressedChunkPath)) + if (IsFile(CompressedChunkPath)) { IoBuffer ExistingCompressedPart = IoBufferBuilder::MakeFromFile(ExistingCompressedChunkPath); if (ExistingCompressedPart) @@ -5481,7 +5557,7 @@ namespace { else { std::error_code DummyEc; - std::filesystem::remove(CompressedChunkPath, DummyEc); + RemoveFile(CompressedChunkPath, DummyEc); } } } @@ -5543,7 +5619,7 @@ namespace { FilteredWrittenBytesPerSecond.Stop(); } - std::filesystem::remove(CompressedChunkPath); + RemoveFile(CompressedChunkPath); std::vector<uint32_t> CompletedSequences = CompleteChunkTargets(ChunkTargetPtrs, SequenceIndexChunksLeftToWriteCounters); @@ -5923,11 +5999,11 @@ namespace { DiskStats)) { std::error_code DummyEc; - std::filesystem::remove(BlockChunkPath, DummyEc); + RemoveFile(BlockChunkPath, DummyEc); throw std::runtime_error(fmt::format("Block {} is malformed", BlockDescription.BlockHash)); } WritePartsComplete++; - std::filesystem::remove(BlockChunkPath); + RemoveFile(BlockChunkPath); if (WritePartsComplete == TotalPartWriteCount) { FilteredWrittenBytesPerSecond.Stop(); @@ -6008,7 +6084,7 @@ namespace { BlockDescription.BlockHash, BlockRange.RangeStart, BlockRange.RangeLength); - std::filesystem::rename(TempBlobPath, BlockChunkPath, Ec); + RenameFile(TempBlobPath, BlockChunkPath, Ec); if (Ec) { BlockChunkPath = std::filesystem::path{}; @@ -6079,14 +6155,14 @@ namespace { DiskStats)) { std::error_code DummyEc; - std::filesystem::remove(BlockChunkPath, DummyEc); + RemoveFile(BlockChunkPath, DummyEc); throw std::runtime_error( fmt::format("Partial block {} is malformed", BlockDescription.BlockHash)); } if (!BlockChunkPath.empty()) { - std::filesystem::remove(BlockChunkPath); + RemoveFile(BlockChunkPath); } WritePartsComplete++; @@ -6180,7 +6256,7 @@ namespace { BlockBuffer = {}; BlockChunkPath = ZenTempBlockFolderPath(ZenFolderPath) / BlockDescription.BlockHash.ToHexString(); - std::filesystem::rename(TempBlobPath, BlockChunkPath, Ec); + RenameFile(TempBlobPath, BlockChunkPath, Ec); if (Ec) { BlockChunkPath = std::filesystem::path{}; @@ -6259,14 +6335,14 @@ namespace { DiskStats)) { std::error_code DummyEc; - std::filesystem::remove(BlockChunkPath, DummyEc); + RemoveFile(BlockChunkPath, DummyEc); throw std::runtime_error( fmt::format("Block {} is malformed", BlockDescription.BlockHash)); } if (!BlockChunkPath.empty()) { - std::filesystem::remove(BlockChunkPath); + RemoveFile(BlockChunkPath); } WritePartsComplete++; @@ -6398,7 +6474,7 @@ namespace { const IoHash& RawHash = LocalContent.RawHashes[LocalPathIndex]; const std::filesystem::path& LocalPath = LocalContent.Paths[LocalPathIndex]; - ZEN_ASSERT_SLOW(std::filesystem::is_regular_file(Path / LocalContent.Paths[LocalPathIndex])); + ZEN_ASSERT_SLOW(IsFile((Path / LocalContent.Paths[LocalPathIndex]).make_preferred())); if (!WipeTargetFolder) { @@ -6430,27 +6506,18 @@ namespace { if (!CachedRemoteSequences.contains(RawHash)) { // We need it - ZEN_ASSERT_SLOW(!std::filesystem::exists(CacheFilePath)); + ZEN_ASSERT_SLOW(!IsFile(CacheFilePath)); const std::filesystem::path LocalFilePath = (Path / LocalPath).make_preferred(); - std::error_code Ec; - std::filesystem::rename(LocalFilePath, CacheFilePath, Ec); - for (size_t Retries = 0; Ec && Retries < 3; Retries++) - { - Sleep(100); - std::filesystem::rename(LocalFilePath, CacheFilePath, Ec); - } - if (Ec) - { - zen::ThrowSystemError(Ec.value(), Ec.message()); - } + RenameFileWithRetry(LocalFilePath, CacheFilePath); + CachedRemoteSequences.insert(RawHash); CachedCount++; } else { // We already have it - ZEN_ASSERT_SLOW(std::filesystem::exists(CacheFilePath)); + ZEN_ASSERT_SLOW(IsFile(CacheFilePath)); SkippedCount++; } } @@ -6499,8 +6566,8 @@ namespace { for (uint32_t LocalPathIndex : RemoveLocalPathIndexes) { const std::filesystem::path LocalFilePath = (Path / LocalContent.Paths[LocalPathIndex]).make_preferred(); - SetFileReadOnly(LocalFilePath, false); - std::filesystem::remove(LocalFilePath); + SetFileReadOnlyWithRetry(LocalFilePath, false); + RemoveFileWithRetry(LocalFilePath); } } } @@ -6579,9 +6646,9 @@ namespace { std::filesystem::path TargetFilePath = (Path / TargetPath).make_preferred(); if (!RemotePathIndexToLocalPathIndex[RemotePathIndex]) { - if (std::filesystem::exists(TargetFilePath)) + if (IsFile(TargetFilePath)) { - SetFileReadOnly(TargetFilePath, false); + SetFileReadOnlyWithRetry(TargetFilePath, false); } else { @@ -6615,13 +6682,13 @@ namespace { if (auto InPlaceIt = RemotePathIndexToLocalPathIndex.find(FirstRemotePathIndex); InPlaceIt != RemotePathIndexToLocalPathIndex.end()) { - ZEN_ASSERT_SLOW(std::filesystem::exists(FirstTargetFilePath)); + ZEN_ASSERT_SLOW(IsFile(FirstTargetFilePath)); } else { - if (std::filesystem::exists(FirstTargetFilePath)) + if (IsFile(FirstTargetFilePath)) { - SetFileReadOnly(FirstTargetFilePath, false); + SetFileReadOnlyWithRetry(FirstTargetFilePath, false); } else { @@ -6634,7 +6701,7 @@ namespace { const uint32_t LocalPathIndex = InplaceIt->second; const std::filesystem::path& SourcePath = LocalContent.Paths[LocalPathIndex]; std::filesystem::path SourceFilePath = (Path / SourcePath).make_preferred(); - ZEN_ASSERT_SLOW(std::filesystem::exists(SourceFilePath)); + ZEN_ASSERT_SLOW(IsFile(SourceFilePath)); CopyFile(SourceFilePath, FirstTargetFilePath, {.EnableClone = false}); RebuildFolderStateStats.FinalizeTreeFilesCopiedCount++; @@ -6643,19 +6710,10 @@ namespace { { const std::filesystem::path CacheFilePath = GetFinalChunkedSequenceFileName(CacheFolderPath, RawHash); - ZEN_ASSERT_SLOW(std::filesystem::exists(CacheFilePath)); + ZEN_ASSERT_SLOW(IsFile(CacheFilePath)); + + RenameFileWithRetry(CacheFilePath, FirstTargetFilePath); - std::error_code Ec; - std::filesystem::rename(CacheFilePath, FirstTargetFilePath, Ec); - for (size_t Retries = 0; Ec && Retries < 3; Retries++) - { - Sleep(100); - std::filesystem::rename(CacheFilePath, FirstTargetFilePath, Ec); - } - if (Ec) - { - zen::ThrowSystemError(Ec.value(), Ec.message()); - } RebuildFolderStateStats.FinalizeTreeFilesMovedCount++; } } @@ -6685,20 +6743,20 @@ namespace { if (auto InPlaceIt = RemotePathIndexToLocalPathIndex.find(RemotePathIndex); InPlaceIt != RemotePathIndexToLocalPathIndex.end()) { - ZEN_ASSERT_SLOW(std::filesystem::exists(TargetFilePath)); + ZEN_ASSERT_SLOW(IsFile(TargetFilePath)); } else { - if (std::filesystem::exists(TargetFilePath)) + if (IsFile(TargetFilePath)) { - SetFileReadOnly(TargetFilePath, false); + SetFileReadOnlyWithRetry(TargetFilePath, false); } else { CreateDirectories(TargetFilePath.parent_path()); } - ZEN_ASSERT_SLOW(std::filesystem::exists(FirstTargetFilePath)); + ZEN_ASSERT_SLOW(IsFile(FirstTargetFilePath)); CopyFile(FirstTargetFilePath, TargetFilePath, {.EnableClone = false}); RebuildFolderStateStats.FinalizeTreeFilesCopiedCount++; } @@ -7167,7 +7225,7 @@ namespace { ChunkedFolderContent LocalContent; bool HasLocalState = false; - if (std::filesystem::is_regular_file(ZenStateFilePath(ZenFolderPath))) + if (IsFile(ZenStateFilePath(ZenFolderPath))) { try { @@ -7268,9 +7326,9 @@ namespace { { const std::filesystem::path& FilePath = PathsToCheck[PathRangeIndex]; std::filesystem::path LocalFilePath = (Path / FilePath).make_preferred(); - if (std::filesystem::exists(LocalFilePath)) + if (IsFile(LocalFilePath)) { - const uint64_t FileSize = std::filesystem::file_size(LocalFilePath); + const uint64_t FileSize = FileSizeFromPath(LocalFilePath); OutLocalFolderContent.Paths[PathRangeIndex] = FilePath; OutLocalFolderContent.RawSizes[PathRangeIndex] = FileSize; OutLocalFolderContent.Attributes[PathRangeIndex] = GetNativeFileAttributes(LocalFilePath); @@ -7502,7 +7560,7 @@ namespace { FolderContent LocalFolderContent; if (!PrimeCacheOnly) { - if (std::filesystem::is_directory(Path)) + if (IsDir(Path)) { if (!WipeTargetFolder) { @@ -7692,7 +7750,7 @@ namespace { } if (CleanDirectory(ZenTempFolder, {})) { - std::filesystem::remove(ZenTempFolder); + RemoveDirWithRetry(ZenTempFolder); } } @@ -8479,7 +8537,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (CleanDirectory(ZenFolderPath, {})) { std::error_code DummyEc; - std::filesystem::remove(ZenFolderPath, DummyEc); + RemoveDir(ZenFolderPath, DummyEc); } }); @@ -8592,7 +8650,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (CleanDirectory(ZenFolderPath, {})) { std::error_code DummyEc; - std::filesystem::remove(ZenFolderPath, DummyEc); + RemoveDir(ZenFolderPath, DummyEc); } }); @@ -8721,7 +8779,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) BuildStorageCache::Statistics StorageCacheStats; const std::filesystem::path ZenFolderPath = - m_ZenFolderPath.empty() ? (Path / ZenFolderName).make_preferred() : MakeSafeAbsolutePath(m_ZenFolderPath); + m_ZenFolderPath.empty() ? Path / ZenFolderName : MakeSafeAbsolutePath(m_ZenFolderPath); StorageInstance Storage = CreateBuildStorage(StorageStats, StorageCacheStats, ZenTempFolderPath(ZenFolderPath)); @@ -8799,7 +8857,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) BuildStorageCache::Statistics StorageCacheStats; const std::filesystem::path ZenFolderPath = - m_ZenFolderPath.empty() ? (Path / ZenFolderName).make_preferred() : MakeSafeAbsolutePath(m_ZenFolderPath); + m_ZenFolderPath.empty() ? Path / ZenFolderName : MakeSafeAbsolutePath(m_ZenFolderPath); StorageInstance Storage = CreateBuildStorage(StorageStats, StorageCacheStats, ZenTempFolderPath(ZenFolderPath)); @@ -8871,7 +8929,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) const std::filesystem::path DownloadPath = Path.parent_path() / (m_BuildPartName + "_test"); const std::filesystem::path ZenFolderPath = - m_ZenFolderPath.empty() ? (DownloadPath / ZenFolderName) : MakeSafeAbsolutePath(m_ZenFolderPath); + m_ZenFolderPath.empty() ? DownloadPath / ZenFolderName : MakeSafeAbsolutePath(m_ZenFolderPath); StorageInstance Storage = CreateBuildStorage(StorageStats, StorageCacheStats, ZenTempFolderPath(ZenFolderPath)); @@ -9000,10 +9058,10 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { Work.ScheduleWork( GetIOWorkerPool(), - [SourceSize, FilePath](std::atomic<bool>&) { + [SourceSize, FilePath = std::filesystem::path(FilePath)](std::atomic<bool>&) { if (!AbortFlag) { - bool IsReadOnly = SetFileReadOnly(FilePath, false); + bool IsReadOnly = SetFileReadOnlyWithRetry(FilePath, false); { BasicFile Source(FilePath, BasicFile::Mode::kWrite); uint64_t RangeSize = Min(SourceSize / 3, 512u * 1024u); @@ -9030,7 +9088,10 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) } break; case 1: - std::filesystem::remove(FilePath); + { + (void)SetFileReadOnlyWithRetry(FilePath, false); + RemoveFileWithRetry(FilePath); + } break; default: break; @@ -9184,7 +9245,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (CleanDirectory(ZenFolderPath, {})) { std::error_code DummyEc; - std::filesystem::remove(ZenFolderPath, DummyEc); + RemoveDir(ZenFolderPath, DummyEc); } }); @@ -9240,7 +9301,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (CleanDirectory(ZenFolderPath, {})) { std::error_code DummyEc; - std::filesystem::remove(ZenFolderPath, DummyEc); + RemoveDir(ZenFolderPath, DummyEc); } }); |