aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/gc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/gc.cc')
-rw-r--r--src/libstore/gc.cc32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 1355702f8..88b7bec32 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -425,10 +425,9 @@ bool LocalStore::isActiveTempFile(const GCState & state,
void LocalStore::deleteGarbage(GCState & state, const Path & path)
{
printMsg(lvlInfo, format("deleting `%1%'") % path);
- unsigned long long bytesFreed, blocksFreed;
- deletePathWrapped(path, bytesFreed, blocksFreed);
+ unsigned long long bytesFreed;
+ deletePathWrapped(path, bytesFreed);
state.results.bytesFreed += bytesFreed;
- state.results.blocksFreed += blocksFreed;
}
@@ -550,7 +549,7 @@ bool LocalStore::tryToDelete(GCState & state, const Path & path)
} else
deleteGarbage(state, path);
- if (state.options.maxFreed && state.results.bytesFreed + state.bytesInvalidated > state.options.maxFreed) {
+ if (state.results.bytesFreed + state.bytesInvalidated > state.options.maxFreed) {
printMsg(lvlInfo, format("deleted or invalidated more than %1% bytes; stopping") % state.options.maxFreed);
throw GCLimitReached();
}
@@ -576,11 +575,13 @@ bool LocalStore::tryToDelete(GCState & state, const Path & path)
safely deleted. FIXME: race condition with optimisePath(): we
might see a link count of 1 just before optimisePath() increases
the link count. */
-void LocalStore::removeUnusedLinks()
+void LocalStore::removeUnusedLinks(const GCState & state)
{
AutoCloseDir dir = opendir(linksDir.c_str());
if (!dir) throw SysError(format("opening directory `%1%'") % linksDir);
+ long long actualSize = 0, unsharedSize = 0;
+
struct dirent * dirent;
while (errno = 0, dirent = readdir(dir)) {
checkInterrupt();
@@ -592,13 +593,28 @@ void LocalStore::removeUnusedLinks()
if (lstat(path.c_str(), &st) == -1)
throw SysError(format("statting `%1%'") % path);
- if (st.st_nlink != 1) continue;
+ if (st.st_nlink != 1) {
+ unsigned long long size = st.st_blocks * 512ULL;
+ actualSize += size;
+ unsharedSize += (st.st_nlink - 1) * size;
+ continue;
+ }
printMsg(lvlTalkative, format("deleting unused link `%1%'") % path);
if (unlink(path.c_str()) == -1)
throw SysError(format("deleting `%1%'") % path);
+
+ state.results.bytesFreed += st.st_blocks * 512;
}
+
+ struct stat st;
+ if (stat(linksDir.c_str(), &st) == -1)
+ throw SysError(format("statting `%1%'") % linksDir);
+ long long overhead = st.st_blocks * 512ULL;
+
+ printMsg(lvlInfo, format("note: currently hard linking saves %.2f MiB")
+ % ((unsharedSize - actualSize - overhead) / (1024.0 * 1024.0)));
}
@@ -660,7 +676,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
throw Error(format("cannot delete path `%1%' since it is still alive") % *i);
}
- } else {
+ } else if (options.maxFreed > 0) {
if (shouldDelete(state.options.action))
printMsg(lvlError, format("deleting garbage..."));
@@ -718,7 +734,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
/* Clean up the links directory. */
printMsg(lvlError, format("deleting unused links..."));
- removeUnusedLinks();
+ removeUnusedLinks(state);
}