static void closeFd(int fd) throws IOException { if (close(fd) == -1) { throw lastErrorToException(); } }
@Override protected void reopen() throws IOException { closeFd(fd()); EnumSet<OpenOption> options = EnumSet.noneOf(OpenOption.class); if (isReadOnly()) { options.add(OpenOption.READ_ONLY); } if ((mReopenOptions & REOPEN_SYNC_IO) != 0) { options.add(OpenOption.SYNC_IO); } if ((mReopenOptions & REOPEN_NON_DURABLE) != 0) { options.add(OpenOption.NON_DURABLE); } if ((mReopenOptions & REOPEN_DIRECT_IO) != 0) { options.add(OpenOption.DIRECT_IO); } mFileDescriptor = openFd(mFile, options); }
@Override protected long doLength() throws IOException { return lseekEndFd(fd(), 0); }
setMappingPtr(PosixFileIO.mmapFd(pageSize * pageCount, prot, flags, -1, 0)); fd = PosixFileIO.openFd(file, options); try { fileLen = PosixFileIO.lseekEndFd(fd, 0); PosixFileIO.lseekSetFd(fd, 0); } catch (IOException e) { try { PosixFileIO.closeFd(fd); } catch (IOException e2) { Utils.suppress(e, e2); try { fileLen = fio.length(); fd = PosixFileIO.openFd(file, options); } finally { fio.close(); PosixFileIO.ftruncateFd(fd, mappingSize); } catch (IOException e) { try { PosixFileIO.closeFd(fd); } catch (IOException e2) { Utils.suppress(e, e2); ptr = PosixFileIO.mmapFd(mappingSize, prot, flags, fd, 0); } catch (IOException e) { try { PosixFileIO.closeFd(fd);
static void fsyncFd(int fd) throws IOException { int result; if (Platform.isMac()) { result = fcntl(fd, 51); // F_FULLFSYNC } else { result = fsync(fd); } if (result == -1) { throw lastErrorToException(); } }
static void fdatasyncFd(int fd) throws IOException { int result; if (Platform.isMac()) { result = fcntl(fd, 51); // F_FULLFSYNC } else { result = fdatasync(fd); } if (result == -1) { throw lastErrorToException(); } }
@Override protected void doSync(boolean metadata) throws IOException { int fd = fd(); if (metadata) { fsyncFd(fd); } else { fdatasyncFd(fd); } }
PosixFileIO(File file, EnumSet<OpenOption> options) throws IOException { super(options); mFile = file; if (options.contains(OpenOption.NON_DURABLE)) { mReopenOptions = REOPEN_NON_DURABLE; } else { mReopenOptions = options.contains(OpenOption.SYNC_IO) ? REOPEN_SYNC_IO : 0; if (options.contains(OpenOption.CREATE)) { new JavaFileIO(file, options, 1, false).close(); } } mAccessLatch = new Latch(); mAccessLatch.acquireExclusive(); try { mFileDescriptor = openFd(file, options); } finally { mAccessLatch.releaseExclusive(); } mBufRef = new ThreadLocal<>(); if (options.contains(OpenOption.MAPPED)) { map(); } if (options.contains(OpenOption.CREATE)) { dirSync(file); } }
flags |= 040000; fd = open(file.getPath(), flags); throw lastErrorToException(); fadvise(fd, 0, 0, 1); // 1 = POSIX_FADV_RANDOM } catch (Throwable e) { try { closeFd(fd); } catch (IOException e2) { Utils.suppress(e, e2);
@Override protected void preallocate(long pos, long length) throws IOException { PlatformIO platform = platform(); if (platform == NullIO.INSTANCE) { // Don't have fallocate (or equivalent). Use default non-destructive zero-fill behavior. super.preallocate(pos, length); return; } // Uses posix_fallocate call to quickly allocate blocks and mark them as uninitialized. // If the filesystem supports fallocate then this requires no I/O to the data blocks, // and is much faster than zero-filling the file, which is the fallback behavior. // Since linux 2.6.31 fallocate is supported by at least btrfs, ext4, ocfs2, and // xfs filesystems. Ext4 on Linux 4.2.0 takes ~30 microseconds to fallocate 64MB, // compared to 27 milliseconds to zero-fill that same amount. // // On OSX, uses fcntl with command F_PREALLOCATE. int result = platform.fallocate(fd(), pos, length); if (result != 0) { // Note: the native call above does not set errno. throw new IOException(errorMessage(result)); } }
@Override protected void doSetLength(long length) throws IOException { ftruncateFd(fd(), length); }
@Override protected void preallocate(long pos, long length) throws IOException { if (FallocateHolder.INSTANCE == null) { // Don't have fallocate (or equivalent). Use default non-destructive zero-fill behavior. super.preallocate(pos, length); return; } // Uses posix_fallocate call to quickly allocate blocks and mark them as uninitialized. // If the filesystem supports fallocate then this requires no I/O to the data blocks, // and is much faster than zero-filling the file, which is the fallback behavior. // Since linux 2.6.31 fallocate is supported by at least btrfs, ext4, ocfs2, and // xfs filesystems. Ext4 on Linux 4.2.0 takes ~30 microseconds to fallocate 64MB, // compared to 27 milliseconds to zero-fill that same amount. // // On OSX, uses fcntl with command F_PREALLOCATE. int result = FallocateHolder.INSTANCE.fallocate(fd(), pos, length); if (result != 0) { // Note: the native call above does not set errno. throw new IOException(errorMessage(result)); } }
@Override public void close(Throwable cause) throws IOException { int fd; mAccessLatch.acquireExclusive(); try { fd = mFileDescriptor; if (fd == 0) { return; } mCause = cause; mFileDescriptor = 0; } finally { mAccessLatch.releaseExclusive(); } IOException ex = null; try { unmap(false); } catch (IOException e) { ex = e; } try { closeFd(fd); } catch (IOException e) { if (ex != null) { e.addSuppressed(ex); } throw e; } }