8202261: (fc) FileChannel.map and RandomAccessFile.setLength should not preallocate space
Reviewed-by: coffeys
diff --git a/jdk/make/mapfiles/libnio/mapfile-linux b/jdk/make/mapfiles/libnio/mapfile-linux
index c38d3e5..30f795f 100644
--- a/jdk/make/mapfiles/libnio/mapfile-linux
+++ b/jdk/make/mapfiles/libnio/mapfile-linux
@@ -56,12 +56,11 @@
Java_sun_nio_ch_FileChannelImpl_close0;
Java_sun_nio_ch_FileChannelImpl_initIDs;
Java_sun_nio_ch_FileChannelImpl_map0;
- Java_sun_nio_ch_FileChannelImpl_position0;
Java_sun_nio_ch_FileChannelImpl_transferTo0;
Java_sun_nio_ch_FileChannelImpl_unmap0;
- Java_sun_nio_ch_FileDispatcherImpl_allocate0;
Java_sun_nio_ch_FileDispatcherImpl_close0;
Java_sun_nio_ch_FileDispatcherImpl_closeIntFD;
+ Java_sun_nio_ch_FileDispatcherImpl_seek0;
Java_sun_nio_ch_FileDispatcherImpl_force0;
Java_sun_nio_ch_FileDispatcherImpl_init;
Java_sun_nio_ch_FileDispatcherImpl_lock0;
diff --git a/jdk/make/mapfiles/libnio/mapfile-macosx b/jdk/make/mapfiles/libnio/mapfile-macosx
index 38eabf6..ac8a572 100644
--- a/jdk/make/mapfiles/libnio/mapfile-macosx
+++ b/jdk/make/mapfiles/libnio/mapfile-macosx
@@ -39,12 +39,11 @@
Java_sun_nio_ch_FileChannelImpl_close0;
Java_sun_nio_ch_FileChannelImpl_initIDs;
Java_sun_nio_ch_FileChannelImpl_map0;
- Java_sun_nio_ch_FileChannelImpl_position0;
Java_sun_nio_ch_FileChannelImpl_transferTo0;
Java_sun_nio_ch_FileChannelImpl_unmap0;
- Java_sun_nio_ch_FileDispatcherImpl_allocate0;
Java_sun_nio_ch_FileDispatcherImpl_close0;
Java_sun_nio_ch_FileDispatcherImpl_closeIntFD;
+ Java_sun_nio_ch_FileDispatcherImpl_seek0;
Java_sun_nio_ch_FileDispatcherImpl_force0;
Java_sun_nio_ch_FileDispatcherImpl_init;
Java_sun_nio_ch_FileDispatcherImpl_lock0;
diff --git a/jdk/make/mapfiles/libnio/mapfile-solaris b/jdk/make/mapfiles/libnio/mapfile-solaris
index 4ea153d..72f1315 100644
--- a/jdk/make/mapfiles/libnio/mapfile-solaris
+++ b/jdk/make/mapfiles/libnio/mapfile-solaris
@@ -44,12 +44,11 @@
Java_sun_nio_ch_FileChannelImpl_close0;
Java_sun_nio_ch_FileChannelImpl_initIDs;
Java_sun_nio_ch_FileChannelImpl_map0;
- Java_sun_nio_ch_FileChannelImpl_position0;
Java_sun_nio_ch_FileChannelImpl_transferTo0;
Java_sun_nio_ch_FileChannelImpl_unmap0;
- Java_sun_nio_ch_FileDispatcherImpl_allocate0;
Java_sun_nio_ch_FileDispatcherImpl_close0;
Java_sun_nio_ch_FileDispatcherImpl_closeIntFD;
+ Java_sun_nio_ch_FileDispatcherImpl_seek0;
Java_sun_nio_ch_FileDispatcherImpl_force0;
Java_sun_nio_ch_FileDispatcherImpl_init;
Java_sun_nio_ch_FileDispatcherImpl_lock0;
diff --git a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
index d1a0f3d..f786f69 100644
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
@@ -261,7 +261,7 @@
return 0;
do {
// in append-mode then position is advanced to end before writing
- p = (append) ? nd.size(fd) : position0(fd, -1);
+ p = (append) ? nd.size(fd) : nd.seek(fd, -1);
} while ((p == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(p);
} finally {
@@ -285,7 +285,7 @@
if (!isOpen())
return null;
do {
- p = position0(fd, newPosition);
+ p = nd.seek(fd, newPosition);
} while ((p == IOStatus.INTERRUPTED) && isOpen());
return this;
} finally {
@@ -345,7 +345,7 @@
// get current position
do {
- p = position0(fd, -1);
+ p = nd.seek(fd, -1);
} while ((p == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
@@ -364,7 +364,7 @@
if (p > newSize)
p = newSize;
do {
- rp = position0(fd, p);
+ rp = nd.seek(fd, p);
} while ((rp == IOStatus.INTERRUPTED) && isOpen());
return this;
} finally {
@@ -906,7 +906,7 @@
}
int rv;
do {
- rv = nd.allocate(fd, position + size);
+ rv = nd.truncate(fd, position + size);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
if (!isOpen())
return null;
@@ -1217,11 +1217,6 @@
private native long transferTo0(FileDescriptor src, long position,
long count, FileDescriptor dst);
- // Sets or reports this file's position
- // If offset is -1, the current position is returned
- // otherwise the position is set to offset
- private native long position0(FileDescriptor fd, long offset);
-
// Caches fieldIDs
private static native long initIDs();
diff --git a/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java b/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java
index 85ba029..f30731a 100644
--- a/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java
+++ b/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java
@@ -36,12 +36,17 @@
public static final int RET_EX_LOCK = 1; // Obtained exclusive lock
public static final int INTERRUPTED = 2; // Request interrupted
+ /**
+ * Sets or reports this file's position
+ * If offset is -1, the current position is returned
+ * otherwise the position is set to offset.
+ */
+ abstract long seek(FileDescriptor fd, long offset) throws IOException;
+
abstract int force(FileDescriptor fd, boolean metaData) throws IOException;
abstract int truncate(FileDescriptor fd, long size) throws IOException;
- abstract int allocate(FileDescriptor fd, long size) throws IOException;
-
abstract long size(FileDescriptor fd) throws IOException;
abstract int lock(FileDescriptor fd, boolean blocking, long pos, long size,
diff --git a/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java b/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
index d0b4531..d49c9bf 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java
@@ -72,6 +72,10 @@
return writev0(fd, address, len);
}
+ long seek(FileDescriptor fd, long offset) throws IOException {
+ return seek0(fd, offset);
+ }
+
int force(FileDescriptor fd, boolean metaData) throws IOException {
return force0(fd, metaData);
}
@@ -80,10 +84,6 @@
return truncate0(fd, size);
}
- int allocate(FileDescriptor fd, long size) throws IOException {
- return allocate0(fd, size);
- }
-
long size(FileDescriptor fd) throws IOException {
return size0(fd);
}
@@ -143,10 +143,10 @@
static native int force0(FileDescriptor fd, boolean metaData)
throws IOException;
- static native int truncate0(FileDescriptor fd, long size)
+ static native long seek0(FileDescriptor fd, long size)
throws IOException;
- static native int allocate0(FileDescriptor fd, long size)
+ static native int truncate0(FileDescriptor fd, long size)
throws IOException;
static native long size0(FileDescriptor fd) throws IOException;
diff --git a/jdk/src/solaris/native/java/io/io_util_md.c b/jdk/src/solaris/native/java/io/io_util_md.c
index 6a85a0f..0dee96b 100644
--- a/jdk/src/solaris/native/java/io/io_util_md.c
+++ b/jdk/src/solaris/native/java/io/io_util_md.c
@@ -212,25 +212,6 @@
handleSetLength(FD fd, jlong length)
{
int result;
-#if defined(__linux__)
- /*
- * On Linux, if the file size is being increased, then ftruncate64()
- * will modify the metadata value of the size without actually allocating
- * any blocks which can cause a SIGBUS error if the file is subsequently
- * memory-mapped.
- */
- struct stat64 sb;
-
- if (fstat64(fd, &sb) == 0 && length > sb.st_blocks*512) {
- RESTARTABLE(posix_fallocate(fd, 0, length), result);
- // Return on success or if errno is neither EOPNOTSUPP nor ENOSYS
- if (result == 0) {
- return 0;
- } else if (errno != EOPNOTSUPP && errno != ENOSYS) {
- return result;
- }
- }
-#endif
RESTARTABLE(ftruncate64(fd, length), result);
return result;
}
diff --git a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c
index d8face7..dc34e1a 100644
--- a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c
+++ b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,26 +23,17 @@
* questions.
*/
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jvm_md.h"
-#include "jlong.h"
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include "sun_nio_ch_FileChannelImpl.h"
-#include "java_lang_Integer.h"
-#include "nio.h"
-#include "nio_util.h"
-#include <dlfcn.h>
+#include <sys/types.h>
+#include <unistd.h>
#if defined(__linux__) || defined(__solaris__)
#include <sys/sendfile.h>
#elif defined(_AIX)
#include <sys/socket.h>
#elif defined(_ALLBSD_SOURCE)
-#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
@@ -50,6 +41,14 @@
#define mmap64 mmap
#endif
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "nio.h"
+#include "nio_util.h"
+#include "sun_nio_ch_FileChannelImpl.h"
+#include "java_lang_Integer.h"
+
static jfieldID chan_fd; /* jobject 'fd' in sun.io.FileChannelImpl */
JNIEXPORT jlong JNICALL
@@ -124,22 +123,6 @@
}
-JNIEXPORT jlong JNICALL
-Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this,
- jobject fdo, jlong offset)
-{
- jint fd = fdval(env, fdo);
- jlong result = 0;
-
- if (offset < 0) {
- result = lseek64(fd, 0, SEEK_CUR);
- } else {
- result = lseek64(fd, offset, SEEK_SET);
- }
- return handle(env, result, "Position failed");
-}
-
-
JNIEXPORT void JNICALL
Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo)
{
diff --git a/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c b/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
index b301b53..9b3ff81 100644
--- a/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
+++ b/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
@@ -27,25 +27,19 @@
#define _FILE_OFFSET_BITS 64
#endif
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jlong.h"
-#include "sun_nio_ch_FileDispatcherImpl.h"
-#include "java_lang_Long.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <unistd.h>
+#include <sys/stat.h>
#if defined(__linux__)
#include <linux/fs.h>
#include <sys/ioctl.h>
#endif
-#include "nio.h"
-#include "nio_util.h"
-#ifdef _ALLBSD_SOURCE
+#if defined(_ALLBSD_SOURCE)
+#define lseek64 lseek
#define stat64 stat
#define flock64 flock
#define off64_t off_t
@@ -60,6 +54,15 @@
#define fdatasync fsync
#endif
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include "nio.h"
+#include "nio_util.h"
+#include "sun_nio_ch_FileDispatcherImpl.h"
+#include "java_lang_Long.h"
+
static int preCloseFD = -1; /* File descriptor to which we dup other fd's
before closing them for real */
@@ -145,6 +148,20 @@
return IOS_THROWN;
}
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_seek0(JNIEnv *env, jclass clazz,
+ jobject fdo, jlong offset)
+{
+ jint fd = fdval(env, fdo);
+ off64_t result;
+ if (offset < 0) {
+ result = lseek64(fd, 0, SEEK_CUR);
+ } else {
+ result = lseek64(fd, offset, SEEK_SET);
+ }
+ return handle(env, (jlong)result, "lseek64 failed");
+}
+
JNIEXPORT jint JNICALL
Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
jobject fdo, jboolean md)
@@ -182,30 +199,6 @@
"Truncation failed");
}
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_FileDispatcherImpl_allocate0(JNIEnv *env, jobject this,
- jobject fdo, jlong size)
-{
-#if defined(__linux__)
- /*
- * On Linux, if the file size is being increased, then ftruncate64()
- * will modify the metadata value of the size without actually allocating
- * any blocks which can cause a SIGBUS error if the file is subsequently
- * memory-mapped.
- */
- // Return on success or if errno is neither EOPNOTSUPP nor ENOSYS
- int result = posix_fallocate(fdval(env, fdo), 0, size);
- if (result == 0) {
- return 0;
- } else if (errno != EOPNOTSUPP && errno != ENOSYS) {
- return handle(env, result, "Allocation failed");
- }
-#endif
- return handle(env,
- ftruncate64(fdval(env, fdo), size),
- "Truncation failed");
-}
-
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
{
diff --git a/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java b/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
index 3c383ed..41f48c3 100644
--- a/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
+++ b/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java
@@ -85,6 +85,10 @@
return writev0(fd, address, len, append);
}
+ long seek(FileDescriptor fd, long offset) throws IOException {
+ return seek0(fd, offset);
+ }
+
int force(FileDescriptor fd, boolean metaData) throws IOException {
return force0(fd, metaData);
}
@@ -93,11 +97,6 @@
return truncate0(fd, size);
}
- int allocate(FileDescriptor fd, long size) throws IOException {
- // truncate0() works for extending and truncating file size
- return truncate0(fd, size);
- }
-
long size(FileDescriptor fd) throws IOException {
return size0(fd);
}
@@ -176,6 +175,8 @@
static native long writev0(FileDescriptor fd, long address, int len, boolean append)
throws IOException;
+ static native long seek0(FileDescriptor fd, long offset) throws IOException;
+
static native int force0(FileDescriptor fd, boolean metaData)
throws IOException;
diff --git a/jdk/src/windows/native/sun/nio/ch/FileChannelImpl.c b/jdk/src/windows/native/sun/nio/ch/FileChannelImpl.c
index cb72478..6edb8ca 100644
--- a/jdk/src/windows/native/sun/nio/ch/FileChannelImpl.c
+++ b/jdk/src/windows/native/sun/nio/ch/FileChannelImpl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -140,30 +140,6 @@
return 0;
}
-JNIEXPORT jlong JNICALL
-Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this,
- jobject fdo, jlong offset)
-{
- DWORD lowPos = 0;
- long highPos = 0;
- HANDLE h = (HANDLE)(handleval(env, fdo));
-
- if (offset < 0) {
- lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
- } else {
- lowPos = (DWORD)offset;
- highPos = (long)(offset >> 32);
- lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);
- }
- if (lowPos == ((DWORD)-1)) {
- if (GetLastError() != ERROR_SUCCESS) {
- JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
- return IOS_THROWN;
- }
- }
- return (((jlong)highPos) << 32) | lowPos;
-}
-
JNIEXPORT void JNICALL
Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo)
{
@@ -184,14 +160,17 @@
{
const int PACKET_SIZE = 524288;
+ LARGE_INTEGER where;
HANDLE src = (HANDLE)(handleval(env, srcFD));
SOCKET dst = (SOCKET)(fdval(env, dstFD));
DWORD chunkSize = (count > java_lang_Integer_MAX_VALUE) ?
java_lang_Integer_MAX_VALUE : (DWORD)count;
- BOOL result = 0;
+ BOOL result;
- jlong pos = Java_sun_nio_ch_FileChannelImpl_position0(env, this, srcFD, position);
- if (pos == IOS_THROWN) {
+ where.QuadPart = position;
+ result = SetFilePointerEx(src, where, &where, FILE_BEGIN);
+ if (result == 0) {
+ JNU_ThrowIOExceptionWithLastError(env, "SetFilePointerEx failed");
return IOS_THROWN;
}
diff --git a/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c b/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c
index 0fdc2ab..850d8ad 100644
--- a/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c
+++ b/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -315,6 +315,31 @@
return convertReturnVal(env, (jint)written, JNI_FALSE);
}
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_seek0(JNIEnv *env, jclass clazz,
+ jobject fdo, jlong offset)
+{
+ BOOL result = 0;
+ HANDLE h = (HANDLE)(handleval(env, fdo));
+ LARGE_INTEGER where;
+ DWORD whence;
+
+ if (offset < 0) {
+ where.QuadPart = 0;
+ whence = FILE_CURRENT;
+ } else {
+ where.QuadPart = offset;
+ whence = FILE_BEGIN;
+ }
+
+ result = SetFilePointerEx(h, where, &where, whence);
+ if (result == 0) {
+ JNU_ThrowIOExceptionWithLastError(env, "SetFilePointerEx failed");
+ return IOS_THROWN;
+ }
+ return (jlong)where.QuadPart;
+}
+
JNIEXPORT jint JNICALL
Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
jobject fdo, jboolean md)