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);
        }
Example #2
0
        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());
        }
Example #4
0
        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();
        }
Example #5
0
        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);
        }
Example #6
0
        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);
            }
        }