--- old/make/mapfiles/libjava/mapfile-vers 2016-08-25 17:51:52.242564682 -0700
+++ new/make/mapfiles/libjava/mapfile-vers 2016-08-25 17:51:52.137564681 -0700
@@ -83,12 +83,17 @@
Java_java_io_FileInputStream_open0;
Java_java_io_FileInputStream_read0;
Java_java_io_FileInputStream_readBytes;
+ Java_java_io_FileInputStream_getPageSize0;
+ Java_java_io_FileInputStream_readBytesD;
Java_java_io_FileInputStream_skip;
Java_java_io_FileOutputStream_close0;
Java_java_io_FileOutputStream_initIDs;
+ Java_java_io_FileOutputStream_getPageSize0;
Java_java_io_FileOutputStream_open0;
Java_java_io_FileOutputStream_write;
Java_java_io_FileOutputStream_writeBytes;
+ Java_java_io_FileOutputStream_writeBytesD;
+ Java_java_io_FileOutputStream_getCurrentLocation0;
Java_java_io_ObjectInputStream_bytesToDoubles;
Java_java_io_ObjectInputStream_bytesToFloats;
Java_java_io_ObjectOutputStream_doublesToBytes;
@@ -102,10 +107,14 @@
Java_java_io_RandomAccessFile_open0;
Java_java_io_RandomAccessFile_read0;
Java_java_io_RandomAccessFile_readBytes;
+ Java_java_io_RandomAccessFile_getPageSize0;
+ Java_java_io_RandomAccessFile_readBytesD;
Java_java_io_RandomAccessFile_seek0;
+ Java_java_io_RandomAccessFile_getCurrentLocation0;
Java_java_io_RandomAccessFile_setLength;
Java_java_io_RandomAccessFile_write0;
Java_java_io_RandomAccessFile_writeBytes;
+ Java_java_io_RandomAccessFile_writeBytesD;
Java_java_io_UnixFileSystem_canonicalize0;
Java_java_io_UnixFileSystem_checkAccess;
Java_java_io_UnixFileSystem_createDirectory;
--- old/src/java.base/share/classes/java/io/FileInputStream.java 2016-08-25 17:51:52.487564684 -0700
+++ new/src/java.base/share/classes/java/io/FileInputStream.java 2016-08-25 17:51:52.384564683 -0700
@@ -62,6 +62,9 @@
private final AtomicBoolean closed = new AtomicBoolean(false);
+ private boolean direct = false;
+
+ private int pageSize = -1;
/**
* Creates a FileInputStream
by
* opening a connection to an actual file,
@@ -94,6 +97,41 @@
}
/**
+ * Creates a FileInputStream
by
+ * opening a connection to an actual file,
+ * the file named by the path name name
+ * in the file system. If the second parameter is
+ * true
, bytes are directly read from
+ * storage media. A new FileDescriptor
+ * object is created to represent this file connection.
+ *
+ * First, if there is a security
+ * manager, its checkRead
method
+ * is called with the name
argument
+ * as its argument.
+ *
+ * If the named file does not exist, is a directory rather than a regular
+ * file, or for some other reason cannot be opened for reading then a
+ * FileNotFoundException
is thrown.
+ *
+ * @param name the system-dependent file name.
+ * @param direct if true
, then bytes will be read
+ * directly to storage media
+ * @exception FileNotFoundException if the file does not exist,
+ * is a directory rather than a regular file,
+ * or for some other reason cannot be opened for
+ * reading.
+ * @exception SecurityException if a security manager exists and its
+ * checkRead
method denies read access
+ * to the file.
+ * @see java.lang.SecurityManager#checkRead(java.lang.String)
+ * @since 1.9
+ */
+ public FileInputStream(String name, boolean direct) throws FileNotFoundException {
+ this(name != null ? new File(name): null, direct);
+ }
+
+ /**
* Creates a FileInputStream
by
* opening a connection to an actual file,
* the file named by the File
@@ -121,21 +159,7 @@
* @see java.lang.SecurityManager#checkRead(java.lang.String)
*/
public FileInputStream(File file) throws FileNotFoundException {
- String name = (file != null ? file.getPath() : null);
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkRead(name);
- }
- if (name == null) {
- throw new NullPointerException();
- }
- if (file.isInvalid()) {
- throw new FileNotFoundException("Invalid file path");
- }
- fd = new FileDescriptor();
- fd.attach(this);
- path = name;
- open(name);
+ this(file, false);
}
/**
@@ -180,11 +204,54 @@
fd.attach(this);
}
+ /**
+ * Creates a FileInputStream
by opening a connection to an
+ * actual file with O_DIRECT option, the file named by the
+ * File
object file
in the file system. A new
+ * FileDescriptor
object is created to represent this file connection.
+ *
+ * First, if there is a security manager, its checkRead
+ * method is called with the path represented by the file
+ * argument as its argument.
+ *
+ * If the named file does not exist, is a directory rather than a regular
+ * file, or for some other reason cannot be opened for reading then a
+ * FileNotFoundException
is thrown.
+ * @param file the file to be opened for reading.
+ * @param direct if true
, then bytes will be read
+ * directly to storage media
+ * @exception FileNotFoundException if the file does not exist, is a
+ * directory rather than a regular file, or for some
+ * other reason cannot be opened for reading.
+ * @exception SecurityException if a security manager exists
+ */
+ public FileInputStream(File file, boolean direct) throws FileNotFoundException {
+ this.direct = direct;
+ if (direct) {
+ getPageSize();
+ }
+ String name = (file != null ? file.getPath() : null);
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkRead(name);
+ }
+ if (name == null) {
+ throw new NullPointerException();
+ }
+ if (file.isInvalid()) {
+ throw new FileNotFoundException("Invalid file path");
+ }
+ fd = new FileDescriptor();
+ fd.attach(this);
+ path = name;
+ open(name);
+ }
+
/**
* Opens the specified file for reading.
* @param name the name of the file
*/
- private native void open0(String name) throws FileNotFoundException;
+ private native void open0(String name, boolean direct) throws FileNotFoundException;
// wrap native call to allow instrumentation
/**
@@ -192,7 +259,16 @@
* @param name the name of the file
*/
private void open(String name) throws FileNotFoundException {
- open0(name);
+ open0(name, direct);
+ }
+
+ private native int getPageSize0();
+
+ private int getPageSize() {
+ if (pageSize == -1) {
+ pageSize = getPageSize0();
+ }
+ return this.pageSize;
}
/**
@@ -219,6 +295,15 @@
private native int readBytes(byte b[], int off, int len) throws IOException;
/**
+ * Reads a subarray as a sequence of bytes with DirectIO.
+ * @param b the data to be written
+ * @param off the start offset in the data
+ * @param len the number of bytes that are written
+ * @exception IOException If an I/O error has occurred.
+ */
+ private native int readBytesD(byte b[], int off, int len) throws IOException;
+
+ /**
* Reads up to b.length
bytes of data from this input
* stream into an array of bytes. This method blocks until some input
* is available.
@@ -230,6 +315,8 @@
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[]) throws IOException {
+ if (direct)
+ return readBytesD(b, 0, b.length);
return readBytes(b, 0, b.length);
}
@@ -252,6 +339,8 @@
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[], int off, int len) throws IOException {
+ if (direct)
+ return readBytesD(b, off, len);
return readBytes(b, off, len);
}
--- old/src/java.base/share/classes/java/io/FileOutputStream.java 2016-08-25 17:51:52.726564686 -0700
+++ new/src/java.base/share/classes/java/io/FileOutputStream.java 2016-08-25 17:51:52.624564685 -0700
@@ -79,6 +79,10 @@
private final AtomicBoolean closed = new AtomicBoolean(false);
+ private boolean direct = false;
+
+ private int pageSize = -1;
+
/**
* Creates a file output stream to write to the file with the
* specified name. A new FileDescriptor
object is
@@ -101,7 +105,7 @@
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
*/
public FileOutputStream(String name) throws FileNotFoundException {
- this(name != null ? new File(name) : null, false);
+ this(name != null ? new File(name) : null, false, false);
}
/**
@@ -133,7 +137,42 @@
public FileOutputStream(String name, boolean append)
throws FileNotFoundException
{
- this(name != null ? new File(name) : null, append);
+ this(name != null ? new File(name) : null, append, false);
+ }
+
+ /**
+ * Creates a file output stream to write to the file with the specified
+ * name. If the second argument is true
, then bytes will
+ * be written to the end of the file rather than the beginning. If the
+ * third parameter is true
, then bytes will be directly
+ * written to storage media. A new FileDescriptor
object
+ * is created to represent this file connection.
+ *
+ * First, if there is a security manager, its checkWrite
+ * method is called with name
as its argument.
+ *
+ * If the file exists but is a directory rather than a regular file, does
+ * not exist but cannot be created, or cannot be opened for any other
+ * reason then a FileNotFoundException
is thrown.
+ *
+ * @param name the system-dependent file name
+ * @param append if true
, then bytes will be written
+ * to the end of the file rather than the beginning
+ * @param direct if true
, then bytes will be written
+ * directly to storage media
+ * @exception FileNotFoundException if the file exists but is a directory
+ * rather than a regular file, does not exist but cannot
+ * be created, or cannot be opened for any other reason.
+ * @exception SecurityException if a security manager exists and its
+ * checkWrite
method denies write access
+ * to the file.
+ * @see java.lang.SecurityManager#checkWrite(java.lang.String)
+ * @since 1.9
+ */
+ public FileOutputStream(String name, boolean append, boolean direct)
+ throws FileNotFoundException
+ {
+ this(name != null ? new File(name) : null, append, direct);
}
/**
@@ -162,7 +201,7 @@
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
*/
public FileOutputStream(File file) throws FileNotFoundException {
- this(file, false);
+ this(file, false, false);
}
/**
@@ -197,6 +236,49 @@
public FileOutputStream(File file, boolean append)
throws FileNotFoundException
{
+ this(file, append, false);
+ }
+
+ /**
+ * Creates a file output stream to write to the file represented by
+ * the specified File
object. If the second argument is
+ * true
, then bytes will be written to the end of the file
+ * rather than the beginning. If the third argument is true
,
+ * then bytes will be directly written to storage media. A new
+ * FileDescriptor
object is created to represent this file
+ * connection.
+ *
+ * First, if there is a security manager, its checkWrite
+ * method is called with the path represented by the file
+ * argument as its argument.
+ *
+ * If the file exists but is a directory rather than a regular file, does
+ * not exist but cannot be created, or cannot be opened for any other
+ * reason then a FileNotFoundException
is thrown.
+ *
+ * @param file the file to be opened for writing.
+ * @param append if true
, then bytes will be written
+ * to the end of the file rather than the beginning
+ * @param direct if true
, then bytes will be written
+ * directly to storage media
+ * @exception FileNotFoundException if the file exists but is a directory
+ * rather than a regular file, does not exist but cannot
+ * be created, or cannot be opened for any other reason
+ * @exception SecurityException if a security manager exists and its
+ * checkWrite
method denies write access
+ * to the file.
+ * @see java.io.File#getPath()
+ * @see java.lang.SecurityException
+ * @see java.lang.SecurityManager#checkWrite(java.lang.String)
+ * @since 1.9
+ */
+ public FileOutputStream(File file, boolean append, boolean direct)
+ throws FileNotFoundException
+ {
+ this.direct = direct;
+ if (direct) {
+ getPageSize();
+ }
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
@@ -256,8 +338,9 @@
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
+ * @param direct whether the file s to be opened in the direct mode
*/
- private native void open0(String name, boolean append)
+ private native void open0(String name, boolean append, boolean direct)
throws FileNotFoundException;
// wrap native call to allow instrumentation
@@ -268,7 +351,16 @@
*/
private void open(String name, boolean append)
throws FileNotFoundException {
- open0(name, append);
+ open0(name, append, direct);
+ }
+
+ private native int getPageSize0();
+
+ private int getPageSize() {
+ if (pageSize == -1) {
+ pageSize = getPageSize0();
+ }
+ return this.pageSize;
}
/**
@@ -304,6 +396,17 @@
throws IOException;
/**
+ * Writes a sub array as a sequence of bytes with DirectIO.
+ * @param b the data to be written
+ * @param off the start offset in the data
+ * @param len the number of bytes that are written
+ * @param append {@code true} to first advance the position to the
+ * end of file
+ * @exception IOException If an I/O error has occurred.*/
+ private native void writeBytesD(byte b[], int off, int len, boolean append)
+ throws IOException;
+
+ /**
* Writes b.length
bytes from the specified byte array
* to this file output stream.
*
@@ -311,7 +414,15 @@
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[]) throws IOException {
- writeBytes(b, 0, b.length, fdAccess.getAppend(fd));
+ if (direct) {
+ if((b.length % pageSize != 0) ||(getCurrentLocation() % pageSize != 0)) {
+ throw new IOException("In DirectIO mode, the IO size must be aligned "
+ + "with kernel page size " + pageSize + " bytes!");
+ }
+ writeBytesD(b, 0, b.length, fdAccess.getAppend(fd));
+ } else {
+ writeBytes(b, 0, b.length, fdAccess.getAppend(fd));
+ }
}
/**
@@ -324,9 +435,23 @@
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[], int off, int len) throws IOException {
- writeBytes(b, off, len, fdAccess.getAppend(fd));
+ if (direct) {
+ if((len % pageSize != 0) || (getCurrentLocation() % pageSize != 0)) {
+ throw new IOException("In DirectIO mode, the IO size and the start "
+ + "point must be aligned with kernel page size " + pageSize + " bytes!");
+ }
+ writeBytesD(b, off, len, fdAccess.getAppend(fd));
+ } else {
+ writeBytes(b, off, len, fdAccess.getAppend(fd));
+ }
+ }
+
+ private long getCurrentLocation() throws IOException {
+ return getCurrentLocation0();
}
+ private native long getCurrentLocation0() throws IOException;
+
/**
* Closes this file output stream and releases any system resources
* associated with this stream. This file output stream may no longer
--- old/src/java.base/share/classes/java/io/RandomAccessFile.java 2016-08-25 17:51:52.967564689 -0700
+++ new/src/java.base/share/classes/java/io/RandomAccessFile.java 2016-08-25 17:51:52.863564688 -0700
@@ -64,6 +64,8 @@
private FileDescriptor fd;
private volatile FileChannel channel;
private boolean rw;
+ private boolean direct = false;
+ private int pageSize = -1;
/**
* The path of the referenced file
@@ -78,6 +80,7 @@
private static final int O_SYNC = 4;
private static final int O_DSYNC = 8;
private static final int O_TEMPORARY = 16;
+ private static final int O_DIRECT = 32;
/**
* Creates a random access file stream to read from, and optionally
@@ -216,6 +219,11 @@
int imode = -1;
if (mode.equals("r"))
imode = O_RDONLY;
+ else if (mode.equals("ro")) {
+ imode = O_RDONLY | O_DIRECT;
+ direct = true;
+ getPageSize();
+ }
else if (mode.startsWith("rw")) {
imode = O_RDWR;
rw = true;
@@ -224,6 +232,11 @@
imode |= O_SYNC;
else if (mode.equals("rwd"))
imode |= O_DSYNC;
+ else if (mode.equals("rwo")) {
+ imode |= O_DIRECT;
+ direct = true;
+ getPageSize();
+ }
else
imode = -1;
}
@@ -233,8 +246,8 @@
if (imode < 0)
throw new IllegalArgumentException("Illegal mode \"" + mode
+ "\" must be one of "
- + "\"r\", \"rw\", \"rws\","
- + " or \"rwd\"");
+ + "\"r\", \"ro\", \"rw\", \"rws\", \"rwd\""
+ + " or \"rwo\"");
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
@@ -338,6 +351,15 @@
open0(name, mode);
}
+ private native int getPageSize0();
+
+ private int getPageSize() {
+ if (pageSize == -1) {
+ pageSize = getPageSize0();
+ }
+ return this.pageSize;
+ }
+
// 'Read' primitives
/**
@@ -371,6 +393,15 @@
private native int readBytes(byte b[], int off, int len) throws IOException;
/**
+ * Reads a sub array as a sequence of bytes with DirectIO.
+ * @param b the buffer into which the data is read.
+ * @param off the start offset of the data.
+ * @param len the number of bytes to read.
+ * @exception IOException If an I/O error has occurred.
+ */
+ private native int readBytesD(byte b[], int off, int len) throws IOException;
+
+ /**
* Reads up to {@code len} bytes of data from this file into an
* array of bytes. This method blocks until at least one byte of input
* is available.
@@ -396,6 +427,9 @@
* {@code b.length - off}
*/
public int read(byte b[], int off, int len) throws IOException {
+ if (direct) {
+ return readBytesD(b, off, len);
+ }
return readBytes(b, off, len);
}
@@ -419,6 +453,9 @@
* @exception NullPointerException If {@code b} is {@code null}.
*/
public int read(byte b[]) throws IOException {
+ if (direct) {
+ return readBytesD(b, 0, b.length);
+ }
return readBytes(b, 0, b.length);
}
@@ -529,6 +566,15 @@
private native void writeBytes(byte b[], int off, int len) throws IOException;
/**
+ * Writes a sub array as a sequence of bytes with DirectIO.
+ * @param b the data to be written
+ * @param off the start offset in the data
+ * @param len the number of bytes that are written
+ * @exception IOException If an I/O error has occurred.
+ */
+ private native void writeBytesD(byte b[], int off, int len) throws IOException;
+
+ /**
* Writes {@code b.length} bytes from the specified byte array
* to this file, starting at the current file pointer.
*
@@ -536,7 +582,16 @@
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[]) throws IOException {
- writeBytes(b, 0, b.length);
+ if (direct) {
+ if((b.length % pageSize != 0) && (getCurrentLocation() % pageSize != 0)) {
+ throw new IOException("In DirectIO mode, the IO size and start point "
+ + "must be aligned with kernel page size " + pageSize + " bytes!");
+ } else {
+ writeBytesD(b, 0, b.length);
+ }
+ } else {
+ writeBytes(b, 0, b.length);
+ }
}
/**
@@ -549,7 +604,16 @@
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[], int off, int len) throws IOException {
- writeBytes(b, off, len);
+ if (direct) {
+ if ((len % pageSize != 0) || (getCurrentLocation() % pageSize != 0)) {
+ throw new IOException("In DirectIO mode, the IO size and start point "
+ + "must be aligned with kernel page size " + pageSize + " bytes!");
+ } else {
+ writeBytesD(b, off, len);
+ }
+ } else {
+ writeBytes(b, off, len);
+ }
}
// 'Random access' stuff
@@ -587,6 +651,12 @@
private native void seek0(long pos) throws IOException;
+ private long getCurrentLocation() throws IOException {
+ return getCurrentLocation0();
+ }
+
+ private native long getCurrentLocation0() throws IOException;
+
/**
* Returns the length of this file.
*
--- old/src/java.base/share/native/libjava/FileInputStream.c 2016-08-25 17:51:53.215564691 -0700
+++ new/src/java.base/share/native/libjava/FileInputStream.c 2016-08-25 17:51:53.111564690 -0700
@@ -42,6 +42,7 @@
/*******************************************************************/
jfieldID fis_fd; /* id for jobject 'fd' in java.io.FileInputStream */
+jfieldID fis_pgsz; /* id for jobject 'pageSize' in java.io.FileInputStream */
/**************************************************************
* static methods to store field ID's in initializers
@@ -50,17 +51,13 @@
JNIEXPORT void JNICALL
Java_java_io_FileInputStream_initIDs(JNIEnv *env, jclass fdClass) {
fis_fd = (*env)->GetFieldID(env, fdClass, "fd", "Ljava/io/FileDescriptor;");
+ fis_pgsz = (*env)->GetFieldID(env, fdClass, "pageSize", "I");
}
/**************************************************************
* Input stream
*/
-JNIEXPORT void JNICALL
-Java_java_io_FileInputStream_open0(JNIEnv *env, jobject this, jstring path) {
- fileOpen(env, this, path, fis_fd, O_RDONLY);
-}
-
JNIEXPORT jint JNICALL
Java_java_io_FileInputStream_read0(JNIEnv *env, jobject this) {
return readSingle(env, this, fis_fd);
--- old/src/java.base/share/native/libjava/RandomAccessFile.c 2016-08-25 17:51:53.454564693 -0700
+++ new/src/java.base/share/native/libjava/RandomAccessFile.c 2016-08-25 17:51:53.350564692 -0700
@@ -39,32 +39,12 @@
*/
jfieldID raf_fd; /* id for jobject 'fd' in java.io.RandomAccessFile */
+jfieldID raf_pgsz; /* id for jobject 'pageSize' in java.io.RandomAccessFile */
JNIEXPORT void JNICALL
Java_java_io_RandomAccessFile_initIDs(JNIEnv *env, jclass fdClass) {
raf_fd = (*env)->GetFieldID(env, fdClass, "fd", "Ljava/io/FileDescriptor;");
-}
-
-
-JNIEXPORT void JNICALL
-Java_java_io_RandomAccessFile_open0(JNIEnv *env,
- jobject this, jstring path, jint mode)
-{
- int flags = 0;
- if (mode & java_io_RandomAccessFile_O_RDONLY)
- flags = O_RDONLY;
- else if (mode & java_io_RandomAccessFile_O_RDWR) {
- flags = O_RDWR | O_CREAT;
- if (mode & java_io_RandomAccessFile_O_SYNC)
- flags |= O_SYNC;
- else if (mode & java_io_RandomAccessFile_O_DSYNC)
- flags |= O_DSYNC;
- }
-#ifdef WIN32
- if (mode & java_io_RandomAccessFile_O_TEMPORARY)
- flags |= O_TEMPORARY;
-#endif
- fileOpen(env, this, path, raf_fd, flags);
+ raf_pgsz = (*env)->GetFieldID(env, fdClass, "pageSize", "I");
}
JNIEXPORT jint JNICALL
--- old/src/java.base/share/native/libjava/io_util.c 2016-08-25 17:51:53.692564695 -0700
+++ new/src/java.base/share/native/libjava/io_util.c 2016-08-25 17:51:53.587564694 -0700
@@ -122,6 +122,103 @@
return nread;
}
+jint
+readBytesD(JNIEnv *env, jobject this, jbyteArray bytes,
+ jint off, jint len, jfieldID fid, jfieldID pgsz_id)
+{
+#ifdef _WIN32
+ JNU_ThrowIOException(env, "DirectIO is not supported on Windows platform!");
+#else
+ jint nread;
+ void *buf = NULL;
+ int delta = 0;
+ int gap = 0;
+ int newLen = 0;
+ long currentLocation;
+ long newStartLocation;
+ FD fd;
+ int pageSize;
+ if (IS_NULL(bytes)) {
+ JNU_ThrowNullPointerException(env, NULL);
+ return -1;
+ }
+
+ if (outOfBounds(env, off, len, bytes)) {
+ JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", NULL);
+ return -1;
+ }
+
+ if (len == 0) {
+ return 0;
+ }
+
+ fd = GET_FD(this, fid);
+ pageSize = GET_PG_SIZE(this, pgsz_id);
+
+ if (fd == -1) {
+ JNU_ThrowIOException(env, "Stream Closed");
+ return -1;
+ } else if (pageSize == -1) {
+ JNU_ThrowIOException(env, "Error getting kernel pageSize for DirectIO alligment");
+ return -1;
+ } else {
+ currentLocation = IO_Lseek(fd, 0, SEEK_CUR);
+
+ if ((currentLocation % pageSize) != 0) {
+ newStartLocation = currentLocation / pageSize * pageSize;
+ gap = currentLocation - newStartLocation;
+ } else {
+ newStartLocation = currentLocation;
+ gap = 0;
+ }
+ IO_Lseek(fd, newStartLocation, SEEK_SET);
+ if ((len % pageSize) != 0) {
+ newLen = (len / pageSize + 1) * pageSize;
+ } else {
+ newLen = len;
+ }
+ if ((newLen - gap) < len) {
+ newLen = newLen + pageSize;
+ }
+
+ delta = newLen - len;
+ if (newLen == 0) {
+ return 0;
+ } else {
+ posix_memalign(&buf, pageSize, newLen);
+ if (buf == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return 0;
+ }
+ }
+ nread = IO_Read(fd, buf, newLen);
+ if (nread > 0) {
+ if (nread >= len) {
+ (*env)->SetByteArrayRegion(env, bytes, off, len, ((jbyte *)(buf) + gap)); //read in the middle of a file
+ } else {
+ (*env)->SetByteArrayRegion(env, bytes, off, (nread-gap), ((jbyte *)(buf) + gap)); //reached the end of the file
+ }
+ } else if (nread == -1) {
+ JNU_ThrowIOExceptionWithLastError(env, "Read error");
+ } else { /*EOF*/
+ nread = -1;
+ }
+ IO_Lseek(fd, (currentLocation + len), SEEK_SET);
+
+ free(buf);
+ if (nread != -1) {
+ if (nread >= len) {
+ return len;
+ } else {
+ return (nread - gap);
+ }
+ } else {
+ return -1;
+ }
+ }
+#endif
+}
+
void
writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid) {
// Discard the 24 high-order bits of byte. See OutputStream#write(int)
@@ -202,6 +299,78 @@
}
void
+writeBytesD(JNIEnv *env, jobject this, jbyteArray bytes,
+ jint off, jint len, jboolean append, jfieldID fid, jfieldID pgsz_id)
+{
+#ifdef _WIN32
+ JNU_ThrowIOException(env, "DirectIO is not supported on Windows platform!");
+#else
+ jint n;
+ void *buf = NULL;
+ FD fd;
+ int pageSize;
+ long currentLocation;
+
+ fd = GET_FD(this, fid);
+ if (fd == -1) {
+ JNU_ThrowIOException(env, "Stream Closed");
+ }
+
+ pageSize = GET_PG_SIZE(this, pgsz_id);
+ if (pageSize == -1) {
+ JNU_ThrowIOException(env, "Error getting kernel pageSize for DirectIO alligment");
+ }
+
+ currentLocation = IO_Lseek(fd, 0, SEEK_CUR);
+
+ if ((len % pageSize != 0) || (currentLocation % pageSize != 0)) {
+ JNU_ThrowIOException(env,
+ "In DirectIO mode, the IO size and currentLocation must be aligned with kernel page size!");
+ }
+
+ if (IS_NULL(bytes)) {
+ JNU_ThrowNullPointerException(env, NULL);
+ return;
+ }
+
+ if (outOfBounds(env, off, len, bytes)) {
+ JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", NULL);
+ return;
+ }
+
+ if (len == 0) {
+ return;
+ } else {
+ posix_memalign(&buf, pageSize, len);
+ if (buf == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return;
+ }
+ }
+
+ (*env)->GetByteArrayRegion(env, bytes, off, len, (jbyte *)buf);
+
+ if (!(*env)->ExceptionOccurred(env)) {
+ off = 0;
+ while (len > 0) {
+ if (append == JNI_TRUE) {
+ n = IO_Append(fd, buf+off, len);
+ } else {
+ n = IO_Write(fd, buf+off, len);
+ }
+ if (n == -1) {
+ JNU_ThrowIOExceptionWithLastError(env, "Write error");
+ break;
+ }
+ off += n;
+ len -= n;
+ }
+ }
+ free(buf);
+#endif
+}
+
+void
throwFileNotFoundException(JNIEnv *env, jstring path)
{
char buf[256];
--- old/src/java.base/share/native/libjava/io_util.h 2016-08-25 17:51:53.933564698 -0700
+++ new/src/java.base/share/native/libjava/io_util.h 2016-08-25 17:51:53.828564697 -0700
@@ -29,6 +29,7 @@
extern jfieldID IO_fd_fdID;
extern jfieldID IO_handle_fdID;
extern jfieldID IO_append_fdID;
+extern jfieldID IO_pgsz_fdID;
#ifdef _ALLBSD_SOURCE
#include