8202261: (fc) FileChannel.map and RandomAccessFile.setLength should not preallocate space

Reviewed-by: bpb
This commit is contained in:
Alan Bateman 2018-04-26 09:04:18 +01:00
parent ccc74fdd60
commit 2df7aa7b9f
9 changed files with 101 additions and 144 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, 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
@ -74,6 +74,10 @@ class FileDispatcherImpl extends FileDispatcher {
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);
}
@ -82,10 +86,6 @@ class FileDispatcherImpl extends FileDispatcher {
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);
}
@ -156,10 +156,10 @@ class FileDispatcherImpl extends FileDispatcher {
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 offset)
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;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
@ -232,25 +232,6 @@ jint
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(fallocate64(fd, 0, 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;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, 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,33 +23,31 @@
* 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>
#define lseek64 lseek
#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.nio.ch.FileChannelImpl */
JNIEXPORT jlong JNICALL
@ -123,23 +121,6 @@ Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this,
"Unmap failed");
}
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 jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
jobject srcFDO,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, 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,40 +23,42 @@
* questions.
*/
#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>
#include <sys/statvfs.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
#define F_SETLKW64 F_SETLKW
#define F_SETLK64 F_SETLK
#define pread64 pread
#define pwrite64 pwrite
#define ftruncate64 ftruncate
#define fstat64 fstat
#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 */
@ -142,6 +144,20 @@ handle(JNIEnv *env, jlong rv, char *msg)
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)
@ -187,30 +203,6 @@ Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,
"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 = fallocate64(fdval(env, fdo), 0, 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)
{