aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2017-05-09 23:25:01 -0700
committerZac Medico <zmedico@gentoo.org>2017-05-14 11:07:44 -0700
commita3c87da25dc1944e6b7720e304318ae5474dff95 (patch)
tree97eadb709d1d7ff9552de2d7bbffdaa8b1b7521b /src
parentfile_copy: replace loff_t with off_t for portability (bug 617778) (diff)
downloadportage-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.c13
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;
}
}