aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/gc.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-03-26 20:56:30 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-03-26 20:56:30 +0200
commit480dda0e42e69be47434be5bce95be950bdb59b5 (patch)
tree2429d3ec9b8fa8b36a8b18bb337642aeab2d3fd4 /src/libstore/gc.cc
parent117670be570d775a18e4e35db3dae00abc24f729 (diff)
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.
Diffstat (limited to 'src/libstore/gc.cc')
-rw-r--r--src/libstore/gc.cc43
1 files changed, 27 insertions, 16 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 65c8dc210..56cb97d87 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -433,8 +433,13 @@ void LocalStore::deleteGarbage(GCState & state, const Path & path)
bool LocalStore::tryToDelete(GCState & state, const Path & path)
{
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.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. */
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 it's a valid path, 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. */
- printMsg(lvlInfo, format("invalidating `%1%'") % path);
- // Estimate the amount freed using the narSize field.
- state.bytesInvalidated += queryPathInfo(path).narSize;
- invalidatePathChecked(path);
- Path tmp = (format("%1%-gc-%2%") % path % getpid()).str();
- makeMutable(path.c_str());
- if (rename(path.c_str(), tmp.c_str()))
- throw SysError(format("unable to rename `%1%' to `%2%'") % path % tmp);
- state.invalidated.insert(tmp);
+ if (S_ISDIR(st.st_mode)) {
+ printMsg(lvlInfo, format("invalidating `%1%'") % path);
+ // Estimate the amount freed using the narSize field.
+ state.bytesInvalidated += queryPathInfo(path).narSize;
+ invalidatePathChecked(path);
+ makeMutable(path.c_str());
+ Path tmp = (format("%1%-gc-%2%") % path % getpid()).str();
+ if (rename(path.c_str(), tmp.c_str()))
+ throw SysError(format("unable to rename `%1%' to `%2%'") % path % tmp);
+ state.invalidated.insert(tmp);
+ } else {
+ invalidatePathChecked(path);
+ deleteGarbage(state, path);
+ }
} else
deleteGarbage(state, path);