8202261: (fc) FileChannel.map and RandomAccessFile.setLength should not preallocate space
Reviewed-by: bpb
This commit is contained in:
parent
ccc74fdd60
commit
2df7aa7b9f
@ -334,7 +334,7 @@ public class FileChannelImpl
|
||||
boolean append = fdAccess.getAppend(fd);
|
||||
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 {
|
||||
@ -358,7 +358,7 @@ public class FileChannelImpl
|
||||
if (!isOpen())
|
||||
return null;
|
||||
do {
|
||||
p = position0(fd, newPosition);
|
||||
p = nd.seek(fd, newPosition);
|
||||
} while ((p == IOStatus.INTERRUPTED) && isOpen());
|
||||
return this;
|
||||
} finally {
|
||||
@ -418,7 +418,7 @@ public class FileChannelImpl
|
||||
|
||||
// get current position
|
||||
do {
|
||||
p = position0(fd, -1);
|
||||
p = nd.seek(fd, -1);
|
||||
} while ((p == IOStatus.INTERRUPTED) && isOpen());
|
||||
if (!isOpen())
|
||||
return null;
|
||||
@ -437,7 +437,7 @@ public class FileChannelImpl
|
||||
if (p > newSize)
|
||||
p = newSize;
|
||||
do {
|
||||
rp = position0(fd, p);
|
||||
rp = nd.seek(fd, p);
|
||||
} while ((rp == IOStatus.INTERRUPTED) && isOpen());
|
||||
return this;
|
||||
} finally {
|
||||
@ -985,7 +985,7 @@ public class FileChannelImpl
|
||||
}
|
||||
int rv;
|
||||
do {
|
||||
rv = nd.allocate(fd, position + size);
|
||||
rv = nd.truncate(fd, position + size);
|
||||
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
|
||||
if (!isOpen())
|
||||
return null;
|
||||
@ -1212,11 +1212,6 @@ public class FileChannelImpl
|
||||
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();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 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
|
||||
@ -36,12 +36,17 @@ abstract class FileDispatcher extends NativeDispatcher {
|
||||
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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
@ -78,6 +78,10 @@ class FileDispatcherImpl extends FileDispatcher {
|
||||
return writev0(fd, address, len, fdAccess.getAppend(fd));
|
||||
}
|
||||
|
||||
long seek(FileDescriptor fd, long offset) throws IOException {
|
||||
return seek0(fd, offset);
|
||||
}
|
||||
|
||||
int force(FileDescriptor fd, boolean metaData) throws IOException {
|
||||
return force0(fd, metaData);
|
||||
}
|
||||
@ -86,11 +90,6 @@ class FileDispatcherImpl extends FileDispatcher {
|
||||
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);
|
||||
}
|
||||
@ -126,8 +125,7 @@ class FileDispatcherImpl extends FileDispatcher {
|
||||
return true;
|
||||
}
|
||||
|
||||
int setDirectIO(FileDescriptor fd, String path)
|
||||
{
|
||||
int setDirectIO(FileDescriptor fd, String path) {
|
||||
int result = -1;
|
||||
String filePath = path.substring(0, path.lastIndexOf(File.separator));
|
||||
CharBuffer buffer = CharBuffer.allocate(filePath.length());
|
||||
@ -178,6 +176,8 @@ class FileDispatcherImpl extends FileDispatcher {
|
||||
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;
|
||||
|
||||
|
@ -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
|
||||
@ -140,31 +140,6 @@ Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this,
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this,
|
||||
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, "Seek failed");
|
||||
return IOS_THROWN;
|
||||
}
|
||||
return (jlong)where.QuadPart;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
|
||||
jobject srcFD,
|
||||
@ -173,14 +148,17 @@ Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -298,6 +298,31 @@ Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fd
|
||||
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user