Add initial ext2 read/write and formatting support
Register ext2 at boot, integrate mode-aware VFS opens and volume cleanup, and queue asynchronous transfers through a persistent worker. Validation: Pascal compiler check and git diff --check passed. Full build blocked by Docker engine HTTP 500; runtime and Linux interoperability remain unverified.
This commit is contained in:
1 parent
720ba46630
commit
c0c56a9c84
7 files changed
+1398
-5
No files matched your search
@@ -96,6 +96,7 @@ uses
|
|||||||
driver.net.dev.e1000,
|
driver.net.dev.e1000,
|
||||||
driver.bus.usb.ehci,
|
driver.bus.usb.ehci,
|
||||||
driver.storage.fs.fat32,
|
driver.storage.fs.fat32,
|
||||||
|
driver.storage.fs.ext2,
|
||||||
arch.x86.fault,
|
arch.x86.fault,
|
||||||
core.ds.fifo,
|
core.ds.fifo,
|
||||||
driver.storage.fs.mgr,
|
driver.storage.fs.mgr,
|
||||||
@@ -562,4 +563,4 @@ initialization
|
|||||||
EntryCount would silently discard their registrations. }
|
EntryCount would silently discard their registrations. }
|
||||||
registerBoot('boot.mgr.debug', @printBootEntriesTree, 'Debug: Print Boot Entries Tree', 'io.syslog');
|
registerBoot('boot.mgr.debug', @printBootEntriesTree, 'Debug: Print Boot Entries Tree', 'io.syslog');
|
||||||
|
|
||||||
end.
|
end.
|
||||||
@@ -222,6 +222,8 @@ type
|
|||||||
to read/write hooks. Also returns the current file size through the
|
to read/write hooks. Also returns the current file size through the
|
||||||
var parameter. Returning nil is legal (disables per-call fast-path). }
|
var parameter. Returning nil is legal (disables per-call fast-path). }
|
||||||
PPOpenFileHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; var fileSize : uint32) : pointer;
|
PPOpenFileHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; var fileSize : uint32) : pointer;
|
||||||
|
{ Mode-aware open avoids creating a missing file during a read-only open. }
|
||||||
|
PPOpenFileModeHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; allowCreate : boolean; var fileSize : uint32) : pointer;
|
||||||
{ Per-file close hook: frees the context allocated by openFileCallback. }
|
{ Per-file close hook: frees the context allocated by openFileCallback. }
|
||||||
PPCloseFileHook = procedure(ctx : pointer);
|
PPCloseFileHook = procedure(ctx : pointer);
|
||||||
|
|
||||||
@@ -324,6 +326,7 @@ type
|
|||||||
renameFileCallback : PPRenameFileHook;
|
renameFileCallback : PPRenameFileHook;
|
||||||
{ Per-file open/close — nil if FS does not cache per-file metadata }
|
{ Per-file open/close — nil if FS does not cache per-file metadata }
|
||||||
openFileCallback : PPOpenFileHook;
|
openFileCallback : PPOpenFileHook;
|
||||||
|
openFileModeCallback : PPOpenFileModeHook;
|
||||||
closeFileCallback : PPCloseFileHook;
|
closeFileCallback : PPCloseFileHook;
|
||||||
formatParamFlags : uint32;
|
formatParamFlags : uint32;
|
||||||
validateLabelCallback : PPValidateLabelHook;
|
validateLabelCallback : PPValidateLabelHook;
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ implementation
|
|||||||
uses
|
uses
|
||||||
driver.storage.fs.mgr,
|
driver.storage.fs.mgr,
|
||||||
driver.storage.fs.fat32,
|
driver.storage.fs.fat32,
|
||||||
|
driver.storage.fs.ext2,
|
||||||
proc.mgr,
|
proc.mgr,
|
||||||
proc.types,
|
proc.types,
|
||||||
io.stdio,
|
io.stdio,
|
||||||
@@ -618,6 +619,8 @@ begin
|
|||||||
|
|
||||||
if (vol^.filesystem <> nil) and (stringCompare(vol^.filesystem^.sName, 'FAT32') = 0) then
|
if (vol^.filesystem <> nil) and (stringCompare(vol^.filesystem^.sName, 'FAT32') = 0) then
|
||||||
FAT32ReleaseVolumeState(vol);
|
FAT32ReleaseVolumeState(vol);
|
||||||
|
if (vol^.filesystem <> nil) and (stringCompare(vol^.filesystem^.sName, 'EXT2') = 0) then
|
||||||
|
driver.storage.fs.ext2.ReleaseVolume(vol);
|
||||||
|
|
||||||
InvalidateVolume := true;
|
InvalidateVolume := true;
|
||||||
debug.tracer.push_trace('driver.storage.vfs.InvalidateVolume.exit');
|
debug.tracer.push_trace('driver.storage.vfs.InvalidateVolume.exit');
|
||||||
@@ -1427,8 +1430,12 @@ begin
|
|||||||
fd^.FSCloseHook := nil;
|
fd^.FSCloseHook := nil;
|
||||||
|
|
||||||
{ Cache per-file metadata and populate DataSize via FS open hook }
|
{ Cache per-file metadata and populate DataSize via FS open hook }
|
||||||
if (vol^.filesystem <> nil) and (vol^.filesystem^.openFileCallback <> nil) then begin
|
if (vol^.filesystem <> nil) and ((vol^.filesystem^.openFileCallback <> nil) or
|
||||||
fd^.FSPrivate := vol^.filesystem^.openFileCallback(vol, dir, fname, fd^.DataSize);
|
(vol^.filesystem^.openFileModeCallback <> nil)) then begin
|
||||||
|
if vol^.filesystem^.openFileModeCallback <> nil then
|
||||||
|
fd^.FSPrivate := vol^.filesystem^.openFileModeCallback(vol, dir, fname,
|
||||||
|
(OpenMode = omCreate) or (OpenMode = omWrite), fd^.DataSize)
|
||||||
|
else fd^.FSPrivate := vol^.filesystem^.openFileCallback(vol, dir, fname, fd^.DataSize);
|
||||||
if fd^.FSPrivate = nil then begin
|
if fd^.FSPrivate = nil then begin
|
||||||
if Error <> nil then begin
|
if Error <> nil then begin
|
||||||
if (OpenMode = omCreate) or (OpenMode = omWrite) then
|
if (OpenMode = omCreate) or (OpenMode = omWrite) then
|
||||||
@@ -1724,8 +1731,12 @@ begin
|
|||||||
fd^.FSCloseHook := nil;
|
fd^.FSCloseHook := nil;
|
||||||
OutHandle := slot;
|
OutHandle := slot;
|
||||||
|
|
||||||
if (vol^.filesystem <> nil) and (vol^.filesystem^.openFileCallback <> nil) then begin
|
if (vol^.filesystem <> nil) and ((vol^.filesystem^.openFileCallback <> nil) or
|
||||||
fd^.FSPrivate := vol^.filesystem^.openFileCallback(vol, dir, fname, fd^.DataSize);
|
(vol^.filesystem^.openFileModeCallback <> nil)) then begin
|
||||||
|
if vol^.filesystem^.openFileModeCallback <> nil then
|
||||||
|
fd^.FSPrivate := vol^.filesystem^.openFileModeCallback(vol, dir, fname,
|
||||||
|
(OpenMode = omCreate) or (OpenMode = omWrite), fd^.DataSize)
|
||||||
|
else fd^.FSPrivate := vol^.filesystem^.openFileCallback(vol, dir, fname, fd^.DataSize);
|
||||||
if fd^.FSPrivate = nil then begin
|
if fd^.FSPrivate = nil then begin
|
||||||
if Error <> nil then begin
|
if Error <> nil then begin
|
||||||
if (OpenMode = omCreate) or (OpenMode = omWrite) then
|
if (OpenMode = omCreate) or (OpenMode = omWrite) then
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,62 @@
|
|||||||
|
unit driver.storage.fs.ext2.types;
|
||||||
|
|
||||||
|
interface
|
||||||
|
uses driver.storage.types;
|
||||||
|
|
||||||
|
const
|
||||||
|
EXT2_MAGIC = $EF53;
|
||||||
|
EXT2_DIR = $4000;
|
||||||
|
EXT2_FILE = $8000;
|
||||||
|
EXT2_ROOT = 2;
|
||||||
|
|
||||||
|
type
|
||||||
|
TExt2Inode = packed record
|
||||||
|
Mode, UID : uint16;
|
||||||
|
Size, ATime, CTime, MTime, DTime : uint32;
|
||||||
|
GID, Links : uint16;
|
||||||
|
Sectors, Flags, OSData : uint32;
|
||||||
|
Blocks : array[0..14] of uint32;
|
||||||
|
Generation, ACL, SizeHigh, Fragment : uint32;
|
||||||
|
OSExtra : array[0..11] of uint8;
|
||||||
|
end;
|
||||||
|
PExt2Inode = ^TExt2Inode;
|
||||||
|
TExt2Group = packed record
|
||||||
|
BlockBitmap, InodeBitmap, InodeTable : uint32;
|
||||||
|
FreeBlocks, FreeInodes, Directories, Pad : uint16;
|
||||||
|
Reserved : array[0..2] of uint32;
|
||||||
|
end;
|
||||||
|
PExt2Group = ^TExt2Group;
|
||||||
|
TExt2Dirent = packed record
|
||||||
|
Inode : uint32;
|
||||||
|
Length : uint16;
|
||||||
|
NameLength, FileType : uint8;
|
||||||
|
end;
|
||||||
|
PExt2Dirent = ^TExt2Dirent;
|
||||||
|
PExt2Volume = ^TExt2Volume;
|
||||||
|
PExt2File = ^TExt2File;
|
||||||
|
TExt2Volume = record
|
||||||
|
Volume : PStorage_Volume;
|
||||||
|
Super, Groups : puint8;
|
||||||
|
BlockSize, SectorsPerBlock, BlockCount, InodeCount : uint32;
|
||||||
|
FirstBlock, BlocksPerGroup, InodesPerGroup, InodeSize : uint32;
|
||||||
|
GroupCount, GDTBlocks, AllocGroup : uint32;
|
||||||
|
Busy, Writable, Poisoned, FileTypes : boolean;
|
||||||
|
Files : PExt2File;
|
||||||
|
end;
|
||||||
|
TExt2File = record
|
||||||
|
Volume : PExt2Volume;
|
||||||
|
Inode : uint32;
|
||||||
|
Next : PExt2File;
|
||||||
|
end;
|
||||||
|
{ One operation owns its buffers. No DMA destination is shared with another
|
||||||
|
operation. The volume lock protects metadata and all read/modify/write. }
|
||||||
|
TExt2Op = record
|
||||||
|
V : PExt2Volume;
|
||||||
|
Scratch, Data : puint8;
|
||||||
|
Error : TError;
|
||||||
|
Mutating : boolean;
|
||||||
|
end;
|
||||||
|
PExt2Op = ^TExt2Op;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
end.
|
||||||
Reference in new issue
Block a user