public PosixJournalWriter(StorageEnvironmentOptions options, string filename, long journalSize) { _options = options; _filename = filename; _fd = Syscall.open(filename, OpenFlags.O_WRONLY | OpenFlags.O_DSYNC | OpenFlags.O_DIRECT | OpenFlags.O_CREAT, FilePermissions.S_IWUSR | FilePermissions.S_IRUSR); if (_fd == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err); } var result = Syscall.posix_fallocate(_fd, 0, (ulong)journalSize); if (result != 0) { PosixHelper.ThrowLastError(result); } if (PosixHelper.CheckSyncDirectoryAllowed(_filename) && PosixHelper.SyncDirectory(filename) == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err); } NumberOfAllocatedPages = (int)(journalSize / _options.PageSize); }
protected override PagerState AllocateMorePages(long newLength) { if (Disposed) { ThrowAlreadyDisposedException(); } var newLengthAfterAdjustment = NearestSizeToPageSize(newLength); if (newLengthAfterAdjustment <= _totalAllocationSize) { return(null); } var allocationSize = newLengthAfterAdjustment - _totalAllocationSize; PosixHelper.AllocateFileSpace(_fd, (ulong)(_totalAllocationSize + allocationSize)); if (_isSyncDirAllowed && PosixHelper.SyncDirectory(_file) == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.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); var tmp = PagerState; PagerState = newPagerState; tmp.Release(); //replacing the pager state --> so one less reference for it _totalAllocationSize += allocationSize; NumberOfAllocatedPages = _totalAllocationSize / _pageSize; return(newPagerState); }
public PosixMemoryMapPager(StorageEnvironmentOptions options, string file, long?initialFileSize = null, bool usePageProtection = false) : base(options, usePageProtection) { FileName = file; _copyOnWriteMode = options.CopyOnWriteMode && file.EndsWith(Constants.DatabaseFilename); _isSyncDirAllowed = PosixHelper.CheckSyncDirectoryAllowed(FileName); PosixHelper.EnsurePathExists(FileName); _fd = Syscall.open(file, OpenFlags.O_RDWR | OpenFlags.O_CREAT, FilePermissions.S_IWUSR | FilePermissions.S_IRUSR); if (_fd == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err, "when opening " + file); } SysPageSize = Syscall.sysconf(SysconfName._SC_PAGESIZE); _totalAllocationSize = GetFileSize(); if (_totalAllocationSize == 0 && initialFileSize.HasValue) { _totalAllocationSize = NearestSizeToPageSize(initialFileSize.Value); } if (_totalAllocationSize == 0 || _totalAllocationSize % SysPageSize != 0 || _totalAllocationSize != GetFileSize()) { _totalAllocationSize = NearestSizeToPageSize(_totalAllocationSize); PosixHelper.AllocateFileSpace(_fd, (ulong)_totalAllocationSize, file); } if (_isSyncDirAllowed && PosixHelper.SyncDirectory(file) == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err, "sync dir for " + file); } NumberOfAllocatedPages = _totalAllocationSize / PageSize; SetPagerState(CreatePagerState()); }
public PosixMemoryMapPager(int pageSize, string file, long?initialFileSize = null) : base(pageSize) { _file = file; _isSyncDirAllowed = PosixHelper.CheckSyncDirectoryAllowed(_file); PosixHelper.EnsurePathExists(_file); _fd = Syscall.open(file, OpenFlags.O_RDWR | OpenFlags.O_CREAT, FilePermissions.S_IWUSR | FilePermissions.S_IRUSR); if (_fd == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err); } SysPageSize = Syscall.sysconf(SysconfName._SC_PAGESIZE); _totalAllocationSize = GetFileSize(); if (_totalAllocationSize == 0 && initialFileSize.HasValue) { _totalAllocationSize = NearestSizeToPageSize(initialFileSize.Value); } if (_totalAllocationSize == 0 || _totalAllocationSize % SysPageSize != 0 || _totalAllocationSize != GetFileSize()) { _totalAllocationSize = NearestSizeToPageSize(_totalAllocationSize); PosixHelper.AllocateFileSpace(_fd, (ulong)_totalAllocationSize); } if (_isSyncDirAllowed && PosixHelper.SyncDirectory(file) == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err); } NumberOfAllocatedPages = _totalAllocationSize / _pageSize; PagerState.Release(); PagerState = CreatePagerState(); }
public PosixJournalWriter(StorageEnvironmentOptions options, string filename, long journalSize) { _options = options; _filename = filename; _maxNumberOfPagesPerSingleWrite = int.MaxValue / _options.PageSize; _fd = Syscall.open(filename, OpenFlags.O_WRONLY | options.PosixOpenFlags | OpenFlags.O_CREAT, FilePermissions.S_IWUSR | FilePermissions.S_IRUSR); if (_fd == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err, "when opening " + filename); } int result; if ((options.SafePosixOpenFlags & PerPlatformValues.OpenFlags.O_DIRECT) == 0) { // fallocate doesn't supported, we'll use lseek instead result = Syscall.AllocateUsingLseek(_fd, journalSize); } else { result = Syscall.posix_fallocate(_fd, IntPtr.Zero, (UIntPtr)journalSize); } if (result != 0) { PosixHelper.ThrowLastError(result, "when allocating " + filename); } if (PosixHelper.CheckSyncDirectoryAllowed(_filename) && PosixHelper.SyncDirectory(filename) == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err, "when syncing dir for on " + filename); } NumberOfAllocatedPages = (int)(journalSize / _options.PageSize); }
public void Truncate(long size) { var result = Syscall.ftruncate(_fd, (IntPtr)size); if (result == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err, "when truncating " + _filename); } result = Syscall.fsync(_fd); if (result == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err, "when fsycning " + _filename); } if (PosixHelper.CheckSyncDirectoryAllowed(_filename) && PosixHelper.SyncDirectory(_filename) == -1) { var err = Marshal.GetLastWin32Error(); PosixHelper.ThrowLastError(err, "when syncing dir for " + _filename); } }