--- old/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java 2017-08-09 14:53:21.974811133 -0700 +++ new/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java 2017-08-09 14:53:21.868811132 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, 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 @@ -40,6 +40,11 @@ import java.nio.channels.ReadableByteChannel; import java.nio.channels.SelectableChannel; import java.nio.channels.WritableByteChannel; +import java.nio.file.Files; +import java.nio.file.FileStore; +import java.nio.file.FileSystemException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; @@ -85,15 +90,27 @@ // Positional-read is not interruptible private volatile boolean uninterruptible; + //directIO + private final boolean direct; + + //IO alignment for DirectIO + private final int alignment; + private FileChannelImpl(FileDescriptor fd, String path, boolean readable, - boolean writable, Object parent) + boolean writable, boolean direct, Object parent) { this.fd = fd; this.readable = readable; this.writable = writable; this.parent = parent; this.path = path; + this.direct = direct; this.nd = new FileDispatcherImpl(); + if (direct) { + this.alignment = nd.setDirectIO(fd, path); + } else { + this.alignment = -1; + } } // Used by FileInputStream.getChannel(), FileOutputStream.getChannel @@ -102,7 +119,14 @@ boolean readable, boolean writable, Object parent) { - return new FileChannelImpl(fd, path, readable, writable, parent); + return new FileChannelImpl(fd, path, readable, writable, false, parent); + } + + public static FileChannel open(FileDescriptor fd, String path, + boolean readable, boolean writable, + boolean direct, Object parent) + { + return new FileChannelImpl(fd, path, readable, writable, direct, parent); } private void ensureOpen() throws IOException { @@ -150,6 +174,16 @@ } public int read(ByteBuffer dst) throws IOException { + if (direct) { + if (dst.remaining() % alignment != 0) { + throw new IOException("Number of remaining bytes is not " + + "a multiple of the block size"); + } + if (position() % alignment != 0) { + throw new IOException("Channel position is not a multiple " + + "of the block size"); + } + } ensureOpen(); if (!readable) throw new NonReadableChannelException(); @@ -162,7 +196,7 @@ if (!isOpen()) return 0; do { - n = IOUtil.read(fd, dst, -1, nd); + n = IOUtil.read(fd, dst, -1, direct, alignment, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally { @@ -178,6 +212,19 @@ { if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) throw new IndexOutOfBoundsException(); + + if (direct && (position() % alignment != 0)) + throw new IOException("Channel position is not " + + "a multiple of the block size"); + + int i = offset; + while (i < dsts.length) { + if (direct && (dsts[i].remaining() % alignment != 0)) + throw new IOException("Number of remaining bytes is not " + + "a multiple of the block size"); + i++; + } + ensureOpen(); if (!readable) throw new NonReadableChannelException(); @@ -190,7 +237,8 @@ if (!isOpen()) return 0; do { - n = IOUtil.read(fd, dsts, offset, length, nd); + n = IOUtil.read(fd, dsts, offset, length, + direct, alignment, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally { @@ -205,6 +253,16 @@ ensureOpen(); if (!writable) throw new NonWritableChannelException(); + if (direct) { + if (src.remaining() % alignment != 0) { + throw new IOException("Number of remaining bytes is not " + + "a multiple of the block size"); + } + if (position() % alignment != 0) { + throw new IOException("Channel position is not a multiple " + + "of the block size"); + } + } synchronized (positionLock) { int n = 0; int ti = -1; @@ -214,7 +272,7 @@ if (!isOpen()) return 0; do { - n = IOUtil.write(fd, src, -1, nd); + n = IOUtil.write(fd, src, -1, direct, alignment, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally { @@ -233,6 +291,19 @@ ensureOpen(); if (!writable) throw new NonWritableChannelException(); + + if (direct && (position() % alignment != 0)) + throw new IOException("Channel position is not a multiple " + + " of the block size"); + + int i = offset; + while (i < srcs.length) { + if (direct && (srcs[i].remaining() % alignment != 0)) + throw new IOException("Number of remaining bytes is not " + + "a multiple of the block size"); + i++; + } + synchronized (positionLock) { long n = 0; int ti = -1; @@ -242,7 +313,8 @@ if (!isOpen()) return 0; do { - n = IOUtil.write(fd, srcs, offset, length, nd); + n = IOUtil.write(fd, srcs, offset, length, + direct, alignment, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally { @@ -725,6 +797,17 @@ throw new IllegalArgumentException("Negative position"); if (!readable) throw new NonReadableChannelException(); + if (direct) { + if (dst.remaining() % alignment != 0) { + throw new IOException("Remaining number of bytes is not " + + "a multiple of the block size"); + } + if (position % alignment != 0) { + throw new IOException("Channel position is not a multiple " + + "of the block size"); + } + } + ensureOpen(); if (nd.needsPositionLock()) { synchronized (positionLock) { @@ -747,7 +830,7 @@ if (!isOpen()) return -1; do { - n = IOUtil.read(fd, dst, position, nd); + n = IOUtil.read(fd, dst, position, direct, alignment, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally { @@ -764,6 +847,16 @@ throw new IllegalArgumentException("Negative position"); if (!writable) throw new NonWritableChannelException(); + if (direct) { + if (src.remaining() % alignment != 0) { + throw new IOException("Remaining number of bytes is not " + + "a multiple of the block size"); + } + if (position % alignment != 0) { + throw new IOException("Channel position is not a multiple " + + "of the block size"); + } + } ensureOpen(); if (nd.needsPositionLock()) { synchronized (positionLock) { @@ -784,7 +877,7 @@ if (!isOpen()) return -1; do { - n = IOUtil.write(fd, src, position, nd); + n = IOUtil.write(fd, src, position, direct, alignment, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); return IOStatus.normalize(n); } finally {