aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/optimise-store.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-06-21 07:55:38 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-06-21 07:55:38 +0000
commitbf87cc44b4484df74388b526c89884fea166ab7f (patch)
tree18a9a0e77d2e2a027eac094b3cdb43d6dd988cf4 /src/libstore/optimise-store.cc
parentd1f6c0cbe39b509545f809f08cbd580859f38e34 (diff)
parentb57189174f6e11c3e9e0f7c65c08a72f689fe194 (diff)
* Sync with the trunk.
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 d15049201..3ed54e24d 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);