mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8264744: (fs) Use file cloning in Linux version of Files::copy method
Reviewed-by: alanb
This commit is contained in:
parent
85d4b49151
commit
da596182a4
4 changed files with 76 additions and 16 deletions
|
@ -35,9 +35,14 @@
|
|||
|
||||
#include <sys/sendfile.h>
|
||||
#include <fcntl.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "sun_nio_fs_LinuxFileSystem.h"
|
||||
|
||||
typedef ssize_t copy_file_range_func(int, loff_t*, int, loff_t*, size_t,
|
||||
unsigned int);
|
||||
static copy_file_range_func* my_copy_file_range_func = NULL;
|
||||
|
||||
#define RESTARTABLE(_cmd, _result) do { \
|
||||
do { \
|
||||
_result = _cmd; \
|
||||
|
@ -52,6 +57,14 @@ static void throwUnixException(JNIEnv* env, int errnum) {
|
|||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_LinuxFileSystem_init
|
||||
(JNIEnv* env, jclass this)
|
||||
{
|
||||
my_copy_file_range_func =
|
||||
(copy_file_range_func*) dlsym(RTLD_DEFAULT, "copy_file_range");
|
||||
}
|
||||
|
||||
// Copy all bytes from src to dst, within the kernel if possible,
|
||||
// and return zero, otherwise return the appropriate status code.
|
||||
//
|
||||
|
@ -72,7 +85,33 @@ Java_sun_nio_fs_LinuxFileSystem_directCopy0
|
|||
const size_t count = cancel != NULL ?
|
||||
1048576 : // 1 MB to give cancellation a chance
|
||||
0x7ffff000; // maximum number of bytes that sendfile() can transfer
|
||||
|
||||
ssize_t bytes_sent;
|
||||
if (my_copy_file_range_func != NULL) {
|
||||
do {
|
||||
RESTARTABLE(my_copy_file_range_func(src, NULL, dst, NULL, count, 0),
|
||||
bytes_sent);
|
||||
if (bytes_sent < 0) {
|
||||
switch (errno) {
|
||||
case EINVAL:
|
||||
case ENOSYS:
|
||||
case EXDEV:
|
||||
// ignore and try sendfile()
|
||||
break;
|
||||
default:
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Copy failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
}
|
||||
if (cancel != NULL && *cancel != 0) {
|
||||
throwUnixException(env, ECANCELED);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
} while (bytes_sent > 0);
|
||||
|
||||
if (bytes_sent == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
RESTARTABLE(sendfile64(dst, src, NULL, count), bytes_sent);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue