commit: a3c87da25dc1944e6b7720e304318ae5474dff95 Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Wed May 10 06:25:01 2017 +0000 Commit: Brian Dolbec <dolsen <AT> gentoo <DOT> org> CommitDate: Sun May 14 18:07:44 2017 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=a3c87da2
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 <AT> gentoo.org> src/portage_util_file_copy_reflink_linux.c | 13 ++++++++----- 1 file 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; } }