changeset 13153:a2361ab40be8

8202261: (fc) FileChannel.map and RandomAccessFile.setLength should not preallocate space Reviewed-by: coffeys
author robm
date Fri, 05 Oct 2018 14:05:02 -0700
parents fd78f7e83f3f
children 5318f8b41bad
files make/mapfiles/libnio/mapfile-linux make/mapfiles/libnio/mapfile-macosx make/mapfiles/libnio/mapfile-solaris src/share/classes/sun/nio/ch/FileChannelImpl.java src/share/classes/sun/nio/ch/FileDispatcher.java src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java src/solaris/native/java/io/io_util_md.c src/solaris/native/sun/nio/ch/FileChannelImpl.c src/solaris/native/sun/nio/ch/FileDispatcherImpl.c src/windows/classes/sun/nio/ch/FileDispatcherImpl.java src/windows/native/sun/nio/ch/FileChannelImpl.c src/windows/native/sun/nio/ch/FileDispatcherImpl.c
diffstat 12 files changed, 97 insertions(+), 138 deletions(-) [+]
line wrap: on
line diff
--- a/make/mapfiles/libnio/mapfile-linux	Sun Jun 01 11:54:04 2014 -0400
+++ b/make/mapfiles/libnio/mapfile-linux	Fri Oct 05 14:05:02 2018 -0700
@@ -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;
--- a/make/mapfiles/libnio/mapfile-macosx	Sun Jun 01 11:54:04 2014 -0400
+++ b/make/mapfiles/libnio/mapfile-macosx	Fri Oct 05 14:05:02 2018 -0700
@@ -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;
--- a/make/mapfiles/libnio/mapfile-solaris	Sun Jun 01 11:54:04 2014 -0400
+++ b/make/mapfiles/libnio/mapfile-solaris	Fri Oct 05 14:05:02 2018 -0700
@@ -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;
--- a/src/share/classes/sun/nio/ch/FileChannelImpl.java	Sun Jun 01 11:54:04 2014 -0400
+++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java	Fri Oct 05 14:05:02 2018 -0700
@@ -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();
 
--- a/src/share/classes/sun/nio/ch/FileDispatcher.java	Sun Jun 01 11:54:04 2014 -0400
+++ b/src/share/classes/sun/nio/ch/FileDispatcher.java	Fri Oct 05 14:05:02 2018 -0700
@@ -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,
--- a/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java	Sun Jun 01 11:54:04 2014 -0400
+++ b/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java	Fri Oct 05 14:05:02 2018 -0700
@@ -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;
--- a/src/solaris/native/java/io/io_util_md.c	Sun Jun 01 11:54:04 2014 -0400
+++ b/src/solaris/native/java/io/io_util_md.c	Fri Oct 05 14:05:02 2018 -0700
@@ -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;
 }
--- a/src/solaris/native/sun/nio/ch/FileChannelImpl.c	Sun Jun 01 11:54:04 2014 -0400
+++ b/src/solaris/native/sun/nio/ch/FileChannelImpl.c	Fri Oct 05 14:05:02 2018 -0700
@@ -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)
 {
--- a/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c	Sun Jun 01 11:54:04 2014 -0400
+++ b/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c	Fri Oct 05 14:05:02 2018 -0700
@@ -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)
 {
--- a/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Sun Jun 01 11:54:04 2014 -0400
+++ b/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Fri Oct 05 14:05:02 2018 -0700
@@ -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;
 
--- a/src/windows/native/sun/nio/ch/FileChannelImpl.c	Sun Jun 01 11:54:04 2014 -0400
+++ b/src/windows/native/sun/nio/ch/FileChannelImpl.c	Fri Oct 05 14:05:02 2018 -0700
@@ -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;
     }
 
--- a/src/windows/native/sun/nio/ch/FileDispatcherImpl.c	Sun Jun 01 11:54:04 2014 -0400
+++ b/src/windows/native/sun/nio/ch/FileDispatcherImpl.c	Fri Oct 05 14:05:02 2018 -0700
@@ -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)