1 |
commit: a3c87da25dc1944e6b7720e304318ae5474dff95 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed May 10 06:25:01 2017 +0000 |
4 |
Commit: Brian Dolbec <dolsen <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun May 14 18:07:44 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=a3c87da2 |
7 |
|
8 |
file_copy: fix lseek offset after EINTR (bug 618086) |
9 |
|
10 |
Fix the lseek offset for the plain read/write loop to account |
11 |
for buffered data that has not been written to to the output |
12 |
file yet (due to previous interruption by EINTR). This code |
13 |
only affects Linux 2.6.32 and earlier (newer kernels use |
14 |
copy_file_range or sendfile). |
15 |
|
16 |
X-Gentoo-bug: 618086 |
17 |
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=618086 |
18 |
Acked-by: Brian Dolbec <dolsen <AT> gentoo.org> |
19 |
|
20 |
src/portage_util_file_copy_reflink_linux.c | 13 ++++++++----- |
21 |
1 file changed, 8 insertions(+), 5 deletions(-) |
22 |
|
23 |
diff --git a/src/portage_util_file_copy_reflink_linux.c b/src/portage_util_file_copy_reflink_linux.c |
24 |
index 2fb17a0f5..4be9e0568 100644 |
25 |
--- a/src/portage_util_file_copy_reflink_linux.c |
26 |
+++ b/src/portage_util_file_copy_reflink_linux.c |
27 |
@@ -323,12 +323,14 @@ _reflink_linux_file_copy(PyObject *self, PyObject *args) |
28 |
if (buf == NULL) { |
29 |
error = errno; |
30 |
|
31 |
- /* For the read call, the fd_in file offset must be |
32 |
- * exactly equal to offset_out. Use lseek to ensure |
33 |
- * correct state, in case an EINTR retry caused it to |
34 |
- * get out of sync somewhow. |
35 |
+ /* For the read call, the fd_in file offset must be exactly |
36 |
+ * equal to offset_out + buf_bytes, where buf_bytes is the |
37 |
+ * amount of buffered data that has not been written to |
38 |
+ * to the output file yet. Use lseek to ensure correct state, |
39 |
+ * in case an EINTR retry caused it to get out of sync |
40 |
+ * somewhow. |
41 |
*/ |
42 |
- } else if (lseek(fd_in, offset_out, SEEK_SET) < 0) { |
43 |
+ } else if (lseek(fd_in, offset_out + buf_bytes, SEEK_SET) < 0) { |
44 |
error = errno; |
45 |
} else { |
46 |
while (1) { |
47 |
@@ -345,6 +347,7 @@ _reflink_linux_file_copy(PyObject *self, PyObject *args) |
48 |
|
49 |
} else if (buf_bytes < 0) { |
50 |
error = errno; |
51 |
+ buf_bytes = 0; |
52 |
break; |
53 |
} |
54 |
} |