diff options
author | Michael Raskin <7c6f434c@mail.ru> | 2009-05-04T08·10+0000 |
---|---|---|
committer | Michael Raskin <7c6f434c@mail.ru> | 2009-05-04T08·10+0000 |
commit | 098cb9d233ff7e1568b55e88dacf52e1dc8eebab (patch) | |
tree | eb700b94450c279a81689c004721ac6c579e969d | |
parent | c710fe540e3763d821eab74621b43d9422cb7e92 (diff) |
Add an ftruncate call paired with fallocate to play safe with some FSes (namely, BtrFS fallocate sets file size to allocated size, i.e. multiple of block size)
-rw-r--r-- | src/libutil/archive.cc | 8 | ||||
-rw-r--r-- | src/libutil/archive.hh | 1 |
2 files changed, 9 insertions, 0 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index 8f100da4c3ed..4899fbaa4580 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -181,6 +181,8 @@ static void parseContents(ParseSink & sink, Source & source, const Path & path) left -= n; } + sink.finalizeContents(size); + readPadding(size, source); } @@ -310,6 +312,12 @@ struct RestoreSink : ParseSink writeFull(fd, data, len); } + void finalizeContents(unsigned long long size) + { + errno = ftruncate(fd, size); + if (errno) throw SysError(format("truncating file to its allocated length of %1% bytes") % size); + } + void createSymlink(const Path & path, const string & target) { Path p = dstPath + path; diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh index fff62031397c..f358a2a6be17 100644 --- a/src/libutil/archive.hh +++ b/src/libutil/archive.hh @@ -64,6 +64,7 @@ struct ParseSink virtual void isExecutable() { }; virtual void preallocateContents(unsigned long long size) { }; virtual void receiveContents(unsigned char * data, unsigned int len) { }; + virtual void finalizeContents(unsigned long long size) { }; virtual void createSymlink(const Path & path, const string & target) { }; }; |