[Veritas] Implement file operations.

This commit is contained in:
2026-03-01 00:38:15 +00:00
parent 268e1ca3c5
commit 0fed8532e5
3 changed files with 114 additions and 11 deletions

View File

@@ -29,6 +29,7 @@
using System;
using System.Collections.Generic;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
using Aaru.Helpers;
@@ -54,6 +55,100 @@ public sealed partial class VxFS
return ErrorNumber.NoError;
}
/// <inheritdoc />
public ErrorNumber OpenFile(string path, out IFileNode node)
{
node = null;
if(!_mounted) return ErrorNumber.AccessDenied;
if(string.IsNullOrEmpty(path) || path == "/") return ErrorNumber.IsDirectory;
ErrorNumber errno = LookupInode(path, out DiskInode inode, out uint inodeNumber);
if(errno != ErrorNumber.NoError) return errno;
var fileType = (VxfsFileType)(inode.vdi_mode & VXFS_TYPE_MASK);
if(fileType == VxfsFileType.Dir) return ErrorNumber.IsDirectory;
node = new VxFsFileNode
{
Path = path,
Length = (long)inode.vdi_size,
Offset = 0,
InodeNumber = inodeNumber,
Inode = inode
};
return ErrorNumber.NoError;
}
/// <inheritdoc />
public ErrorNumber CloseFile(IFileNode node)
{
if(!_mounted) return ErrorNumber.AccessDenied;
if(node is not VxFsFileNode) return ErrorNumber.InvalidArgument;
return ErrorNumber.NoError;
}
/// <inheritdoc />
public ErrorNumber ReadFile(IFileNode node, long length, byte[] buffer, out long read)
{
read = 0;
if(!_mounted) return ErrorNumber.AccessDenied;
if(node is not VxFsFileNode fileNode) return ErrorNumber.InvalidArgument;
if(buffer == null) return ErrorNumber.InvalidArgument;
if(fileNode.Offset < 0 || fileNode.Offset >= fileNode.Length) return ErrorNumber.InvalidArgument;
long toRead = length;
if(fileNode.Offset + toRead > fileNode.Length) toRead = fileNode.Length - fileNode.Offset;
if(toRead <= 0) return ErrorNumber.NoError;
if(toRead > buffer.Length) toRead = buffer.Length;
int blockSize = _superblock.vs_bsize;
long bytesRead = 0;
long currentOffset = fileNode.Offset;
while(bytesRead < toRead)
{
var blockNum = (uint)(currentOffset / blockSize);
var offsetInBlock = (int)(currentOffset % blockSize);
byte[] blockData = ReadInodeBlock(fileNode.Inode, blockNum);
if(blockData == null)
{
// Sparse block / hole — fill with zeros
long bytesToZero = Math.Min(blockSize - offsetInBlock, toRead - bytesRead);
Array.Clear(buffer, (int)bytesRead, (int)bytesToZero);
bytesRead += bytesToZero;
currentOffset += bytesToZero;
continue;
}
long bytesToCopy = Math.Min(blockSize - offsetInBlock, toRead - bytesRead);
Array.Copy(blockData, offsetInBlock, buffer, bytesRead, bytesToCopy);
bytesRead += bytesToCopy;
currentOffset += bytesToCopy;
}
read = bytesRead;
fileNode.Offset += bytesRead;
return ErrorNumber.NoError;
}
/// <summary>Resolves a path to its inode</summary>
/// <param name="path">Path to resolve</param>
/// <param name="inode">Output inode</param>

View File

@@ -46,4 +46,23 @@ public sealed partial class VxFS
/// <inheritdoc />
public string Path { get; init; }
}
/// <summary>File node for reading file contents</summary>
sealed class VxFsFileNode : IFileNode
{
/// <summary>The inode number</summary>
internal uint InodeNumber { get; init; }
/// <summary>The file's disk inode containing metadata and extent pointers</summary>
internal DiskInode Inode { get; init; }
/// <inheritdoc />
public string Path { get; init; }
/// <inheritdoc />
public long Length { get; init; }
/// <inheritdoc />
public long Offset { get; set; }
}
}

View File

@@ -28,7 +28,6 @@
using System;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
namespace Aaru.Filesystems;
@@ -40,14 +39,4 @@ public sealed partial class VxFS
/// <inheritdoc />
public ErrorNumber ReadLink(string path, out string dest) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber OpenFile(string path, out IFileNode node) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber CloseFile(IFileNode node) => throw new NotImplementedException();
/// <inheritdoc />
public ErrorNumber ReadFile(IFileNode node, long length, byte[] buffer, out long read) =>
throw new NotImplementedException();
}