public PosixJournalWriter(StorageEnvironmentOptions options, VoronPathSetting filename, long journalSize) { try { _options = options; _filename = filename; _maxNumberOf4KbPerSingleWrite = int.MaxValue / (4 * Constants.Size.Kilobyte); _fd = Syscall.open(filename.FullPath, OpenFlags.O_WRONLY | options.PosixOpenFlags | PerPlatformValues.OpenFlags.O_CREAT, FilePermissions.S_IWUSR | FilePermissions.S_IRUSR); if (_fd == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when opening " + filename); } if (RunningOnMacOsx) { // mac doesn't support O_DIRECT, we fcntl instead: var rc = Syscall.fcntl(_fd, FcntlCommands.F_NOCACHE, (IntPtr)1); if (rc != 0) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when fcntl F_NOCACHE for " + filename); } } var length = new FileInfo(filename.FullPath).Length; if (length < journalSize) { length = journalSize; try { PosixHelper.AllocateFileSpace(options, _fd, journalSize, filename.FullPath); } catch (Exception) { Syscall.close(_fd); throw; } } if (Syscall.CheckSyncDirectoryAllowed(_filename.FullPath) && Syscall.SyncDirectory(filename.FullPath) == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when syncing dir for on " + filename); } NumberOfAllocated4Kb = (int)(length / (4 * Constants.Size.Kilobyte)); } catch { Dispose(); throw; } }
public Posix32BitsMemoryMapPager(StorageEnvironmentOptions options, VoronPathSetting file, long?initialFileSize = null, bool usePageProtection = false) : base(options, usePageProtection) { _options = options; FileName = file; if (Options.CopyOnWriteMode) { ThrowNotSupportedOption(file.FullPath); } _copyOnWriteMode = options.CopyOnWriteMode && file.FullPath.EndsWith(Constants.DatabaseFilename); _isSyncDirAllowed = Syscall.CheckSyncDirectoryAllowed(FileName.FullPath); PosixHelper.EnsurePathExists(FileName.FullPath); Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.OSX) == false); // O_LARGEFILE not exists in mac and supported by default (however we do not run on mac 32bit..) _fd = Syscall.open(file.FullPath, OpenFlags.O_RDWR | PerPlatformValues.OpenFlags.O_CREAT | PerPlatformValues.OpenFlags.O_LARGEFILE, FilePermissions.S_IWUSR | FilePermissions.S_IRUSR); if (_fd == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when opening " + file); } _totalAllocationSize = GetFileSize(); if (_totalAllocationSize == 0 && initialFileSize.HasValue) { _totalAllocationSize = NearestSizeToAllocationGranularity(initialFileSize.Value); } if (_totalAllocationSize == 0 || _totalAllocationSize % AllocationGranularity != 0 || _totalAllocationSize != GetFileSize()) { _totalAllocationSize = NearestSizeToAllocationGranularity(_totalAllocationSize); PosixHelper.AllocateFileSpace(_options, _fd, _totalAllocationSize, file.FullPath); } if (_isSyncDirAllowed && Syscall.SyncDirectory(file.FullPath) == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "sync dir for " + file); } NumberOfAllocatedPages = _totalAllocationSize / Constants.Storage.PageSize; SetPagerState(new PagerState(this) { Files = null, MapBase = null, AllocationInfos = new PagerState.AllocationInfo[0] }); }
public PosixMemoryMapPager(StorageEnvironmentOptions options, VoronPathSetting file, long?initialFileSize = null, bool usePageProtection = false) : base(options, canPrefetchAhead: true, usePageProtection: usePageProtection) { _options = options; FileName = file; _copyOnWriteMode = options.CopyOnWriteMode && file.FullPath.EndsWith(Constants.DatabaseFilename); _isSyncDirAllowed = Syscall.CheckSyncDirectoryAllowed(FileName.FullPath); PosixHelper.EnsurePathExists(FileName.FullPath); _fd = Syscall.open(file.FullPath, OpenFlags.O_RDWR | PerPlatformValues.OpenFlags.O_CREAT, FilePermissions.S_IWUSR | FilePermissions.S_IRUSR); if (_fd == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when opening " + file); } SysPageSize = Syscall.sysconf(PerPlatformValues.SysconfNames._SC_PAGESIZE); if (SysPageSize <= 0) // i.e. -1 because _SC_PAGESIZE defined differently on various platforms { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "Got SysPageSize <= 0 for " + FileName); } _totalAllocationSize = GetFileSize(); if (_totalAllocationSize == 0 && initialFileSize.HasValue) { _totalAllocationSize = NearestSizeToPageSize(initialFileSize.Value); } if (_totalAllocationSize == 0 || _totalAllocationSize % SysPageSize != 0 || _totalAllocationSize != GetFileSize()) { _totalAllocationSize = NearestSizeToPageSize(_totalAllocationSize); PosixHelper.AllocateFileSpace(_options, _fd, _totalAllocationSize, file.FullPath); } if (_isSyncDirAllowed && Syscall.SyncDirectory(file.FullPath) == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "sync dir for " + file); } NumberOfAllocatedPages = _totalAllocationSize / Constants.Storage.PageSize; SetPagerState(CreatePagerState()); }
protected internal override PagerState AllocateMorePages(long newLength) { if (DisposeOnceRunner.Disposed) { ThrowAlreadyDisposedException(); } var newLengthAfterAdjustment = NearestSizeToPageSize(newLength); if (newLengthAfterAdjustment <= _totalAllocationSize) { return(null); } var allocationSize = newLengthAfterAdjustment - _totalAllocationSize; PosixHelper.AllocateFileSpace(_options, _fd, _totalAllocationSize + allocationSize, FileName.FullPath); if (DeleteOnClose == false && _isSyncDirAllowed && Syscall.SyncDirectory(FileName.FullPath) == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err); } PagerState newPagerState = CreatePagerState(); if (newPagerState == null) { var errorMessage = string.Format( "Unable to allocate more pages - unsuccessfully tried to allocate continuous block of virtual memory with size = {0:##,###;;0} bytes", (_totalAllocationSize + allocationSize)); throw new OutOfMemoryException(errorMessage); } newPagerState.DebugVerify(newLengthAfterAdjustment); newPagerState.CopyPrefetchState(this._pagerState); SetPagerState(newPagerState); _totalAllocationSize += allocationSize; NumberOfAllocatedPages = _totalAllocationSize / Constants.Storage.PageSize; return(newPagerState); }
public void Truncate(long size) { var result = Syscall.ftruncate(_fd, (IntPtr)size); if (result == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when truncating " + _filename); } result = Syscall.FSync(_fd); if (result == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when fsycning " + _filename); } if (Syscall.CheckSyncDirectoryAllowed(_filename.FullPath) && Syscall.SyncDirectory(_filename.FullPath) == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when syncing dir for " + _filename); } }
protected internal override PagerState AllocateMorePages(long newLength) { var newLengthAfterAdjustment = NearestSizeToAllocationGranularity(newLength); if (newLengthAfterAdjustment <= _totalAllocationSize) { return(null); } var allocationSize = newLengthAfterAdjustment - _totalAllocationSize; PosixHelper.AllocateFileSpace(_options, _fd, _totalAllocationSize + allocationSize, FileName.FullPath); if (_isSyncDirAllowed && Syscall.SyncDirectory(FileName.FullPath) == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err); } _totalAllocationSize += allocationSize; NumberOfAllocatedPages = _totalAllocationSize / Constants.Storage.PageSize; return(null); }