daemon: Account for deleted store files when deduplication is on.

Previously, a store item that is a regular file would not be accounted
for in the 'bytesFreed' value computed by 'deletePath' because its
'st_nlink' count would always be >= 2.  This commit fixes that.

* nix/libutil/util.hh (deletePath): Add optional 'linkThreshold' argument.
* nix/libutil/util.cc (_deletePath): Add 'linkThreshold' argument and
honor it.  Pass it down in recursive call.
(deletePath): Add 'linkThreshold' and honor it.
* nix/libstore/gc.cc (LocalStore::deleteGarbage): Pass 'linkThreshold'
argument to 'deletePath', with a value of 2 when PATH is a store item
and deduplication is on.
This commit is contained in:
Ludovic Courtès 2020-01-11 18:46:23 +01:00
parent 79154f0a09
commit 7033c7692c
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
3 changed files with 17 additions and 8 deletions

View file

@ -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);
}