guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: guix-commits
Subject: 05/12: daemon: Account for deleted store files when deduplication is on.
Date: Sat, 11 Jan 2020 18:22:39 -0500 (EST)

civodul pushed a commit to branch master
in repository guix.

commit 7033c7692ccbbbad8f7b9952015de071a5588e87
Author: Ludovic Courtès <address@hidden>
AuthorDate: Sat Jan 11 18:46:23 2020 +0100

    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.
---
 nix/libstore/gc.cc  |  9 ++++++++-
 nix/libutil/util.cc | 10 +++++-----
 nix/libutil/util.hh |  6 ++++--
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/nix/libstore/gc.cc b/nix/libstore/gc.cc
index 29b75aa..5043963 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;
 }
 
diff --git a/nix/libutil/util.cc b/nix/libutil/util.cc
index faba378..fb2dfad 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 6a6e07c..9e3c14b 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",



reply via email to

[Prev in Thread] Current Thread [Next in Thread]