mirror of
https://git.savannah.gnu.org/git/guix.git
synced 2025-01-18 21:46:35 +01:00
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:
parent
79154f0a09
commit
7033c7692c
3 changed files with 17 additions and 8 deletions
|
@ -392,7 +392,14 @@ bool LocalStore::isActiveTempFile(const GCState & state,
|
||||||
void LocalStore::deleteGarbage(GCState & state, const Path & path)
|
void LocalStore::deleteGarbage(GCState & state, const Path & path)
|
||||||
{
|
{
|
||||||
unsigned long long bytesFreed;
|
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;
|
state.results.bytesFreed += bytesFreed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
checkInterrupt();
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
|
||||||
struct stat st = lstat(path);
|
struct stat st = lstat(path);
|
||||||
#endif
|
#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;
|
bytesFreed += st.st_size;
|
||||||
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
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))
|
for (auto & i : readDirectory(path))
|
||||||
_deletePath(path + "/" + i.name, bytesFreed);
|
_deletePath(path + "/" + i.name, bytesFreed, linkThreshold);
|
||||||
}
|
}
|
||||||
#undef st_mode
|
#undef st_mode
|
||||||
#undef st_size
|
#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,
|
startNest(nest, lvlDebug,
|
||||||
format("recursively deleting path `%1%'") % path);
|
format("recursively deleting path `%1%'") % path);
|
||||||
bytesFreed = 0;
|
bytesFreed = 0;
|
||||||
_deletePath(path, bytesFreed);
|
_deletePath(path, bytesFreed, linkThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -94,10 +94,12 @@ void writeLine(int fd, string s);
|
||||||
|
|
||||||
/* Delete a path; i.e., in the case of a directory, it is deleted
|
/* 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
|
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);
|
||||||
|
|
||||||
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. */
|
/* Create a temporary directory. */
|
||||||
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
|
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
|
||||||
|
|
Loading…
Reference in a new issue