8264744: (fs) Use file cloning in Linux version of Files::copy method
Reviewed-by: alanb
This commit is contained in:
parent
85d4b49151
commit
da596182a4
@ -161,6 +161,8 @@ class LinuxFileSystem extends UnixFileSystem {
|
||||
|
||||
// -- native methods --
|
||||
|
||||
private static native void init();
|
||||
|
||||
/**
|
||||
* Copies data between file descriptors {@code src} and {@code dst} using
|
||||
* a platform-specific function or system call possibly having kernel
|
||||
@ -179,4 +181,9 @@ class LinuxFileSystem extends UnixFileSystem {
|
||||
private static native int directCopy0(int dst, int src,
|
||||
long addressToPollForCancel)
|
||||
throws UnixException;
|
||||
|
||||
static {
|
||||
jdk.internal.loader.BootLoader.loadLibrary("nio");
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -71,6 +71,13 @@ class BsdFileSystem extends UnixFileSystem {
|
||||
return SupportedFileFileAttributeViewsHolder.supportedFileAttributeViews;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int directCopy(int dst, int src, long addressToPollForCancel)
|
||||
throws UnixException
|
||||
{
|
||||
return directCopy0(dst, src, addressToPollForCancel);
|
||||
}
|
||||
|
||||
@Override
|
||||
void copyNonPosixAttributes(int ofd, int nfd) {
|
||||
UnixUserDefinedFileAttributeView.copyExtendedAttributes(ofd, nfd);
|
||||
@ -102,22 +109,11 @@ class BsdFileSystem extends UnixFileSystem {
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
FileStore getFileStore(UnixMountEntry entry) throws IOException {
|
||||
return new BsdFileStore(this, entry);
|
||||
}
|
||||
|
||||
// --- file copying ---
|
||||
|
||||
@Override
|
||||
int directCopy(int dst, int src, long addressToPollForCancel)
|
||||
throws UnixException
|
||||
{
|
||||
return directCopy0(dst, src, addressToPollForCancel);
|
||||
}
|
||||
|
||||
// -- native methods --
|
||||
|
||||
private static native int directCopy0(int dst, int src,
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4313887 6838333 6917021 7006126 6950237 8006645 8201407 8267820
|
||||
* @bug 4313887 6838333 6917021 7006126 6950237 8006645 8201407 8264744 8267820
|
||||
* @summary Unit test for java.nio.file.Files copy and move methods (use -Dseed=X to set PRNG seed)
|
||||
* @library .. /test/lib
|
||||
* @build jdk.test.lib.Platform jdk.test.lib.RandomFactory
|
||||
@ -59,15 +59,33 @@ public class CopyAndMove {
|
||||
testCopyFileToFile(dir1, dir1, TestUtil.supportsLinks(dir1));
|
||||
testMove(dir1, dir1, TestUtil.supportsLinks(dir1));
|
||||
|
||||
// Different directories. Use test.dir if possible as it might be
|
||||
// a different volume/file system and so improve test coverage.
|
||||
// Use test.dir to define second directory if possible as it might
|
||||
// be a different volume/file system and so improve test coverage.
|
||||
String testDir = System.getProperty("test.dir", ".");
|
||||
Path dir2 = TestUtil.createTemporaryDirectory(testDir);
|
||||
FileStore fileStore2 = getFileStore(dir2);
|
||||
printDirInfo("dir2", dir2, fileStore2);
|
||||
|
||||
// If different type (format) from dir1, re-do same directory tests
|
||||
if (!fileStore1.type().equals(fileStore2.type())) {
|
||||
try {
|
||||
testPosixAttributes =
|
||||
fileStore2.supportsFileAttributeView("posix");
|
||||
testCopyFileToFile(dir2, dir2, TestUtil.supportsLinks(dir2));
|
||||
testMove(dir2, dir2, TestUtil.supportsLinks(dir2));
|
||||
} finally {
|
||||
TestUtil.removeAll(dir2);
|
||||
}
|
||||
}
|
||||
|
||||
// Different directories.
|
||||
try {
|
||||
// Recreate dir2 if it was removed above
|
||||
if (notExists(dir2)) {
|
||||
dir2 = TestUtil.createTemporaryDirectory(testDir);
|
||||
}
|
||||
boolean testSymbolicLinks =
|
||||
TestUtil.supportsLinks(dir1) && TestUtil.supportsLinks(dir2);
|
||||
FileStore fileStore2 = getFileStore(dir2);
|
||||
printDirInfo("dir2", dir2, fileStore2);
|
||||
testPosixAttributes = fileStore1.supportsFileAttributeView("posix") &&
|
||||
fileStore2.supportsFileAttributeView("posix");
|
||||
testCopyFileToFile(dir1, dir2, testSymbolicLinks);
|
||||
|
Loading…
Reference in New Issue
Block a user