< prev index next >

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

Print this page
rev 16220 : 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 /*
   2  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 881         if (mode == MapMode.READ_ONLY)
 882             imode = MAP_RO;
 883         else if (mode == MapMode.READ_WRITE)
 884             imode = MAP_RW;
 885         else if (mode == MapMode.PRIVATE)
 886             imode = MAP_PV;
 887         assert (imode >= 0);
 888         if ((mode != MapMode.READ_ONLY) && !writable)
 889             throw new NonWritableChannelException();
 890         if (!readable)
 891             throw new NonReadableChannelException();
 892 
 893         long addr = -1;
 894         int ti = -1;
 895         try {
 896             begin();
 897             ti = threads.add();
 898             if (!isOpen())
 899                 return null;
 900 



 901             long filesize;
 902             do {
 903                 filesize = nd.size(fd);
 904             } while ((filesize == IOStatus.INTERRUPTED) && isOpen());
 905             if (!isOpen())
 906                 return null;
 907 
 908             if (filesize < position + size) { // Extend file size
 909                 if (!writable) {
 910                     throw new IOException("Channel not open for writing " +
 911                         "- cannot extend file to required size");
 912                 }
 913                 int rv;
 914                 do {
 915                     rv = nd.truncate(fd, position + size);
 916                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 917                 if (!isOpen())
 918                     return null;
 919             }

 920             if (size == 0) {
 921                 addr = 0;
 922                 // a valid file descriptor is not required
 923                 FileDescriptor dummy = new FileDescriptor();
 924                 if ((!writable) || (imode == MAP_RO))
 925                     return Util.newMappedByteBufferR(0, 0, dummy, null);
 926                 else
 927                     return Util.newMappedByteBuffer(0, 0, dummy, null);
 928             }
 929 
 930             int pagePosition = (int)(position % allocationGranularity);
 931             long mapPosition = position - pagePosition;
 932             long mapSize = size + pagePosition;
 933             try {
 934                 // If no exception was thrown from map0, the address is valid
 935                 addr = map0(imode, mapPosition, mapSize);
 936             } catch (OutOfMemoryError x) {
 937                 // An OutOfMemoryError may indicate that we've exhausted memory
 938                 // so force gc and re-attempt map
 939                 System.gc();
 940                 try {
 941                     Thread.sleep(100);
 942                 } catch (InterruptedException y) {
 943                     Thread.currentThread().interrupt();
 944                 }
 945                 try {
 946                     addr = map0(imode, mapPosition, mapSize);
 947                 } catch (OutOfMemoryError y) {
 948                     // After a second OOME, fail
 949                     throw new IOException("Map failed", y);
 950                 }
 951             }

 952 
 953             // On Windows, and potentially other platforms, we need an open
 954             // file descriptor for some mapping operations.
 955             FileDescriptor mfd;
 956             try {
 957                 mfd = nd.duplicateForMapping(fd);
 958             } catch (IOException ioe) {
 959                 unmap0(addr, mapSize);
 960                 throw ioe;
 961             }
 962 
 963             assert (IOStatus.checkAll(addr));
 964             assert (addr % allocationGranularity == 0);
 965             int isize = (int)size;
 966             Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
 967             if ((!writable) || (imode == MAP_RO)) {
 968                 return Util.newMappedByteBufferR(isize,
 969                                                  addr + pagePosition,
 970                                                  mfd,
 971                                                  um);


   1 /*
   2  * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 881         if (mode == MapMode.READ_ONLY)
 882             imode = MAP_RO;
 883         else if (mode == MapMode.READ_WRITE)
 884             imode = MAP_RW;
 885         else if (mode == MapMode.PRIVATE)
 886             imode = MAP_PV;
 887         assert (imode >= 0);
 888         if ((mode != MapMode.READ_ONLY) && !writable)
 889             throw new NonWritableChannelException();
 890         if (!readable)
 891             throw new NonReadableChannelException();
 892 
 893         long addr = -1;
 894         int ti = -1;
 895         try {
 896             begin();
 897             ti = threads.add();
 898             if (!isOpen())
 899                 return null;
 900 
 901             long mapSize;
 902             int pagePosition;
 903             synchronized (positionLock) {
 904                 long filesize;
 905                 do {
 906                     filesize = nd.size(fd);
 907                 } while ((filesize == IOStatus.INTERRUPTED) && isOpen());
 908                 if (!isOpen())
 909                     return null;
 910 
 911                 if (filesize < position + size) { // Extend file size
 912                     if (!writable) {
 913                         throw new IOException("Channel not open for writing " +
 914                             "- cannot extend file to required size");
 915                     }
 916                     int rv;
 917                     do {
 918                         rv = nd.allocate(fd, position + size);
 919                     } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 920                     if (!isOpen())
 921                         return null;
 922                 }
 923 
 924                 if (size == 0) {
 925                     addr = 0;
 926                     // a valid file descriptor is not required
 927                     FileDescriptor dummy = new FileDescriptor();
 928                     if ((!writable) || (imode == MAP_RO))
 929                         return Util.newMappedByteBufferR(0, 0, dummy, null);
 930                     else
 931                         return Util.newMappedByteBuffer(0, 0, dummy, null);
 932                 }
 933 
 934                 pagePosition = (int)(position % allocationGranularity);
 935                 long mapPosition = position - pagePosition;
 936                 mapSize = size + pagePosition;
 937                 try {
 938                     // If map0 did not throw an exception, the address is valid
 939                     addr = map0(imode, mapPosition, mapSize);
 940                 } catch (OutOfMemoryError x) {
 941                     // An OutOfMemoryError may indicate that we've exhausted
 942                     // memory so force gc and re-attempt map
 943                     System.gc();
 944                     try {
 945                         Thread.sleep(100);
 946                     } catch (InterruptedException y) {
 947                         Thread.currentThread().interrupt();
 948                     }
 949                     try {
 950                         addr = map0(imode, mapPosition, mapSize);
 951                     } catch (OutOfMemoryError y) {
 952                         // After a second OOME, fail
 953                         throw new IOException("Map failed", y);
 954                     }
 955                 }
 956             } // synchronized
 957 
 958             // On Windows, and potentially other platforms, we need an open
 959             // file descriptor for some mapping operations.
 960             FileDescriptor mfd;
 961             try {
 962                 mfd = nd.duplicateForMapping(fd);
 963             } catch (IOException ioe) {
 964                 unmap0(addr, mapSize);
 965                 throw ioe;
 966             }
 967 
 968             assert (IOStatus.checkAll(addr));
 969             assert (addr % allocationGranularity == 0);
 970             int isize = (int)size;
 971             Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
 972             if ((!writable) || (imode == MAP_RO)) {
 973                 return Util.newMappedByteBufferR(isize,
 974                                                  addr + pagePosition,
 975                                                  mfd,
 976                                                  um);


< prev index next >