about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2016-11-14T12·33+0100
committerEelco Dolstra <edolstra@gmail.com>2016-11-14T12·35+0100
commitccb10220228250066e8dc487894fb1e11b338c48 (patch)
tree88c2a5c4b52781eccc87d150edf9d58c018ea768
parentb8d9616af141ff669c94308da3b40f8be824cc83 (diff)
daemon: Do not error out when deduplication fails due to ENOSPC.
This solves a problem whereby if /gnu/store/.links had enough entries,
ext4's directory index would be full, leading to link(2) returning
ENOSPC.

* nix/libstore/optimise-store.cc (LocalStore::optimisePath_): Upon
ENOSPC from link(2), print a message and return instead of throwing a
'SysError'.
-rw-r--r--src/libstore/optimise-store.cc24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index 1bf8b7d83bbc..2fd9a9bb8787 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -148,10 +148,24 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
             inodeHash.insert(st.st_ino);
             return;
         }
-        if (errno != EEXIST)
-            throw SysError(format("cannot link ‘%1%’ to ‘%2%’") % linkPath % path);
-        /* Fall through if another process created ‘linkPath’ before
-           we did. */
+
+        switch (errno) {
+        case EEXIST:
+            /* Fall through if another process created ‘linkPath’ before
+               we did. */
+            break;
+
+        case ENOSPC:
+            /* On ext4, that probably means the directory index is
+               full.  When that happens, it's fine to ignore it: we
+               just effectively disable deduplication of this
+               file.  */
+            printInfo("cannot link ‘%s’ to ‘%s’: %m", linkPath, path);
+            return;
+
+        default:
+            throw SysError("cannot link ‘%1%’ to ‘%2%’", linkPath, path);
+        }
     }
 
     /* Yes!  We've seen a file with the same contents.  Replace the
@@ -195,7 +209,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
                 printInfo(format("‘%1%’ has maximum number of links") % linkPath);
             return;
         }
-        throw SysError(format("cannot link ‘%1%’ to ‘%2%’") % tempLink % linkPath);
+        throw SysError("cannot link ‘%1%’ to ‘%2%’", tempLink, linkPath);
     }
 
     /* Atomically replace the old file with the new hard link. */