aboutsummaryrefslogtreecommitdiff
path: root/nix
diff options
context:
space:
mode:
authorMarius Bakke <mbakke@fastmail.com>2020-01-15 00:09:46 +0100
committerMarius Bakke <mbakke@fastmail.com>2020-01-15 00:09:46 +0100
commit3cfe76bec06fbd8bb7e7cb3387866fefbcad674f (patch)
treeb66780d205fb50fd44d0bbb38f5df99cf3167ba1 /nix
parentec836b46bf52a5f86c61f50e3a2c3330a7ee3665 (diff)
parent574a71a7a9668aa184661c58e1f18a4d4fccd792 (diff)
downloadpatches-3cfe76bec06fbd8bb7e7cb3387866fefbcad674f.tar
patches-3cfe76bec06fbd8bb7e7cb3387866fefbcad674f.tar.gz
Merge branch 'master' into core-updates
Diffstat (limited to 'nix')
-rw-r--r--nix/libstore/gc.cc18
-rw-r--r--nix/libutil/util.cc10
-rw-r--r--nix/libutil/util.hh6
3 files changed, 22 insertions, 12 deletions
diff --git a/nix/libstore/gc.cc b/nix/libstore/gc.cc
index 29b75aa875..77d7fa2dc7 100644
--- a/nix/libstore/gc.cc
+++ b/nix/libstore/gc.cc
@@ -392,7 +392,14 @@ bool LocalStore::isActiveTempFile(const GCState & state,
void LocalStore::deleteGarbage(GCState & state, const Path & path)
{
unsigned long long bytesFreed;
- deletePath(path, bytesFreed);
+
+ /* When deduplication is on, store items always have at least two links:
+ the one at PATH, and one in /gnu/store/.links. In that case, increase
+ bytesFreed when PATH has two or fewer links. */
+ size_t linkThreshold =
+ (settings.autoOptimiseStore && isStorePath(path)) ? 2 : 1;
+
+ deletePath(path, bytesFreed, linkThreshold);
state.results.bytesFreed += bytesFreed;
}
@@ -419,13 +426,14 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
}
if (state.options.maxFreed != ULLONG_MAX) {
- double fraction = state.results.bytesFreed + size
- / state.options.maxFreed;
+ auto freed = state.results.bytesFreed + state.bytesInvalidated;
+ double fraction = ((double) freed) / (double) state.options.maxFreed;
unsigned int percentage = (fraction > 1. ? 1. : fraction) * 100.;
printMsg(lvlInfo, format("[%1%%%] deleting '%2%'") % percentage % path);
} else {
- size_t total = (state.results.bytesFreed + size) / (1024 * 1024);
- printMsg(lvlInfo, format("[%1% MiB] deleting '%2%'") % total % path);
+ auto freed = state.results.bytesFreed + state.bytesInvalidated;
+ freed /= 1024ULL * 1024ULL;
+ printMsg(lvlInfo, format("[%1% MiB] deleting '%2%'") % freed % path);
}
state.results.paths.insert(path);
diff --git a/nix/libutil/util.cc b/nix/libutil/util.cc
index faba3789df..fb2dfad1f7 100644
--- a/nix/libutil/util.cc
+++ b/nix/libutil/util.cc
@@ -305,7 +305,7 @@ void writeLine(int fd, string s)
}
-static void _deletePath(const Path & path, unsigned long long & bytesFreed)
+static void _deletePath(const Path & path, unsigned long long & bytesFreed, size_t linkThreshold)
{
checkInterrupt();
@@ -324,7 +324,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
struct stat st = lstat(path);
#endif
- if (!S_ISDIR(st.st_mode) && st.st_nlink == 1)
+ if (!S_ISDIR(st.st_mode) && st.st_nlink <= linkThreshold)
bytesFreed += st.st_size;
if (S_ISDIR(st.st_mode)) {
@@ -335,7 +335,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
}
for (auto & i : readDirectory(path))
- _deletePath(path + "/" + i.name, bytesFreed);
+ _deletePath(path + "/" + i.name, bytesFreed, linkThreshold);
}
#undef st_mode
#undef st_size
@@ -353,12 +353,12 @@ void deletePath(const Path & path)
}
-void deletePath(const Path & path, unsigned long long & bytesFreed)
+void deletePath(const Path & path, unsigned long long & bytesFreed, size_t linkThreshold)
{
startNest(nest, lvlDebug,
format("recursively deleting path `%1%'") % path);
bytesFreed = 0;
- _deletePath(path, bytesFreed);
+ _deletePath(path, bytesFreed, linkThreshold);
}
diff --git a/nix/libutil/util.hh b/nix/libutil/util.hh
index 6a6e07c478..9e3c14bdd4 100644
--- a/nix/libutil/util.hh
+++ b/nix/libutil/util.hh
@@ -94,10 +94,12 @@ void writeLine(int fd, string s);
/* Delete a path; i.e., in the case of a directory, it is deleted
recursively. Don't use this at home, kids. The second variant
- returns the number of bytes and blocks freed. */
+ returns the number of bytes and blocks freed, and 'linkThreshold' denotes
+ the number of links under which a file is accounted for in 'bytesFreed'. */
void deletePath(const Path & path);
-void deletePath(const Path & path, unsigned long long & bytesFreed);
+void deletePath(const Path & path, unsigned long long & bytesFreed,
+ size_t linkThreshold = 1);
/* Create a temporary directory. */
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",