aboutsummaryrefslogtreecommitdiff
path: root/paludis/fs_merger.cc
diff options
context:
space:
mode:
Diffstat (limited to 'paludis/fs_merger.cc')
-rw-r--r--paludis/fs_merger.cc23
1 files changed, 23 insertions, 0 deletions
diff --git a/paludis/fs_merger.cc b/paludis/fs_merger.cc
index 4205c3b6e..57413f51e 100644
--- a/paludis/fs_merger.cc
+++ b/paludis/fs_merger.cc
@@ -47,10 +47,15 @@
#include <unordered_map>
#include "config.h"
+
#ifdef HAVE_XATTRS
# include <sys/xattr.h>
#endif
+#ifdef HAVE_FALLOCATE
+# include <linux/falloc.h>
+#endif
+
using namespace paludis;
#include <paludis/fs_merger-se.cc>
@@ -390,6 +395,24 @@ FSMerger::install_file(const FSPath & src, const FSPath & dst_dir, const std::st
throw FSMergerError("Cannot fchmod '" + stringify(dst) + "': " + stringify(::strerror(errno)));
try_to_copy_xattrs(src, output_fd, result);
+#ifdef HAVE_FALLOCATE
+ if (0 != ::fallocate(output_fd, FALLOC_FL_KEEP_SIZE, 0, src_stat.file_size()))
+ switch (errno)
+ {
+ case EOPNOTSUPP:
+ case ENOSYS:
+ break;
+
+ case ENOSPC:
+ throw FSMergerError("fallocate '" + stringify(dst) + "' returned " + stringify(::strerror(errno)));
+
+ default:
+ Log::get_instance()->message("merger.file.fallocate_failed", ll_debug, lc_context) <<
+ "fallocate '" + stringify(dst) + "' returned " + stringify(::strerror(errno));
+ break;
+ }
+#endif
+
char buf[4096];
ssize_t count;
while ((count = read(input_fd, buf, 4096)) > 0)