< prev index next >

src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java

Print this page
rev 16200 : 8168628: (fc) SIGBUS when extending file size to map it
Summary: Synchronize file extension and subsequent map0(); on Linux use fallocate64() instead of ftruncate64().
Reviewed-by: rehn, simonis, alanb

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -896,10 +896,13 @@
             begin();
             ti = threads.add();
             if (!isOpen())
                 return null;
 
+            long mapSize;
+            int pagePosition;
+            synchronized (positionLock) {
             long filesize;
             do {
                 filesize = nd.size(fd);
             } while ((filesize == IOStatus.INTERRUPTED) && isOpen());
             if (!isOpen())

@@ -910,34 +913,35 @@
                     throw new IOException("Channel not open for writing " +
                         "- cannot extend file to required size");
                 }
                 int rv;
                 do {
-                    rv = nd.truncate(fd, position + size);
+                        rv = nd.allocate(fd, position + size);
                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
                 if (!isOpen())
                     return null;
             }
+
             if (size == 0) {
                 addr = 0;
                 // a valid file descriptor is not required
                 FileDescriptor dummy = new FileDescriptor();
                 if ((!writable) || (imode == MAP_RO))
                     return Util.newMappedByteBufferR(0, 0, dummy, null);
                 else
                     return Util.newMappedByteBuffer(0, 0, dummy, null);
             }
 
-            int pagePosition = (int)(position % allocationGranularity);
+                pagePosition = (int)(position % allocationGranularity);
             long mapPosition = position - pagePosition;
-            long mapSize = size + pagePosition;
+                mapSize = size + pagePosition;
             try {
-                // If no exception was thrown from map0, the address is valid
+                    // If map0 did not throw an exception, the address is valid
                 addr = map0(imode, mapPosition, mapSize);
             } catch (OutOfMemoryError x) {
-                // An OutOfMemoryError may indicate that we've exhausted memory
-                // so force gc and re-attempt map
+                    // An OutOfMemoryError may indicate that we've exhausted
+                    // memory so force gc and re-attempt map
                 System.gc();
                 try {
                     Thread.sleep(100);
                 } catch (InterruptedException y) {
                     Thread.currentThread().interrupt();

@@ -947,10 +951,11 @@
                 } catch (OutOfMemoryError y) {
                     // After a second OOME, fail
                     throw new IOException("Map failed", y);
                 }
             }
+            } // synchronized
 
             // On Windows, and potentially other platforms, we need an open
             // file descriptor for some mapping operations.
             FileDescriptor mfd;
             try {
< prev index next >