1 |
The sendfile *offset parameter refers to the input file offest, so |
2 |
it cannot be used in the same way as the copy_file_range *off_out |
3 |
parameter. Therefore, add sf_wrapper function which implements the |
4 |
*off_out behavior for sendfile. |
5 |
|
6 |
Bug: https://bugs.gentoo.org/635126 |
7 |
--- |
8 |
src/portage_util_file_copy_reflink_linux.c | 34 ++++++++++++++++++++++++------ |
9 |
1 file changed, 28 insertions(+), 6 deletions(-) |
10 |
|
11 |
diff --git a/src/portage_util_file_copy_reflink_linux.c b/src/portage_util_file_copy_reflink_linux.c |
12 |
index 4be9e0568..5bfa1cd8f 100644 |
13 |
--- a/src/portage_util_file_copy_reflink_linux.c |
14 |
+++ b/src/portage_util_file_copy_reflink_linux.c |
15 |
@@ -56,7 +56,7 @@ initreflink_linux(void) |
16 |
|
17 |
/** |
18 |
* cfr_wrapper - A copy_file_range syscall wrapper function, having a |
19 |
- * function signature that is compatible with sendfile. |
20 |
+ * function signature that is compatible with sf_wrapper. |
21 |
* @fd_out: output file descriptor |
22 |
* @fd_in: input file descriptor |
23 |
* @off_out: offset of the output file |
24 |
@@ -79,6 +79,28 @@ cfr_wrapper(int fd_out, int fd_in, off_t *off_out, size_t len) |
25 |
} |
26 |
|
27 |
/** |
28 |
+ * sf_wrapper - A sendfile wrapper function, having a function signature |
29 |
+ * that is compatible with cfr_wrapper. |
30 |
+ * @fd_out: output file descriptor |
31 |
+ * @fd_in: input file descriptor |
32 |
+ * @off_out: offset of the output file |
33 |
+ * @len: number of bytes to copy between the file descriptors |
34 |
+ * |
35 |
+ * Return: Number of bytes written to out_fd on success, -1 on failure |
36 |
+ * (errno is set appropriately). |
37 |
+ */ |
38 |
+static ssize_t |
39 |
+sf_wrapper(int fd_out, int fd_in, off_t *off_out, size_t len) |
40 |
+{ |
41 |
+ ssize_t ret; |
42 |
+ ret = sendfile(fd_out, fd_in, NULL, len); |
43 |
+ if (ret > 0) |
44 |
+ (*off_out) += ret; |
45 |
+ return ret; |
46 |
+} |
47 |
+ |
48 |
+ |
49 |
+/** |
50 |
* do_lseek_data - Adjust file offsets to the next location containing |
51 |
* data, creating sparse empty blocks in the output file as needed. |
52 |
* @fd_in: input file descriptor |
53 |
@@ -250,7 +272,7 @@ _reflink_linux_file_copy(PyObject *self, PyObject *args) |
54 |
* syscall is not available (less than Linux 4.5). |
55 |
*/ |
56 |
error = 0; |
57 |
- copyfunc = sendfile; |
58 |
+ copyfunc = sf_wrapper; |
59 |
copyfunc_ret = copyfunc(fd_out, |
60 |
fd_in, |
61 |
&offset_out, |
62 |
@@ -293,10 +315,10 @@ _reflink_linux_file_copy(PyObject *self, PyObject *args) |
63 |
error = errno; |
64 |
} else { |
65 |
while (offset_out < stat_in.st_size) { |
66 |
- copyfunc_ret = sendfile(fd_out, |
67 |
- fd_in, |
68 |
- &offset_out, |
69 |
- stat_in.st_size - offset_out); |
70 |
+ copyfunc_ret = sf_wrapper(fd_out, |
71 |
+ fd_in, |
72 |
+ &offset_out, |
73 |
+ stat_in.st_size - offset_out); |
74 |
|
75 |
if (copyfunc_ret < 0) { |
76 |
error = errno; |
77 |
-- |
78 |
2.13.5 |