diff options
author | Marius Bakke <mbakke@fastmail.com> | 2020-01-15 00:09:46 +0100 |
---|---|---|
committer | Marius Bakke <mbakke@fastmail.com> | 2020-01-15 00:09:46 +0100 |
commit | 3cfe76bec06fbd8bb7e7cb3387866fefbcad674f (patch) | |
tree | b66780d205fb50fd44d0bbb38f5df99cf3167ba1 /nix | |
parent | ec836b46bf52a5f86c61f50e3a2c3330a7ee3665 (diff) | |
parent | 574a71a7a9668aa184661c58e1f18a4d4fccd792 (diff) | |
download | patches-3cfe76bec06fbd8bb7e7cb3387866fefbcad674f.tar patches-3cfe76bec06fbd8bb7e7cb3387866fefbcad674f.tar.gz |
Merge branch 'master' into core-updates
Diffstat (limited to 'nix')
-rw-r--r-- | nix/libstore/gc.cc | 18 | ||||
-rw-r--r-- | nix/libutil/util.cc | 10 | ||||
-rw-r--r-- | nix/libutil/util.hh | 6 |
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", |