diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2022-03-16 09:19:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-16 09:19:57 +0100 |
commit | a53c1dc96d059aea6d67726f44c37c39c95404e3 (patch) | |
tree | c41d110073e6995fa2ca38c190e1eae4a363d26e /src | |
parent | 7b0eb9eaf299b913fa780d8cb82b7f18757a5b5e (diff) | |
parent | 6b1872312f1b505334acb67b8bf7990b0a0fdbd8 (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.cc | 3 | ||||
-rw-r--r-- | src/libutil/util.cc | 25 |
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. */ |