--- 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. *