Skip to content

Commit

Permalink
8164900: Add support for O_DIRECT
Browse files Browse the repository at this point in the history
Add support for Direct I/O in FileChannel

Co-authored-by: Volker Simonis <volker.simonis@gmail.com>
Reviewed-by: alanb, bpb, alanbur, coffeys, aph, clanger, plevart, mli, psandoz, simonis
  • Loading branch information
2 people authored and Brian Burkhalter committed Oct 17, 2017
1 parent 97db013 commit ec1c3bc
Show file tree
Hide file tree
Showing 30 changed files with 1,523 additions and 45 deletions.
4 changes: 2 additions & 2 deletions make/gensrc/GensrcMisc.gmk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 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
Expand Down Expand Up @@ -63,7 +63,7 @@ endif
define generate-preproc-src
$(call MakeDir, $(@D))
( $(NAWK) '/@@END_COPYRIGHT@@/{exit}1' $< && \
$(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $< \
$(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $(CFLAGS_JDKLIB) $< \
2> >($(GREP) -v '^$(<F)$$' >&2) \
| $(NAWK) '/@@START_HERE@@/,0' \
| $(SED) -e 's/@@START_HERE@@/\/\/ AUTOMATICALLY GENERATED FILE - DO NOT EDIT/' \
Expand Down
3 changes: 2 additions & 1 deletion make/jprt.properties
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ jprt.test.bundle.targets=\
${my.make.rule.test.targets.hotspot.reg}, \
${my.make.rule.test.targets.hotspot.gtest} \
${my.make.rule.test.targets.nativesanity} \
${my.test.target.set:TESTNAME=jdk_lang}
${my.test.target.set:TESTNAME=jdk_lang} \
${my.test.target.set:TESTNAME=jdk_nio}

# 7155453: Work-around to prevent popups on OSX from blocking test completion
# but the work-around is added to all platforms to be consistent
Expand Down
1 change: 1 addition & 0 deletions make/mapfiles/libnio/mapfile-linux
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_FileDispatcherImpl_truncate0;
Java_sun_nio_ch_FileDispatcherImpl_write0;
Java_sun_nio_ch_FileDispatcherImpl_writev0;
Java_sun_nio_ch_FileDispatcherImpl_setDirect0;
Java_sun_nio_ch_FileKey_init;
Java_sun_nio_ch_FileKey_initIDs;
Java_sun_nio_ch_InheritedChannel_close0;
Expand Down
1 change: 1 addition & 0 deletions make/mapfiles/libnio/mapfile-solaris
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_FileDispatcherImpl_truncate0;
Java_sun_nio_ch_FileDispatcherImpl_write0;
Java_sun_nio_ch_FileDispatcherImpl_writev0;
Java_sun_nio_ch_FileDispatcherImpl_setDirect0;
Java_sun_nio_ch_FileKey_init;
Java_sun_nio_ch_FileKey_initIDs;
Java_sun_nio_ch_InheritedChannel_close0;
Expand Down
6 changes: 6 additions & 0 deletions make/test/JtregNativeJdk.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ BUILD_JDK_JTREG_NATIVE_SRC += \
$(TOPDIR)/test/jdk/java/lang/String/nativeEncoding \
#

ifneq ($(OPENJDK_TARGET_OS), windows)
BUILD_JDK_JTREG_NATIVE_SRC += $(TOPDIR)/test/jdk/java/nio/channels/FileChannel/directio
endif

BUILD_JDK_JTREG_OUTPUT_DIR := $(OUTPUTDIR)/support/test/jdk/jtreg/native

BUILD_JDK_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/jdk/jtreg
Expand All @@ -56,8 +60,10 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := $(WIN_LIB_JAVA)
else ifeq ($(OPENJDK_TARGET_OS), solaris)
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava -lc
BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava -lc
else
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava
BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava
endif

$(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_LIBRARIES, \
Expand Down
27 changes: 26 additions & 1 deletion src/java.base/share/classes/java/nio/file/FileStore.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 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
Expand Down Expand Up @@ -111,6 +111,31 @@ protected FileStore() {
*/
public abstract long getUsableSpace() throws IOException;

/**
* Returns the number of bytes per block in this file store.
*
* <p> File storage is typically organized into discrete sequences of bytes
* called <i>blocks</i>. A block is the smallest storage unit of a file store.
* Every read and write operation is performed on a multiple of blocks.
*
* @implSpec The implementation in this class throws an
* {@code UnsupportedOperationException}.
*
* @return a positive value representing the block size of this file store,
* in bytes
*
* @throws IOException
* if an I/O error occurs
*
* @throws UnsupportedOperationException
* if the operation is not supported
*
* @since 10
*/
public long getBlockSize() throws IOException {
throw new UnsupportedOperationException();
}

/**
* Returns the number of unallocated bytes in the file store.
*
Expand Down
56 changes: 48 additions & 8 deletions src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,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;

Expand Down Expand Up @@ -87,6 +92,12 @@ public class FileChannelImpl
// Positional-read is not interruptible
private volatile boolean uninterruptible;

// DirectIO flag
private final boolean direct;

// IO alignment value for DirectIO
private final int alignment;

// Cleanable with an action which closes this channel's file descriptor
private final Cleanable closer;

Expand All @@ -103,14 +114,22 @@ public void run() {
}

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) {
assert path != null;
this.alignment = nd.setDirectIO(fd, path);
} else {
this.alignment = -1;
}

// Register a cleaning action if and only if there is no parent
// as the parent will take care of closing the file descriptor.
// FileChannel is used by the LambdaMetaFactory so a lambda cannot
Expand All @@ -125,7 +144,14 @@ public static FileChannel open(FileDescriptor fd, String path,
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 {
Expand Down Expand Up @@ -181,6 +207,8 @@ public int read(ByteBuffer dst) throws IOException {
if (!readable)
throw new NonReadableChannelException();
synchronized (positionLock) {
if (direct)
Util.checkChannelPositionAligned(position(), alignment);
int n = 0;
int ti = -1;
try {
Expand All @@ -189,7 +217,7 @@ public int read(ByteBuffer dst) throws IOException {
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 {
Expand All @@ -209,6 +237,8 @@ public long read(ByteBuffer[] dsts, int offset, int length)
if (!readable)
throw new NonReadableChannelException();
synchronized (positionLock) {
if (direct)
Util.checkChannelPositionAligned(position(), alignment);
long n = 0;
int ti = -1;
try {
Expand All @@ -217,7 +247,8 @@ public long read(ByteBuffer[] dsts, int offset, int length)
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 {
Expand All @@ -233,6 +264,8 @@ public int write(ByteBuffer src) throws IOException {
if (!writable)
throw new NonWritableChannelException();
synchronized (positionLock) {
if (direct)
Util.checkChannelPositionAligned(position(), alignment);
int n = 0;
int ti = -1;
try {
Expand All @@ -241,7 +274,7 @@ public int write(ByteBuffer src) throws IOException {
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 {
Expand All @@ -261,6 +294,8 @@ public long write(ByteBuffer[] srcs, int offset, int length)
if (!writable)
throw new NonWritableChannelException();
synchronized (positionLock) {
if (direct)
Util.checkChannelPositionAligned(position(), alignment);
long n = 0;
int ti = -1;
try {
Expand All @@ -269,7 +304,8 @@ public long write(ByteBuffer[] srcs, int offset, int length)
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 {
Expand Down Expand Up @@ -752,6 +788,8 @@ public int read(ByteBuffer dst, long position) throws IOException {
throw new IllegalArgumentException("Negative position");
if (!readable)
throw new NonReadableChannelException();
if (direct)
Util.checkChannelPositionAligned(position, alignment);
ensureOpen();
if (nd.needsPositionLock()) {
synchronized (positionLock) {
Expand All @@ -774,7 +812,7 @@ private int readInternal(ByteBuffer dst, long position) throws IOException {
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 {
Expand All @@ -791,6 +829,8 @@ public int write(ByteBuffer src, long position) throws IOException {
throw new IllegalArgumentException("Negative position");
if (!writable)
throw new NonWritableChannelException();
if (direct)
Util.checkChannelPositionAligned(position, alignment);
ensureOpen();
if (nd.needsPositionLock()) {
synchronized (positionLock) {
Expand All @@ -811,7 +851,7 @@ private int writeInternal(ByteBuffer src, long position) throws IOException {
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 {
Expand Down
4 changes: 3 additions & 1 deletion src/java.base/share/classes/sun/nio/ch/FileDispatcher.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 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
Expand Down Expand Up @@ -61,4 +61,6 @@ abstract FileDescriptor duplicateForMapping(FileDescriptor fd)
abstract boolean canTransferToDirectly(SelectableChannel sc);

abstract boolean transferToDirectlyNeedsPositionLock();

abstract int setDirectIO(FileDescriptor fd, String path);
}

0 comments on commit ec1c3bc

Please sign in to comment.