From 993e9ebd07246b0f1a4201eed180c6f74c4d2f13 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sun, 27 Feb 2022 10:49:29 +0000 Subject: [PATCH] freebsd: use copy_file_range() in uv_fs_sendfile() (#3496) Use copy_file_range() on FreeBSD 13 and above. --- src/unix/freebsd.c | 15 +++++++++++++++ src/unix/fs.c | 11 +++++++++++ src/unix/internal.h | 10 ++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/unix/freebsd.c b/src/unix/freebsd.c index 170b897e..658ff262 100644 --- a/src/unix/freebsd.c +++ b/src/unix/freebsd.c @@ -287,3 +287,18 @@ int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { return errno = ENOSYS, -1; #endif } + +ssize_t +uv__fs_copy_file_range(int fd_in, + off_t* off_in, + int fd_out, + off_t* off_out, + size_t len, + unsigned int flags) +{ +#if __FreeBSD__ >= 13 && !defined(__DragonFly__) + return copy_file_range(fd_in, off_in, fd_out, off_out, len, flags); +#else + return errno = ENOSYS, -1; +#endif +} diff --git a/src/unix/fs.c b/src/unix/fs.c index 99ea7465..b3211ec1 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c @@ -1075,6 +1075,17 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) { */ #if defined(__FreeBSD__) || defined(__DragonFly__) +#if defined(__FreeBSD__) + off_t off; + + off = req->off; + r = uv__fs_copy_file_range(in_fd, &off, out_fd, NULL, req->bufsml[0].len, 0); + if (r >= 0) { + r = off - req->off; + req->off = off; + return r; + } +#endif len = 0; r = sendfile(in_fd, out_fd, req->off, req->bufsml[0].len, NULL, &len, 0); #elif defined(__FreeBSD_kernel__) diff --git a/src/unix/internal.h b/src/unix/internal.h index ec46f385..2fa903e9 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -359,5 +359,15 @@ size_t strnlen(const char* s, size_t maxlen); #endif #endif +#if defined(__FreeBSD__) +ssize_t +uv__fs_copy_file_range(int fd_in, + off_t* off_in, + int fd_out, + off_t* off_out, + size_t len, + unsigned int flags); +#endif + #endif /* UV_UNIX_INTERNAL_H_ */