fat32 rewrite and storage stability fixes

This commit is contained in:
Aaron committed 2026-03-16 21:18:44 +00:00
1 parent 5d7aacc28f
commit aadc59f831
13 files changed
+9163 -4706

No files matched your search

+8 -4
View File
@@ -336,18 +336,20 @@ end;
procedure write_mbr(device : PStorage_Device; mbr : PMaster_Boot_Record);
var
oldCache : pointer;
cache : puint32;
buf : puint32;
begin
push_trace('driver.storage.mgr.write_mbr');
if (device = nil) or (mbr = nil) or (not device^.writable) then exit;
{ Update cache }
if device^.cachedMBR <> nil then
kfree(device^.cachedMBR);
oldCache := device^.cachedMBR;
cache := puint32(kalloc(sizeof(TMaster_Boot_Record)));
if cache <> nil then
memcpy(uint32(mbr), uint32(cache), sizeof(TMaster_Boot_Record));
device^.cachedMBR := pointer(cache);
if oldCache <> nil then
kfree(oldCache);
buf := alloc_mbr_io_buffer(device, mbr);
if buf = nil then exit;
@@ -364,6 +366,7 @@ end;
procedure write_mbr_async(device : PStorage_Device; mbr : PMaster_Boot_Record;
callback : TIOCallback; callbackData : pointer);
var
oldCache : pointer;
cache : puint32;
buf : puint32;
ctx : PMBRWriteAsyncData;
@@ -379,12 +382,13 @@ begin
exit;
end;
{ Update cache }
if device^.cachedMBR <> nil then
kfree(device^.cachedMBR);
oldCache := device^.cachedMBR;
cache := puint32(kalloc(sizeof(TMaster_Boot_Record)));
if cache <> nil then
memcpy(uint32(mbr), uint32(cache), sizeof(TMaster_Boot_Record));
device^.cachedMBR := pointer(cache);
if oldCache <> nil then
kfree(oldCache);
buf := alloc_mbr_io_buffer(device, mbr);
if buf = nil then begin
+65 -2
View File
@@ -134,7 +134,7 @@ procedure UnwatchDirectory(WatchID : uint32);
{ Volume invalidation — must be called before freeing a volume.
Closes all open FDs referencing the volume across all processes,
evicts directory cache entries, and removes VFS mount points. }
procedure InvalidateVolume(vol : PStorage_Volume);
function InvalidateVolume(vol : PStorage_Volume) : boolean;
{ VFS Functions }
function newVirtualDirectory(Path : pchar) : TError;
@@ -149,6 +149,7 @@ implementation
uses
driver.storage.fs.mgr,
driver.storage.fs.fat32,
proc.mgr,
proc.types,
io.stdio,
@@ -508,7 +509,36 @@ end;
function GetObjectFromPath(path : pchar) : PVFSObject; forward;
function GetObjectFromPathEx(path : pchar; var volRelPath : pchar) : PVFSObject; forward;
procedure InvalidateVolume(vol : PStorage_Volume);
function volumeHasAsyncHandles(vol : PStorage_Volume) : boolean;
var
pCount : uint32;
pi : uint32;
fi : uint32;
pCtx : proc.types.PProcessContext;
tbl : PFDTable;
begin
volumeHasAsyncHandles := false;
if vol = nil then exit;
pCount := proc.mgr.processCount();
if pCount = 0 then exit;
for pi := 0 to pCount - 1 do begin
pCtx := proc.mgr.getProcessByIndex(pi);
if pCtx = nil then continue;
tbl := PFDTable(pCtx^.FDTable);
if tbl = nil then continue;
for fi := 0 to MAX_FDS - 1 do begin
if tbl^.Entries[fi].InUse and (tbl^.Entries[fi].Volume = vol)
and (tbl^.Entries[fi].AsyncRefs > 0) then begin
volumeHasAsyncHandles := true;
exit;
end;
end;
end;
end;
function InvalidateVolume(vol : PStorage_Volume) : boolean;
var
pCount : uint32;
pi : uint32;
@@ -522,7 +552,12 @@ var
child : PVFSObject;
begin
debug.tracer.push_trace('driver.storage.vfs.InvalidateVolume.enter');
InvalidateVolume := false;
if vol = nil then exit;
if volumeHasAsyncHandles(vol) then begin
debug.tracer.push_trace('driver.storage.vfs.InvalidateVolume.busy');
exit;
end;
{ 1. Evict all directory cache entries for this volume }
DirCache_Invalidate(vol, nil);
@@ -575,6 +610,10 @@ begin
kfree(void(bootObj));
end;
if (vol^.filesystem <> nil) and (stringCompare(vol^.filesystem^.sName, 'FAT32') = 0) then
FAT32ReleaseVolumeState(vol);
InvalidateVolume := true;
debug.tracer.push_trace('driver.storage.vfs.InvalidateVolume.exit');
end;
@@ -1313,6 +1352,17 @@ begin
{ Cache per-file metadata and populate DataSize via FS open hook }
if (vol^.filesystem <> nil) and (vol^.filesystem^.openFileCallback <> nil) then begin
fd^.FSPrivate := vol^.filesystem^.openFileCallback(vol, dir, fname, fd^.DataSize);
if fd^.FSPrivate = nil then begin
if Error <> nil then begin
if (OpenMode = omCreate) or (OpenMode = omWrite) then
Error^ := eInvalidFileName
else
Error^ := eFileDoesNotExist;
end;
fd_close(tbl, slot);
debug.tracer.push_trace('driver.storage.vfs.OpenFile.exit');
exit;
end;
if vol^.filesystem^.closeFileCallback <> nil then
fd^.FSCloseHook := pointer(vol^.filesystem^.closeFileCallback);
if Error <> nil then Error^ := eNone;
@@ -1599,6 +1649,19 @@ begin
if (vol^.filesystem <> nil) and (vol^.filesystem^.openFileCallback <> nil) then begin
fd^.FSPrivate := vol^.filesystem^.openFileCallback(vol, dir, fname, fd^.DataSize);
if fd^.FSPrivate = nil then begin
if Error <> nil then begin
if (OpenMode = omCreate) or (OpenMode = omWrite) then
Error^ := eInvalidFileName
else
Error^ := eFileDoesNotExist;
end;
fd_close(tbl, slot);
OutHandle := 0;
if Callback <> nil then Callback(Error^, CallbackData);
debug.tracer.push_trace('driver.storage.vfs.OpenFileAsync.exit');
exit;
end;
if vol^.filesystem^.closeFileCallback <> nil then
fd^.FSCloseHook := pointer(vol^.filesystem^.closeFileCallback);
if Error <> nil then Error^ := eNone;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -34,6 +34,7 @@ uses
io.syslog,
debug.tracer,
core.util, arch.x86.util,
driver.storage.vol.mbr,
driver.storage.vol.mgr;
type
@@ -763,13 +764,38 @@ end;
function identify_volume(volume : PStorage_Volume) : boolean;
var
buffer : puint32;
bufSize : uint32;
buffer : puint32;
bufSize : uint32;
mbr : PMaster_Boot_Record;
freeMbr : boolean;
slot : sint32;
i : uint32;
begin
push_trace('driver.storage.fs.flatfs.identify_volume');
identify_volume := false;
if volume^.device^.dispatchRead = nil then exit;
mbr := driver.storage.mgr.get_cached_mbr(volume^.device);
freeMbr := false;
if mbr = nil then begin
mbr := driver.storage.mgr.read_mbr(volume^.device);
freeMbr := mbr <> nil;
end;
slot := -1;
if mbr <> nil then begin
for i := 0 to 3 do begin
if mbr^.partition[i].LBA_start = volume^.sectorStart then begin
slot := sint32(i);
break;
end;
end;
if (slot >= 0) and (mbr^.partition[slot].system_id <> filesystem.system_id) then begin
if freeMbr then kfree(void(mbr));
exit;
end;
end;
bufSize := volume^.device^.sectorSize;
if bufSize < 512 then bufSize := 512;
buffer := puint32(kalloc(bufSize));
@@ -783,6 +809,7 @@ begin
end;
kfree(buffer);
if freeMbr then kfree(void(mbr));
end;
function readDirectoryEntries(volume : PStorage_Volume; directory : pchar; status : PuInt32) : PLinkedListBase;
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
File diff suppressed because it is too large. Load diff