Ejemplo n.º 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;
            }
        }