about summary refs log tree commit diff
path: root/src/libstore/optimise-store.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-06-04T13·56+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-06-04T13·56+0000
commit07ca66cf242eef3c7a6396e9353e48037034498b (patch)
tree95330ef20e23c75a1d01946a8fe0c68910a6df6c /src/libstore/optimise-store.cc
parent1ab67cf437704f51f514e2ab7856e3c87f3c88b1 (diff)
* Applied a patch from David Brown to prevent `nix-store --optimise'
  from failing on rename() on BtrFS.

Diffstat (limited to 'src/libstore/optimise-store.cc')
-rw-r--r--src/libstore/optimise-store.cc16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index d15049201ea4..3ed54e24d773 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -119,9 +119,23 @@ static void hashAndLink(bool dryRun, HashToPath & hashToPath,
             }
 
             /* Atomically replace the old file with the new hard link. */
-            if (rename(tempLink.c_str(), path.c_str()) == -1)
+            if (rename(tempLink.c_str(), path.c_str()) == -1) {
+                if (errno == EMLINK) {
+                    /* Some filesystems generate too many links on the
+                       rename, rather than on the original link.
+                       (Probably it temporarily increases the st_nlink
+                       field before decreasing it again.) */
+                    printMsg(lvlInfo, format("`%1%' has maximum number of links") % prevPath.first);
+                    hashToPath[hash] = std::pair<Path, ino_t>(path, st.st_ino);
+
+                    /* Unlink the temp link. */
+                    if (unlink(tempLink.c_str()) == -1)
+                        printMsg(lvlError, format("unable to unlink `%1%'") % tempLink);
+                    return;
+                }
                 throw SysError(format("cannot rename `%1%' to `%2%'")
                     % tempLink % path);
+            }
         } else
             printMsg(lvlTalkative, format("would link `%1%' to `%2%'") % path % prevPath.first);