From: Joel Rosdahl Date: Wed, 1 Jul 2020 14:28:28 +0000 (+0200) Subject: Extract copy_raw_file into Util::clone_hard_link_or_copy_file X-Git-Tag: v4.0~349 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=024e9fa12e68ac800fe1d498c24e19f4ca47f8d1;p=thirdparty%2Fccache.git Extract copy_raw_file into Util::clone_hard_link_or_copy_file --- diff --git a/src/Util.cpp b/src/Util.cpp index 488631fc0..e0897f4a7 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -107,6 +107,36 @@ change_extension(string_view path, string_view new_ext) return std::string(without_ext).append(new_ext.data(), new_ext.length()); } +bool +clone_hard_link_or_copy_file(const Context& ctx, + const std::string& source, + const std::string& dest, + bool via_tmp_file) +{ + if (ctx.config.file_clone()) { + cc_log("Cloning %s to %s", source.c_str(), dest.c_str()); + if (clone_file(source.c_str(), dest.c_str(), via_tmp_file)) { + return true; + } + cc_log("Failed to clone: %s", strerror(errno)); + } + if (ctx.config.hard_link()) { + unlink(dest.c_str()); + cc_log("Hard linking %s to %s", source.c_str(), dest.c_str()); + int ret = link(source.c_str(), dest.c_str()); + if (ret == 0) { + if (chmod(dest.c_str(), 0444) != 0) { + cc_log("Failed to chmod: %s", strerror(errno)); + } + return true; + } + cc_log("Failed to hard link: %s", strerror(errno)); + } + + cc_log("Copying %s to %s", source.c_str(), dest.c_str()); + return copy_file(source.c_str(), dest.c_str(), via_tmp_file); +} + size_t common_dir_prefix_length(string_view dir, string_view path) { diff --git a/src/Util.hpp b/src/Util.hpp index a879080f5..59e0852a2 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -83,6 +83,14 @@ big_endian_to_int(const uint8_t* buffer, uint8_t& value) std::string change_extension(nonstd::string_view path, nonstd::string_view new_ext); +// Clone, hard link or copy a file from `source` to `dest` depending on settings +// in `ctx`. If cloning or hard linking cannot and should not be done the file +// will be copied instead. Returns true if successful otherwise false. +bool clone_hard_link_or_copy_file(const Context& ctx, + const std::string& source, + const std::string& dest, + bool via_tmp_file); + // Compute the length of the longest directory path that is common to paths // `dir` (a directory) and `path` (any path). size_t common_dir_prefix_length(nonstd::string_view dir, diff --git a/src/result.cpp b/src/result.cpp index ad858a873..da90d7527 100644 --- a/src/result.cpp +++ b/src/result.cpp @@ -219,36 +219,6 @@ get_raw_file_path(const std::string& result_path_in_cache, entry_number); } -static bool -copy_raw_file(const Context& ctx, - const std::string& source, - const std::string& dest, - bool to_cache) -{ - if (ctx.config.file_clone()) { - cc_log("Cloning %s to %s", source.c_str(), dest.c_str()); - if (clone_file(source.c_str(), dest.c_str(), to_cache)) { - return true; - } - cc_log("Failed to clone: %s", strerror(errno)); - } - if (ctx.config.hard_link()) { - unlink(dest.c_str()); - cc_log("Hard linking %s to %s", source.c_str(), dest.c_str()); - int ret = link(source.c_str(), dest.c_str()); - if (ret == 0) { - if (chmod(dest.c_str(), 0444) != 0) { - cc_log("Failed to chmod: %s", strerror(errno)); - } - return true; - } - cc_log("Failed to hard link: %s", strerror(errno)); - } - - cc_log("Copying %s to %s", source.c_str(), dest.c_str()); - return copy_file(source.c_str(), dest.c_str(), to_cache); -} - static void read_raw_file_entry(const Context& ctx, CacheEntryReader& reader, @@ -292,7 +262,8 @@ read_raw_file_entry(const Context& ctx, cc_log("Not copying to /dev/null"); } else { const auto& dest_path = it->second; - if (!copy_raw_file(ctx, raw_path, dest_path, false)) { + if (!Util::clone_hard_link_or_copy_file( + ctx, raw_path, dest_path, false)) { throw Error( fmt::format("Failed to copy raw file {} to {}", raw_path, dest_path)); } @@ -422,7 +393,7 @@ write_raw_file_entry(Context& ctx, auto raw_file = get_raw_file_path(result_path_in_cache, entry_number); auto old_stat = Stat::stat(raw_file); - if (!copy_raw_file(ctx, source_path, raw_file, true)) { + if (!Util::clone_hard_link_or_copy_file(ctx, source_path, raw_file, true)) { throw Error( fmt::format("Failed to store {} as raw file {}", source_path, raw_file)); }