Only use renameFile where needed

In most places the fallback to copying isn’t needed and can actually be
bad, so we’d rather not transparently fallback
This commit is contained in:
Théophane Hufschmitt 2022-04-13 14:19:42 +02:00
parent d71d9e9fbf
commit 90f9680733
3 changed files with 19 additions and 6 deletions

View file

@ -1430,7 +1430,7 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, std::string_view name
writeFile(realPath, dumpSource); writeFile(realPath, dumpSource);
} else { } else {
/* Move the temporary path we restored above. */ /* Move the temporary path we restored above. */
renameFile(tempPath, realPath); moveFile(tempPath, realPath);
} }
/* For computing the nar hash. In recursive SHA-256 mode, this /* For computing the nar hash. In recursive SHA-256 mode, this

View file

@ -54,7 +54,6 @@ void setWriteTime(const fs::path & p, const struct stat & st)
.tv_sec = st.st_mtime, .tv_sec = st.st_mtime,
.tv_usec = 0, .tv_usec = 0,
}; };
warn("Setting the mtime of %s to %d", p.c_str(), st.st_mtim.tv_sec);
if (lutimes(p.c_str(), times) != 0) if (lutimes(p.c_str(), times) != 0)
throw SysError("changing modification time of '%s'", p); throw SysError("changing modification time of '%s'", p);
} }
@ -92,14 +91,19 @@ void copy(const fs::directory_entry & from, const fs::path & to, bool andDelete)
void renameFile(const Path & oldName, const Path & newName) void renameFile(const Path & oldName, const Path & newName)
{ {
fs::rename(oldName, newName);
}
void moveFile(const Path & oldName, const Path & newName)
{
try {
renameFile(oldName, newName);
} catch (fs::filesystem_error & e) {
auto oldPath = fs::path(oldName); auto oldPath = fs::path(oldName);
auto newPath = fs::path(newName); auto newPath = fs::path(newName);
try {
fs::rename(oldPath, newPath);
} catch (fs::filesystem_error & e) {
if (e.code().value() == EXDEV) { if (e.code().value() == EXDEV) {
fs::remove(newPath); fs::remove(newPath);
warn("Copying %s to %s", oldName, newName); warn("Cant rename %s as %s, copying instead", oldName, newName);
copy(fs::directory_entry(oldPath), newPath, true); copy(fs::directory_entry(oldPath), newPath, true);
} }
} }

View file

@ -170,6 +170,15 @@ void replaceSymlink(const Path & target, const Path & link,
void renameFile(const Path & src, const Path & dst); void renameFile(const Path & src, const Path & dst);
/**
* Similar to 'renameFile', but fallback to a copy+remove if `src` and `dst`
* are on a different filesystem.
*
* Beware that this might not be atomic because of the copy that happens behind
* the scenes
*/
void moveFile(const Path & src, const Path & dst);
/* Wrappers arount read()/write() that read/write exactly the /* Wrappers arount read()/write() that read/write exactly the
requested number of bytes. */ requested number of bytes. */