Browse Source

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'.
version-0.12.0
Ludovic Courtès 6 years ago
parent
commit
12b6c951cf
No known key found for this signature in database GPG Key ID: 90B11993D9AEBB5
  1. 23
      nix/libstore/optimise-store.cc

23
nix/libstore/optimise-store.cc

@ -148,10 +148,23 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
inodeHash.insert(st.st_ino);
return;
}
if (errno != EEXIST)
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. */
printMsg(lvlInfo, format("cannot link `%1%' to `%2%': %m") % linkPath % path);
return;
default:
throw SysError(format("cannot link `%1%' to `%2%'") % linkPath % path);
/* Fall through if another process created ‘linkPath’ before
we did. */
}
}
/* Yes! We've seen a file with the same contents. Replace the
@ -195,8 +208,8 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath);
return;
}
throw SysError(format("cannot link `%1%' to `%2%'") % tempLink % linkPath);
}
throw SysError(format("cannot link `%1%' to `%2%'") % tempLink % linkPath);
}
/* Atomically replace the old file with the new hard link. */
if (rename(tempLink.c_str(), path.c_str()) == -1) {

Loading…
Cancel
Save