mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8164900: Add support for O_DIRECT
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
This commit is contained in:
parent
97db013bd3
commit
ec1c3bce45
30 changed files with 1523 additions and 45 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2013, 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
|
||||
|
@ -47,22 +47,38 @@ public class IOUtil {
|
|||
NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
if (src instanceof DirectBuffer)
|
||||
return writeFromNativeBuffer(fd, src, position, nd);
|
||||
return write(fd, src, position, false, -1, nd);
|
||||
}
|
||||
|
||||
static int write(FileDescriptor fd, ByteBuffer src, long position,
|
||||
boolean directIO, int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
if (src instanceof DirectBuffer) {
|
||||
return writeFromNativeBuffer(fd, src, position,
|
||||
directIO, alignment, nd);
|
||||
}
|
||||
|
||||
// Substitute a native buffer
|
||||
int pos = src.position();
|
||||
int lim = src.limit();
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
|
||||
ByteBuffer bb;
|
||||
if (directIO) {
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
bb = Util.getTemporaryAlignedDirectBuffer(rem, alignment);
|
||||
} else {
|
||||
bb = Util.getTemporaryDirectBuffer(rem);
|
||||
}
|
||||
try {
|
||||
bb.put(src);
|
||||
bb.flip();
|
||||
// Do not update src until we see how many bytes were written
|
||||
src.position(pos);
|
||||
|
||||
int n = writeFromNativeBuffer(fd, bb, position, nd);
|
||||
int n = writeFromNativeBuffer(fd, bb, position,
|
||||
directIO, alignment, nd);
|
||||
if (n > 0) {
|
||||
// now update src
|
||||
src.position(pos + n);
|
||||
|
@ -74,7 +90,8 @@ public class IOUtil {
|
|||
}
|
||||
|
||||
private static int writeFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
|
||||
long position, NativeDispatcher nd)
|
||||
long position, boolean directIO,
|
||||
int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
int pos = bb.position();
|
||||
|
@ -82,6 +99,11 @@ public class IOUtil {
|
|||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
if (directIO) {
|
||||
Util.checkBufferPositionAligned(bb, pos, alignment);
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
}
|
||||
|
||||
int written = 0;
|
||||
if (rem == 0)
|
||||
return 0;
|
||||
|
@ -100,12 +122,19 @@ public class IOUtil {
|
|||
static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return write(fd, bufs, 0, bufs.length, nd);
|
||||
return write(fd, bufs, 0, bufs.length, false, -1, nd);
|
||||
}
|
||||
|
||||
static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
|
||||
NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return write(fd, bufs, offset, length, false, -1, nd);
|
||||
}
|
||||
|
||||
static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
|
||||
boolean directIO, int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
IOVecWrapper vec = IOVecWrapper.get(length);
|
||||
|
||||
|
@ -122,12 +151,20 @@ public class IOUtil {
|
|||
int lim = buf.limit();
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
if (directIO)
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
|
||||
if (rem > 0) {
|
||||
vec.setBuffer(iov_len, buf, pos, rem);
|
||||
|
||||
// allocate shadow buffer to ensure I/O is done with direct buffer
|
||||
if (!(buf instanceof DirectBuffer)) {
|
||||
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
|
||||
ByteBuffer shadow;
|
||||
if (directIO)
|
||||
shadow = Util.getTemporaryAlignedDirectBuffer(rem,
|
||||
alignment);
|
||||
else
|
||||
shadow = Util.getTemporaryDirectBuffer(rem);
|
||||
shadow.put(buf);
|
||||
shadow.flip();
|
||||
vec.setShadow(iov_len, shadow);
|
||||
|
@ -185,16 +222,33 @@ public class IOUtil {
|
|||
static int read(FileDescriptor fd, ByteBuffer dst, long position,
|
||||
NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return read(fd, dst, position, false, -1, nd);
|
||||
}
|
||||
|
||||
static int read(FileDescriptor fd, ByteBuffer dst, long position,
|
||||
boolean directIO, int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
if (dst.isReadOnly())
|
||||
throw new IllegalArgumentException("Read-only buffer");
|
||||
if (dst instanceof DirectBuffer)
|
||||
return readIntoNativeBuffer(fd, dst, position, nd);
|
||||
return readIntoNativeBuffer(fd, dst, position,
|
||||
directIO, alignment, nd);
|
||||
|
||||
// Substitute a native buffer
|
||||
ByteBuffer bb = Util.getTemporaryDirectBuffer(dst.remaining());
|
||||
ByteBuffer bb;
|
||||
int rem = dst.remaining();
|
||||
if (directIO) {
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
bb = Util.getTemporaryAlignedDirectBuffer(rem,
|
||||
alignment);
|
||||
} else {
|
||||
bb = Util.getTemporaryDirectBuffer(rem);
|
||||
}
|
||||
try {
|
||||
int n = readIntoNativeBuffer(fd, bb, position, nd);
|
||||
int n = readIntoNativeBuffer(fd, bb, position,
|
||||
directIO, alignment,nd);
|
||||
bb.flip();
|
||||
if (n > 0)
|
||||
dst.put(bb);
|
||||
|
@ -205,7 +259,8 @@ public class IOUtil {
|
|||
}
|
||||
|
||||
private static int readIntoNativeBuffer(FileDescriptor fd, ByteBuffer bb,
|
||||
long position, NativeDispatcher nd)
|
||||
long position, boolean directIO,
|
||||
int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
int pos = bb.position();
|
||||
|
@ -213,6 +268,11 @@ public class IOUtil {
|
|||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
if (directIO) {
|
||||
Util.checkBufferPositionAligned(bb, pos, alignment);
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
}
|
||||
|
||||
if (rem == 0)
|
||||
return 0;
|
||||
int n = 0;
|
||||
|
@ -230,12 +290,19 @@ public class IOUtil {
|
|||
static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return read(fd, bufs, 0, bufs.length, nd);
|
||||
return read(fd, bufs, 0, bufs.length, false, -1, nd);
|
||||
}
|
||||
|
||||
static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
|
||||
NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
return read(fd, bufs, offset, bufs.length, false, -1, nd);
|
||||
}
|
||||
|
||||
static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
|
||||
boolean directIO, int alignment, NativeDispatcher nd)
|
||||
throws IOException
|
||||
{
|
||||
IOVecWrapper vec = IOVecWrapper.get(length);
|
||||
|
||||
|
@ -255,12 +322,21 @@ public class IOUtil {
|
|||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
if (directIO)
|
||||
Util.checkRemainingBufferSizeAligned(rem, alignment);
|
||||
|
||||
if (rem > 0) {
|
||||
vec.setBuffer(iov_len, buf, pos, rem);
|
||||
|
||||
// allocate shadow buffer to ensure I/O is done with direct buffer
|
||||
if (!(buf instanceof DirectBuffer)) {
|
||||
ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
|
||||
ByteBuffer shadow;
|
||||
if (directIO) {
|
||||
shadow = Util.getTemporaryAlignedDirectBuffer(rem,
|
||||
alignment);
|
||||
} else {
|
||||
shadow = Util.getTemporaryDirectBuffer(rem);
|
||||
}
|
||||
vec.setShadow(iov_len, shadow);
|
||||
buf = shadow;
|
||||
pos = shadow.position();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue