public override int CopyPage(I4KbBatchWrites destI4KbBatchWrites, long pageNumber, PagerState pagerState) { long sizeToMap = AllocationGranularity; var distanceFromStart = (pageNumber % NumberOfPagesInAllocationGranularity); var allocationStartPosition = pageNumber - distanceFromStart; var offset = allocationStartPosition * Constants.Storage.PageSize; var mmflags = _copyOnWriteMode ? MmapFlags.MAP_PRIVATE : MmapFlags.MAP_SHARED; var result = Syscall.mmap64(IntPtr.Zero, (UIntPtr)sizeToMap, MmapProts.PROT_READ | MmapProts.PROT_WRITE, mmflags, _fd, offset); try { if (result.ToInt64() == -1) //system didn't succeed in mapping the address where we wanted { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, $"Unable to map (default view size) {sizeToMap/Constants.Size.Kilobyte:#,#0} kb for page {pageNumber} starting at {allocationStartPosition} on {FileName}"); } var pageHeader = (PageHeader *)(result.ToInt64() + distanceFromStart * Constants.Storage.PageSize); int numberOfPages = 1; if ((pageHeader->Flags & PageFlags.Overflow) == PageFlags.Overflow) { numberOfPages = VirtualPagerLegacyExtensions.GetNumberOfOverflowPages(pageHeader->OverflowSize); } if (numberOfPages + distanceFromStart > NumberOfPagesInAllocationGranularity) { Syscall.munmap(result, (UIntPtr)sizeToMap); result = new IntPtr(-1); sizeToMap = NearestSizeToAllocationGranularity((numberOfPages + distanceFromStart) * Constants.Storage.PageSize); result = Syscall.mmap64(IntPtr.Zero, (UIntPtr)sizeToMap, MmapProts.PROT_READ | MmapProts.PROT_WRITE, mmflags, _fd, offset); if (result.ToInt64() == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, $"Unable to map {sizeToMap/Constants.Size.Kilobyte:#,#0} kb for page {pageNumber} starting at {allocationStartPosition} on {FileName}"); } pageHeader = (PageHeader *)(result.ToInt64() + (distanceFromStart * Constants.Storage.PageSize)); } const int adjustPageSize = (Constants.Storage.PageSize) / (4 * Constants.Size.Kilobyte); destI4KbBatchWrites.Write(pageHeader->PageNumber * adjustPageSize, numberOfPages * adjustPageSize, (byte *)pageHeader); return(numberOfPages); } finally { if (result.ToInt64() != -1) { Syscall.munmap(result, (UIntPtr)sizeToMap); } } }