Delete non-directory valid paths right away
It's unlikely that rename() is faster than unlink() on a regular file or symlink, so don't bother.
This commit is contained in:
parent
117670be57
commit
480dda0e42
|
@ -433,8 +433,13 @@ void LocalStore::deleteGarbage(GCState & state, const Path & path)
|
||||||
bool LocalStore::tryToDelete(GCState & state, const Path & path)
|
bool LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||||
{
|
{
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
if (!pathExists(path)) return true;
|
struct stat st;
|
||||||
|
if (lstat(path.c_str(), &st)) {
|
||||||
|
if (errno == ENOENT) return true;
|
||||||
|
throw SysError(format("getting status of %1%") % path);
|
||||||
|
}
|
||||||
|
|
||||||
if (state.deleted.find(path) != state.deleted.end()) return true;
|
if (state.deleted.find(path) != state.deleted.end()) return true;
|
||||||
if (state.live.find(path) != state.live.end()) return false;
|
if (state.live.find(path) != state.live.end()) return false;
|
||||||
|
|
||||||
|
@ -514,21 +519,27 @@ bool LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||||
/* The path is garbage, so delete it. */
|
/* The path is garbage, so delete it. */
|
||||||
if (shouldDelete(state.options.action)) {
|
if (shouldDelete(state.options.action)) {
|
||||||
|
|
||||||
|
/* If it's a valid path that's not a regular file or symlink,
|
||||||
|
invalidate it, rename it, and schedule it for deletion.
|
||||||
|
The renaming is to ensure that later (when we're not
|
||||||
|
holding the global GC lock) we can delete the path without
|
||||||
|
being afraid that the path has become alive again.
|
||||||
|
Otherwise delete it right away. */
|
||||||
if (isValidPath(path)) {
|
if (isValidPath(path)) {
|
||||||
/* If it's a valid path, invalidate it, rename it, and
|
if (S_ISDIR(st.st_mode)) {
|
||||||
schedule it for deletion. The renaming is to ensure
|
printMsg(lvlInfo, format("invalidating `%1%'") % path);
|
||||||
that later (when we're not holding the global GC lock)
|
// Estimate the amount freed using the narSize field.
|
||||||
we can delete the path without being afraid that the
|
state.bytesInvalidated += queryPathInfo(path).narSize;
|
||||||
path has become alive again. */
|
invalidatePathChecked(path);
|
||||||
printMsg(lvlInfo, format("invalidating `%1%'") % path);
|
makeMutable(path.c_str());
|
||||||
// Estimate the amount freed using the narSize field.
|
Path tmp = (format("%1%-gc-%2%") % path % getpid()).str();
|
||||||
state.bytesInvalidated += queryPathInfo(path).narSize;
|
if (rename(path.c_str(), tmp.c_str()))
|
||||||
invalidatePathChecked(path);
|
throw SysError(format("unable to rename `%1%' to `%2%'") % path % tmp);
|
||||||
Path tmp = (format("%1%-gc-%2%") % path % getpid()).str();
|
state.invalidated.insert(tmp);
|
||||||
makeMutable(path.c_str());
|
} else {
|
||||||
if (rename(path.c_str(), tmp.c_str()))
|
invalidatePathChecked(path);
|
||||||
throw SysError(format("unable to rename `%1%' to `%2%'") % path % tmp);
|
deleteGarbage(state, path);
|
||||||
state.invalidated.insert(tmp);
|
}
|
||||||
} else
|
} else
|
||||||
deleteGarbage(state, path);
|
deleteGarbage(state, path);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue