diff options
author | Zac Medico <zmedico@gentoo.org> | 2017-05-09 23:25:01 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2017-05-14 11:07:44 -0700 |
commit | a3c87da25dc1944e6b7720e304318ae5474dff95 (patch) | |
tree | 97eadb709d1d7ff9552de2d7bbffdaa8b1b7521b /src | |
parent | file_copy: replace loff_t with off_t for portability (bug 617778) (diff) | |
download | portage-a3c87da25dc1944e6b7720e304318ae5474dff95.tar.gz portage-a3c87da25dc1944e6b7720e304318ae5474dff95.tar.bz2 portage-a3c87da25dc1944e6b7720e304318ae5474dff95.zip |
file_copy: fix lseek offset after EINTR (bug 618086)
Fix the lseek offset for the plain read/write loop to account
for buffered data that has not been written to to the output
file yet (due to previous interruption by EINTR). This code
only affects Linux 2.6.32 and earlier (newer kernels use
copy_file_range or sendfile).
X-Gentoo-bug: 618086
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=618086
Acked-by: Brian Dolbec <dolsen@gentoo.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/portage_util_file_copy_reflink_linux.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/src/portage_util_file_copy_reflink_linux.c b/src/portage_util_file_copy_reflink_linux.c index 2fb17a0f5..4be9e0568 100644 --- a/src/portage_util_file_copy_reflink_linux.c +++ b/src/portage_util_file_copy_reflink_linux.c @@ -323,12 +323,14 @@ _reflink_linux_file_copy(PyObject *self, PyObject *args) if (buf == NULL) { error = errno; - /* For the read call, the fd_in file offset must be - * exactly equal to offset_out. Use lseek to ensure - * correct state, in case an EINTR retry caused it to - * get out of sync somewhow. + /* For the read call, the fd_in file offset must be exactly + * equal to offset_out + buf_bytes, where buf_bytes is the + * amount of buffered data that has not been written to + * to the output file yet. Use lseek to ensure correct state, + * in case an EINTR retry caused it to get out of sync + * somewhow. */ - } else if (lseek(fd_in, offset_out, SEEK_SET) < 0) { + } else if (lseek(fd_in, offset_out + buf_bytes, SEEK_SET) < 0) { error = errno; } else { while (1) { @@ -345,6 +347,7 @@ _reflink_linux_file_copy(PyObject *self, PyObject *args) } else if (buf_bytes < 0) { error = errno; + buf_bytes = 0; break; } } |