Пример #1
0
        public static bool IsMounted(this FileSystemClient fs, U8Span mountName)
        {
            Result      rc;
            bool        isMounted;
            Span <byte> logBuffer = stackalloc byte[0x30];

            if (fs.Impl.IsEnabledAccessLog() && fs.Impl.IsEnabledFileSystemAccessorAccessLog(mountName))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fs.Impl.IsMounted(out isMounted, mountName);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                ReadOnlySpan <byte> boolString = AccessLogImpl.ConvertFromBoolToAccessLogBooleanValue(isMounted);
                sb.Append(LogName).Append(mountName).Append(LogIsMounted).Append(boolString).Append((byte)'"');

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = fs.Impl.IsMounted(out isMounted, mountName);
            }
            fs.Impl.LogErrorMessage(rc);
            Abort.DoAbortUnless(rc.IsSuccess());

            return(isMounted);
        }
Пример #2
0
        public FileRegion(long offset, long size)
        {
            Offset = offset;
            Size   = size;

            Abort.DoAbortUnless(size >= 0);
        }
Пример #3
0
        public static Result IterateDirectoryRecursively(IFileSystem fs, U8Span rootPath, Span <byte> workPath,
                                                         ref DirectoryEntry dirEntry, FsIterationTask onEnterDir, FsIterationTask onExitDir, FsIterationTask onFile)
        {
            Abort.DoAbortUnless(workPath.Length >= PathTool.EntryNameLengthMax + 1);

            // Get size of the root path.
            int rootPathLen = StringUtils.GetLength(rootPath, PathTool.EntryNameLengthMax + 1);

            if (rootPathLen > PathTool.EntryNameLengthMax)
            {
                return(ResultFs.TooLongPath.Log());
            }

            // Copy root path in, add a / if necessary.
            rootPath.Value.Slice(0, rootPathLen).CopyTo(workPath);
            if (!PathTool.IsSeparator(workPath[rootPathLen - 1]))
            {
                workPath[rootPathLen++] = StringTraits.DirectorySeparator;
            }

            // Make sure the result path is still valid.
            if (rootPathLen > PathTool.EntryNameLengthMax)
            {
                return(ResultFs.TooLongPath.Log());
            }

            workPath[rootPathLen] = StringTraits.NullTerminator;

            return(IterateDirectoryRecursivelyImpl(fs, workPath, ref dirEntry, onEnterDir, onExitDir, onFile));
        }
Пример #4
0
        protected virtual void Dispose(bool disposing)
        {
            if (!disposing)
            {
                return;
            }

            using (ScopedLock.Lock(ref _openListLock))
            {
                Abort.DoAbortUnless(_openFiles.Count == 0, ResultFs.FileNotClosed.Value,
                                    "All files must be closed before unmounting.");

                Abort.DoAbortUnless(_openDirectories.Count == 0, ResultFs.DirectoryNotClosed.Value,
                                    "All directories must be closed before unmounting.");

                if (_isPathCacheAttached)
                {
                    throw new NotImplementedException();
                }
            }

            _saveDataAttributeGetter?.Dispose();
            _saveDataAttributeGetter = null;

            _mountNameGenerator?.Dispose();
            _mountNameGenerator = null;

            _fileSystem?.Dispose();
            _fileSystem = null;
        }
Пример #5
0
        public static unsafe Result CopyDirectoryRecursively(IFileSystem destFileSystem, IFileSystem sourceFileSystem,
                                                             U8Span destPath, U8Span sourcePath, Span <byte> workBuffer)
        {
            var destPathBuf  = new FsPath();
            int originalSize = StringUtils.Copy(destPathBuf.Str, destPath);

            Abort.DoAbortUnless(originalSize < Unsafe.SizeOf <FsPath>());

            // Pin and recreate the span because C# can't use byref-like types in a closure
            int workBufferSize = workBuffer.Length;

            fixed(byte *pWorkBuffer = workBuffer)
            {
                // Copy the pointer to workaround CS1764.
                // IterateDirectoryRecursively won't store the delegate anywhere, so it should be safe
                byte *pWorkBuffer2 = pWorkBuffer;

                Result OnEnterDir(U8Span path, ref DirectoryEntry entry)
                {
                    // Update path, create new dir.
                    StringUtils.Concat(SpanHelpers.AsByteSpan(ref destPathBuf), entry.Name);
                    StringUtils.Concat(SpanHelpers.AsByteSpan(ref destPathBuf), DirectorySeparator);

                    return(destFileSystem.CreateDirectory(destPathBuf));
                }

                Result OnExitDir(U8Span path, ref DirectoryEntry entry)
                {
                    // Check we have a parent directory.
                    int len = StringUtils.GetLength(SpanHelpers.AsByteSpan(ref destPathBuf));

                    if (len < 2)
                    {
                        return(ResultFs.InvalidPathFormat.Log());
                    }

                    // Find previous separator, add null terminator
                    int cur = len - 2;

                    while (!PathTool.IsSeparator(SpanHelpers.AsByteSpan(ref destPathBuf)[cur]) && cur > 0)
                    {
                        cur--;
                    }

                    SpanHelpers.AsByteSpan(ref destPathBuf)[cur + 1] = StringTraits.NullTerminator;

                    return(Result.Success);
                }

                Result OnFile(U8Span path, ref DirectoryEntry entry)
                {
                    var buffer = new Span <byte>(pWorkBuffer2, workBufferSize);

                    return(CopyFile(destFileSystem, sourceFileSystem, destPathBuf, path, ref entry, buffer));
                }

                return(IterateDirectoryRecursively(sourceFileSystem, sourcePath, OnEnterDir, OnExitDir, OnFile));
            }
        }
Пример #6
0
        private void Write(ReadOnlySpan <byte> source)
        {
            // Bounds check.
            Abort.DoAbortUnless(_offset + source.Length <= _buffer.Length &&
                                _offset + source.Length > _offset);

            source.CopyTo(_buffer.Slice(_offset));
            _offset += source.Length;
        }
Пример #7
0
        public HorizonClient CreatePrivilegedHorizonClient()
        {
            ulong processId = Interlocked.Increment(ref _currentInitialProcessId);

            Abort.DoAbortUnless(processId <= InitialProcessCountMax, "Created too many privileged clients.");

            // Todo: Register process with FS

            return(new HorizonClient(this, new ProcessId(processId)));
        }
Пример #8
0
        public void Unlock()
        {
            Abort.DoAbortUnless(IsLockedByCurrentThread());

            _recursiveCount--;
            if (_recursiveCount == 0)
            {
                _cs.Leave();
            }
        }
Пример #9
0
        public void Lock()
        {
            if (!IsLockedByCurrentThread())
            {
                _cs.Enter();
            }

            _recursiveCount++;
            Abort.DoAbortUnless(_recursiveCount != 0);
        }
Пример #10
0
        public bool TryLock()
        {
            if (!IsLockedByCurrentThread())
            {
                if (!_cs.TryEnter())
                {
                    return(false);
                }
            }

            _recursiveCount++;
            Abort.DoAbortUnless(_recursiveCount != 0);

            return(true);
        }
Пример #11
0
        public static int GetNodeL2Count(long nodeSize, long entrySize, int entryCount)
        {
            int offsetCountPerNode = GetOffsetCount(nodeSize);
            int entrySetCount      = GetEntrySetCount(nodeSize, entrySize, entryCount);

            if (entrySetCount <= offsetCountPerNode)
            {
                return(0);
            }

            int nodeL2Count = Utilities.DivideByRoundUp(entrySetCount, offsetCountPerNode);

            Abort.DoAbortUnless(nodeL2Count <= offsetCountPerNode);

            return(Utilities.DivideByRoundUp(entrySetCount - (offsetCountPerNode - (nodeL2Count - 1)), offsetCountPerNode));
        }
Пример #12
0
        public static void Unmount(this FileSystemClient fs, U8Span mountName)
        {
            Result      rc;
            Span <byte> logBuffer = stackalloc byte[0x30];

            if (fs.Impl.IsEnabledAccessLog() && fs.Impl.IsEnabledFileSystemAccessorAccessLog(mountName))
            {
                Tick start = fs.Hos.Os.GetSystemTick();
                rc = fs.Impl.Unmount(mountName);
                Tick end = fs.Hos.Os.GetSystemTick();

                var sb = new U8StringBuilder(logBuffer, true);
                sb.Append(LogName).Append(mountName).Append((byte)'"');

                fs.Impl.OutputAccessLog(rc, start, end, null, new U8Span(sb.Buffer));
            }
            else
            {
                rc = fs.Impl.Unmount(mountName);
            }
            fs.Impl.LogErrorMessage(rc);
            Abort.DoAbortUnless(rc.IsSuccess());
        }
Пример #13
0
        public static Result CopyFile(IFileSystem destFileSystem, IFileSystem sourceFileSystem, U8Span destParentPath,
                                      U8Span sourcePath, ref DirectoryEntry entry, Span <byte> workBuffer)
        {
            // Open source file.
            Result rc = sourceFileSystem.OpenFile(out IFile sourceFile, sourcePath, OpenMode.Read);

            if (rc.IsFailure())
            {
                return(rc);
            }

            using (sourceFile)
            {
                // Open dest file.
                FsPath destPath;
                unsafe { _ = &destPath; } // workaround for CS0165

                var sb = new U8StringBuilder(destPath.Str);
                sb.Append(destParentPath).Append(entry.Name);

                Abort.DoAbortUnless(sb.Length < Unsafe.SizeOf <FsPath>());

                rc = destFileSystem.CreateFile(new U8Span(destPath.Str), entry.Size, CreateFileOptions.None);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                rc = destFileSystem.OpenFile(out IFile destFile, new U8Span(destPath.Str), OpenMode.Write);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                using (destFile)
                {
                    // Read/Write file in work buffer sized chunks.
                    long remaining = entry.Size;
                    long offset    = 0;

                    while (remaining > 0)
                    {
                        rc = sourceFile.Read(out long bytesRead, offset, workBuffer, ReadOption.None);
                        if (rc.IsFailure())
                        {
                            return(rc);
                        }

                        rc = destFile.Write(offset, workBuffer.Slice(0, (int)bytesRead), WriteOption.None);
                        if (rc.IsFailure())
                        {
                            return(rc);
                        }

                        remaining -= bytesRead;
                        offset    += bytesRead;
                    }
                }
            }

            return(Result.Success);
        }
Пример #14
0
 public void Unlock()
 {
     Abort.DoAbortUnless(IsLockedByCurrentThread());
     _cs.Leave();
 }
Пример #15
0
 public bool TryLock()
 {
     Abort.DoAbortUnless(!IsLockedByCurrentThread());
     return(_cs.TryEnter());
 }
Пример #16
0
 public void Lock()
 {
     Abort.DoAbortUnless(!IsLockedByCurrentThread());
     _cs.Enter();
 }