about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorwmertens <Wout.Mertens@gmail.com>2014-05-10T13·53+0200
committerwmertens <Wout.Mertens@gmail.com>2014-05-10T13·53+0200
commita84f503d863fd77de9b6ecf149399c2ca7642b75 (patch)
treeea6d6053aea32d5667b8686e50e118119f3b8969 /src
parentaa9b1cf48e6482a74dcc19e6aef1d8236b57abe4 (diff)
Shortcut already-hardlinked files
If an inode in the Nix store has more than 1 link, it probably means that it was linked into .links/ by us. If so, skip.

There's a possibility that something else hardlinked the file, so it would be nice to be able to override this.

Also, by looking at the number of hardlinks for each of the files in .links/, you can get deduplication numbers and space savings.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/optimise-store.cc11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index d833f3aa05b5..1b81f64078b4 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -71,6 +71,16 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path)
         return;
     }
 
+    stats.totalFiles++;
+
+    /* If a store inode has 2 or more links we presume that it was
+       already linked by us */
+    /* TODO: allow overriding this behavior */
+    if (st.st_nlink > 1) {
+        printMsg(lvlDebug, format("`%1%' is already linked, with %2% other file(s).") % path % (st.st_nlink - 2));
+        return;
+    }
+
     /* Hash the file.  Note that hashPath() returns the hash over the
        NAR serialisation, which includes the execute bit on the file.
        Thus, executable and non-executable files with the same
@@ -81,7 +91,6 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path)
        contents of the symlink (i.e. the result of readlink()), not
        the contents of the target (which may not even exist). */
     Hash hash = hashPath(htSHA256, path).first;
-    stats.totalFiles++;
     printMsg(lvlDebug, format("`%1%' has hash `%2%'") % path % printHash(hash));
 
     /* Check if this is a known hash. */