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'.
This commit is contained in:
Ludovic Courtès 2016-11-14 13:33:36 +01:00 committed by Eelco Dolstra
parent b8d9616af1
commit ccb1022022

View file

@ -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. */