1 |
Fix the lseek offset for the plain read/write loop to account |
2 |
for buffered data that has not been written to to the output |
3 |
file yet (due to previous interruption by EINTR). This code |
4 |
only affects Linux 2.6.32 and earlier (newer kernels use |
5 |
copy_file_range or sendfile). |
6 |
|
7 |
X-Gentoo-bug: 618086 |
8 |
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=618086 |
9 |
--- |
10 |
src/portage_util_file_copy_reflink_linux.c | 13 ++++++++----- |
11 |
1 file changed, 8 insertions(+), 5 deletions(-) |
12 |
|
13 |
diff --git a/src/portage_util_file_copy_reflink_linux.c b/src/portage_util_file_copy_reflink_linux.c |
14 |
index 2fb17a0..4be9e05 100644 |
15 |
--- a/src/portage_util_file_copy_reflink_linux.c |
16 |
+++ b/src/portage_util_file_copy_reflink_linux.c |
17 |
@@ -323,12 +323,14 @@ _reflink_linux_file_copy(PyObject *self, PyObject *args) |
18 |
if (buf == NULL) { |
19 |
error = errno; |
20 |
|
21 |
- /* For the read call, the fd_in file offset must be |
22 |
- * exactly equal to offset_out. Use lseek to ensure |
23 |
- * correct state, in case an EINTR retry caused it to |
24 |
- * get out of sync somewhow. |
25 |
+ /* For the read call, the fd_in file offset must be exactly |
26 |
+ * equal to offset_out + buf_bytes, where buf_bytes is the |
27 |
+ * amount of buffered data that has not been written to |
28 |
+ * to the output file yet. Use lseek to ensure correct state, |
29 |
+ * in case an EINTR retry caused it to get out of sync |
30 |
+ * somewhow. |
31 |
*/ |
32 |
- } else if (lseek(fd_in, offset_out, SEEK_SET) < 0) { |
33 |
+ } else if (lseek(fd_in, offset_out + buf_bytes, SEEK_SET) < 0) { |
34 |
error = errno; |
35 |
} else { |
36 |
while (1) { |
37 |
@@ -345,6 +347,7 @@ _reflink_linux_file_copy(PyObject *self, PyObject *args) |
38 |
|
39 |
} else if (buf_bytes < 0) { |
40 |
error = errno; |
41 |
+ buf_bytes = 0; |
42 |
break; |
43 |
} |
44 |
} |
45 |
-- |
46 |
2.10.2 |