From a0b52e170866b00cd27e243ffd5599be91152395 Mon Sep 17 00:00:00 2001 From: Maksim Denisov Date: Fri, 5 Apr 2024 09:49:02 +0200 Subject: LargeBlobs: Make LocalCAS::BlobPathNoSync public to fix synchronization of executable files during splitting. --- src/buildtool/storage/large_object_cas.tpp | 15 ++++++++++++--- src/buildtool/storage/local_cas.hpp | 20 ++++++++++++-------- 2 files changed, 24 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/buildtool/storage/large_object_cas.tpp b/src/buildtool/storage/large_object_cas.tpp index ef720822..db2f46a9 100644 --- a/src/buildtool/storage/large_object_cas.tpp +++ b/src/buildtool/storage/large_object_cas.tpp @@ -125,9 +125,18 @@ auto LargeObjectCAS::Split( } // Get path to the file: - auto file_path = IsTreeObject(kType) - ? local_cas_.TreePath(digest) - : local_cas_.BlobPath(digest, /*is_executable=*/false); + std::optional file_path; + if constexpr (IsTreeObject(kType)) { + file_path = local_cas_.TreePath(digest); + } + else { + // Avoid synchronization between file/executable storages: + static constexpr bool kIsExec = IsExecutableObject(kType); + file_path = local_cas_.BlobPathNoSync(digest, kIsExec); + file_path = file_path ? file_path + : local_cas_.BlobPathNoSync(digest, not kIsExec); + } + if (not file_path) { return LargeObjectError{ LargeObjectErrorCode::FileNotFound, diff --git a/src/buildtool/storage/local_cas.hpp b/src/buildtool/storage/local_cas.hpp index 64dc5082..892946de 100644 --- a/src/buildtool/storage/local_cas.hpp +++ b/src/buildtool/storage/local_cas.hpp @@ -108,6 +108,18 @@ class LocalCAS { return path ? path : TrySyncBlob(digest, is_executable); } + /// \brief Obtain blob path from digest with x-bit. + /// Synchronization between file/executable CAS is skipped. + /// \param digest Digest of the blob to lookup. + /// \param is_executable Lookup blob with executable permissions. + /// \returns Path to the blob if found or nullopt otherwise. + [[nodiscard]] auto BlobPathNoSync(bazel_re::Digest const& digest, + bool is_executable) const noexcept + -> std::optional { + return is_executable ? cas_exec_.BlobPath(digest) + : cas_file_.BlobPath(digest); + } + /// \brief Split a blob into chunks. /// \param digest The digest of a blob to be split. /// \returns Digests of the parts of the large object or an @@ -280,14 +292,6 @@ class LocalCAS { return ObjectCAS::kDefaultExists; } - /// \brief Get blob path without sync between file/executable CAS. - [[nodiscard]] auto BlobPathNoSync(bazel_re::Digest const& digest, - bool is_executable) const noexcept - -> std::optional { - return is_executable ? cas_exec_.BlobPath(digest) - : cas_file_.BlobPath(digest); - } - /// \brief Try to sync blob between file CAS and executable CAS. /// \param digest Blob digest. /// \param to_executable Sync direction. -- cgit v1.2.3