Example #1
0
        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;
            }
        }
Example #2
0
        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]
            });
        }
Example #3
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());
        }
Example #4
0
        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);
        }