< 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 >