aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-03-16 09:19:57 +0100
committerGitHub <noreply@github.com>2022-03-16 09:19:57 +0100
commita53c1dc96d059aea6d67726f44c37c39c95404e3 (patch)
treec41d110073e6995fa2ca38c190e1eae4a363d26e /src
parent7b0eb9eaf299b913fa780d8cb82b7f18757a5b5e (diff)
parent6b1872312f1b505334acb67b8bf7990b0a0fdbd8 (diff)
Merge pull request #6245 from trofi/fix-nix-store-gc-limit-auto-optimise-store
nix store gc: account for auto-optimised store
Diffstat (limited to 'src')
-rw-r--r--src/libstore/gc.cc3
-rw-r--r--src/libutil/util.cc25
2 files changed, 25 insertions, 3 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 024da66c1..69755bd19 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -841,7 +841,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
if (unlink(path.c_str()) == -1)
throw SysError("deleting '%1%'", path);
- results.bytesFreed += st.st_size;
+ /* Do not accound for deleted file here. Rely on deletePath()
+ accounting. */
}
struct stat st;
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 9f13d5f02..70eaf4f9c 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -406,8 +406,29 @@ static void _deletePath(int parentfd, const Path & path, uint64_t & bytesFreed)
throw SysError("getting status of '%1%'", path);
}
- if (!S_ISDIR(st.st_mode) && st.st_nlink == 1)
- bytesFreed += st.st_size;
+ if (!S_ISDIR(st.st_mode)) {
+ /* We are about to delete a file. Will it likely free space? */
+
+ switch (st.st_nlink) {
+ /* Yes: last link. */
+ case 1:
+ bytesFreed += st.st_size;
+ break;
+ /* Maybe: yes, if 'auto-optimise-store' or manual optimisation
+ was performed. Instead of checking for real let's assume
+ it's an optimised file and space will be freed.
+
+ In worst case we will double count on freed space for files
+ with exactly two hardlinks for unoptimised packages.
+ */
+ case 2:
+ bytesFreed += st.st_size;
+ break;
+ /* No: 3+ links. */
+ default:
+ break;
+ }
+ }
if (S_ISDIR(st.st_mode)) {
/* Make the directory accessible. */