Enable copy_file_range when it is available.
Fallback to read+write when copy_file_range failed, as both fd_in and fd_out must refer to regular files. Signed-off-by: LongPing Wei <weilongping@huawei.com>
This commit is contained in:
parent
7459474343
commit
613db35596
@ -629,20 +629,25 @@ int get_block_device_size(int fd, unsigned long long* size)
|
||||
long long sendfile_len(int in, int out, long long bytes, long long *consumed)
|
||||
{
|
||||
long long total = 0, len, ww;
|
||||
int copy_file_range = CFG_TOYBOX_COPYFILERANGE;
|
||||
|
||||
if (consumed) *consumed = 0;
|
||||
if (in<0) return 0;
|
||||
while (bytes != total) {
|
||||
ww = 0;
|
||||
len = bytes-total;
|
||||
if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf);
|
||||
|
||||
errno = 0;
|
||||
#if CFG_TOYBOX_COPYFILERANGE
|
||||
len = copy_file_range(in, 0, out, 0, bytes, 0);
|
||||
#else
|
||||
ww = len = read(in, libbuf, len);
|
||||
#endif
|
||||
if (copy_file_range) {
|
||||
if (bytes<0) len = INT_MAX;
|
||||
len = syscall(__NR_copy_file_range, in, 0, out, 0, len, 0);
|
||||
if (len < 0 && errno == EINVAL)
|
||||
copy_file_range = 0;
|
||||
}
|
||||
if (!copy_file_range) {
|
||||
if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf);
|
||||
ww = len = read(in, libbuf, len);
|
||||
}
|
||||
if (len<1 && errno==EAGAIN) continue;
|
||||
if (len<1) break;
|
||||
if (consumed) *consumed += len;
|
||||
|
@ -104,7 +104,7 @@ EOF
|
||||
probesymbol TOYBOX_COPYFILERANGE << EOF
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
int main(void) { copyfilerange(0, 0, 1, 0, 123, 0); }
|
||||
int main(void) { syscall(__NR_copy_file_range, 0, 0, 1, 0, 123, 0); }
|
||||
EOF
|
||||
probesymbol TOYBOX_HASTIMERS << EOF
|
||||
#include <signal.h>
|
||||
|
Loading…
Reference in New Issue
Block a user