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); }
public FileRegion(long offset, long size) { Offset = offset; Size = size; Abort.DoAbortUnless(size >= 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)); }
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; }
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)); } }
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; }
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))); }
public void Unlock() { Abort.DoAbortUnless(IsLockedByCurrentThread()); _recursiveCount--; if (_recursiveCount == 0) { _cs.Leave(); } }
public void Lock() { if (!IsLockedByCurrentThread()) { _cs.Enter(); } _recursiveCount++; Abort.DoAbortUnless(_recursiveCount != 0); }
public bool TryLock() { if (!IsLockedByCurrentThread()) { if (!_cs.TryEnter()) { return(false); } } _recursiveCount++; Abort.DoAbortUnless(_recursiveCount != 0); return(true); }
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)); }
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()); }
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); }
public void Unlock() { Abort.DoAbortUnless(IsLockedByCurrentThread()); _cs.Leave(); }
public bool TryLock() { Abort.DoAbortUnless(!IsLockedByCurrentThread()); return(_cs.TryEnter()); }
public void Lock() { Abort.DoAbortUnless(!IsLockedByCurrentThread()); _cs.Enter(); }