Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] file_copy: use sendfile return value to measure bytes copied (bug 635126)
Date: Mon, 23 Oct 2017 02:19:30
Message-Id: 20171023021703.250265-1-zmedico@gentoo.org
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

Replies