2727 * @summary Test for ExtendedOpenOption.DIRECT flag
2828 * @requires (os.family == "linux" | os.family == "aix")
2929 * @library /test/lib
30+ * @modules java.base/sun.nio.ch:+open java.base/java.io:+open
3031 * @build jdk.test.lib.Platform
3132 * @run main/native DirectIOTest
3233 */
3334
3435import java .io .*;
36+ import java .lang .reflect .Field ;
3537import java .nio .ByteBuffer ;
3638import java .nio .CharBuffer ;
3739import java .nio .channels .*;
4749public class DirectIOTest {
4850
4951 private static final int BASE_SIZE = 4096 ;
52+ private static final int TRIES = 3 ;
53+
54+ public static int getFD (FileChannel channel ) throws Exception {
55+ Field fFdFd = channel .getClass ().getDeclaredField ("fd" );
56+ fFdFd .setAccessible (true );
57+ FileDescriptor fd = (FileDescriptor ) fFdFd .get (channel );
58+
59+ Field fFd = FileDescriptor .class .getDeclaredField ("fd" );
60+ fFd .setAccessible (true );
61+ return fFd .getInt (fd );
62+ }
63+
64+ private static void testWrite (Path p , long blockSize ) throws Exception {
65+ try (FileChannel fc = FileChannel .open (p ,
66+ StandardOpenOption .READ ,
67+ StandardOpenOption .WRITE ,
68+ ExtendedOpenOption .DIRECT )) {
69+ int fd = getFD (fc );
5070
51- private static int testWrite (Path p , long blockSize ) throws Exception {
52- try (FileChannel fc = FileChannel .open (p , StandardOpenOption .WRITE ,
53- ExtendedOpenOption .DIRECT )) {
5471 int bs = (int )blockSize ;
5572 int size = Math .max (BASE_SIZE , bs );
5673 int alignment = bs ;
@@ -60,22 +77,55 @@ private static int testWrite(Path p, long blockSize) throws Exception {
6077 for (int j = 0 ; j < size ; j ++) {
6178 src .put ((byte )0 );
6279 }
63- src .flip ();
64- fc .write (src );
65- return size ;
80+
81+ // If there is AV or other FS tracing software, it may cache the file
82+ // contents on first access, even though we have asked for DIRECT here.
83+ // Do several attempts to make test more resilient.
84+
85+ for (int t = 0 ; t < TRIES ; t ++) {
86+ flushFileCache (size , fd );
87+ src .flip ();
88+ fc .position (0 );
89+ fc .write (src );
90+ if (!isFileInCache (size , fd )) {
91+ return ;
92+ }
93+ }
94+
95+ throw new RuntimeException ("DirectIO is not working properly with " +
96+ "write. File still exists in cache!" );
6697 }
6798 }
6899
69- private static int testRead (Path p , long blockSize ) throws Exception {
70- try (FileChannel fc = FileChannel .open (p , ExtendedOpenOption .DIRECT )) {
100+ private static void testRead (Path p , long blockSize ) throws Exception {
101+ try (FileChannel fc = FileChannel .open (p ,
102+ StandardOpenOption .READ ,
103+ ExtendedOpenOption .DIRECT )) {
104+ int fd = getFD (fc );
105+
71106 int bs = (int )blockSize ;
72107 int size = Math .max (BASE_SIZE , bs );
73108 int alignment = bs ;
74109 ByteBuffer dest = ByteBuffer .allocateDirect (size + alignment - 1 )
75110 .alignedSlice (alignment );
76111 assert dest .capacity () != 0 ;
77- fc .read (dest );
78- return size ;
112+
113+ // If there is AV or other FS tracing software, it may cache the file
114+ // contents on first access, even though we have asked for DIRECT here.
115+ // Do several attempts to make test more resilient.
116+
117+ for (int t = 0 ; t < TRIES ; t ++) {
118+ flushFileCache (size , fd );
119+ dest .clear ();
120+ fc .position (0 );
121+ fc .read (dest );
122+ if (!isFileInCache (size , fd )) {
123+ return ;
124+ }
125+ }
126+
127+ throw new RuntimeException ("DirectIO is not working properly with " +
128+ "read. File still exists in cache!" );
79129 }
80130 }
81131
@@ -84,12 +134,8 @@ public static Path createTempFile() throws IOException {
84134 Paths .get (System .getProperty ("test.dir" , "." )), "test" , null );
85135 }
86136
87- private static boolean isFileInCache (int size , Path p ) {
88- String path = p .toString ();
89- return isFileInCache0 (size , path );
90- }
91-
92- private static native boolean isFileInCache0 (int size , String path );
137+ private static native boolean flushFileCache (int size , int fd );
138+ private static native boolean isFileInCache (int size , int fd );
93139
94140 public static void main (String [] args ) throws Exception {
95141 Path p = createTempFile ();
@@ -98,16 +144,8 @@ public static void main(String[] args) throws Exception {
98144 System .loadLibrary ("DirectIO" );
99145
100146 try {
101- int size = testWrite (p , blockSize );
102- if (isFileInCache (size , p )) {
103- throw new RuntimeException ("DirectIO is not working properly with "
104- + "write. File still exists in cache!" );
105- }
106- size = testRead (p , blockSize );
107- if (isFileInCache (size , p )) {
108- throw new RuntimeException ("DirectIO is not working properly with "
109- + "read. File still exists in cache!" );
110- }
147+ testWrite (p , blockSize );
148+ testRead (p , blockSize );
111149 } finally {
112150 Files .delete (p );
113151 }
0 commit comments