fat32: fix pre-alloc cluster leak; add write-handle ref-count
- Remove FAT_WRITE_PREALLOC_BYTES (redundant at typical cluster sizes) - Simplify fatPreallocClusterCount to always return MAX_CLUSTERS - FAT32CloseFile: truncate pre-allocated tail clusters back to ByteSize on close, freeing FAT chain entries beyond the file's real size - Add TFATWriteRef + WriteRefs[32] in TFATVolumeCtx and Registered flag on TFATOpenFile to track concurrent write handles per dir entry - fatRegisterWriteHandle / fatUnregisterWriteHandle: CLI-guarded slot scan keyed by (DirLoc.SectorLBA, DirLoc.EntryIdx) - Register on first FAT chain extension in FAT32EnsureCapacityForWrite - Truncation in FAT32CloseFile skipped unless this is the last writer (prevents RunMap corruption in concurrent-open scenarios) - Add forward decl for fatFreeClusterChain to fix ordering issue - app.iotest: update default path to /disk/vol2/IOTEST.BIN
This commit is contained in:
@@ -34,7 +34,7 @@ const
|
||||
TICK_HZ = 1024; { timer ISR frequency }
|
||||
IO_WAIT_TIMEOUT_TICKS = 10 * TICK_HZ;
|
||||
DELETE_TIMEOUT_TICKS = 5 * TICK_HZ;
|
||||
DEFAULT_PATH : pchar = '/disk/vol0/IOTEST.BIN';
|
||||
DEFAULT_PATH : pchar = '/disk/vol2/IOTEST.BIN';
|
||||
|
||||
type
|
||||
TIOTSyncWaitCtx = record
|
||||
|
||||
@@ -69,7 +69,7 @@ function send_read_capacity(device : PAHCI_Device; sectorCount : puint32; blockS
|
||||
implementation
|
||||
|
||||
const
|
||||
AHCI_ENABLE_NCQ = false;
|
||||
AHCI_ENABLE_NCQ = true;
|
||||
|
||||
function min_u32(a : uint32; b : uint32) : uint32;
|
||||
begin
|
||||
@@ -421,15 +421,15 @@ begin
|
||||
start_port(device^.port);
|
||||
|
||||
{ Re-enable port interrupts and bail — device is non-functional. }
|
||||
device^.port^.int_enable := $40000003;
|
||||
device^.port^.int_enable := $4000000B;
|
||||
kfree(buffer);
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ Re-enable port interrupts now that IDENTIFY polling is done.
|
||||
$40000003 = bit 0 (D2H Register FIS) | bit 1 (PIO Setup FIS) | bit 30 (Task File Error)
|
||||
These three bits cover all normal completions and hardware error events. }
|
||||
device^.port^.int_enable := $40000003;
|
||||
$4000000B = bit 0 (D2H Register FIS) | bit 1 (PIO Setup FIS) | bit 3 (Set Device Bits / NCQ) | bit 30 (Task File Error)
|
||||
Bit 3 is required for NCQ completion notifications via SDB FIS. }
|
||||
device^.port^.int_enable := $4000000B;
|
||||
|
||||
b8 := puint16(buffer);
|
||||
memcpy(uint32(buffer), uint32(@device^.ata_info[0]), 512);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+4
-2
@@ -14,7 +14,8 @@ implementation
|
||||
|
||||
uses
|
||||
io.syslog,
|
||||
driver.storage.fs.fat32.old,
|
||||
core.util,
|
||||
driver.storage.fs.fat32.vol,
|
||||
driver.storage.fs.fat32.core,
|
||||
driver.storage.fs.fat32.transfer;
|
||||
|
||||
@@ -23,13 +24,13 @@ var
|
||||
|
||||
procedure FAT32ReleaseVolumeState(volume : PStorage_Volume);
|
||||
begin
|
||||
FAT32LegacyReleaseVolumeCtx(volume);
|
||||
FAT32ReleaseVolumeCtx(volume);
|
||||
end;
|
||||
|
||||
procedure init;
|
||||
begin
|
||||
io.syslog.logln('FAT32', 'init: registering FAT32 filesystem');
|
||||
memset(uint32(@filesystem), 0, sizeof(TFilesystem));
|
||||
filesystem.sName := 'FAT32';
|
||||
filesystem.system_id := $0B;
|
||||
filesystem.readDirCallback := @FAT32ReadDirectory;
|
||||
@@ -52,6 +53,7 @@ begin
|
||||
filesystem.readDirAsyncCallback := nil;
|
||||
filesystem.formatParamFlags := FS_FORMAT_PARAM_CLUSTER_SIZE;
|
||||
|
||||
FAT32VolInit(@filesystem);
|
||||
driver.storage.fs.mgr.register_filesystem(@filesystem);
|
||||
end;
|
||||
|
||||
@@ -67,17 +67,16 @@ type
|
||||
end;
|
||||
|
||||
const
|
||||
FAT_CACHE_SETS = 512;
|
||||
FAT_CACHE_WAYS = 2;
|
||||
FAT_CACHE_SETS = 1024;
|
||||
FAT_CACHE_WAYS = 4;
|
||||
FAT_CACHE_LINES = FAT_CACHE_SETS * FAT_CACHE_WAYS;
|
||||
FAT_TRANSFER_POOL_CAPACITY = 64;
|
||||
FAT_ALLOC_HINT_SLOTS = 8;
|
||||
FAT_DIR_HINT_SLOTS = 16;
|
||||
FAT_WRITE_PREALLOC_BYTES = 16 * 1024 * 1024;
|
||||
FAT_DIR_HINT_SLOTS = 8;
|
||||
FAT_WRITE_PREALLOC_MAX_CLUSTERS = 2048;
|
||||
FAT_WRITE_PREALLOC_MIN_CLUSTERS = 64;
|
||||
FAT_MAX_IO_SECTORS = 2048;
|
||||
|
||||
FAT_MAX_IO_SECTORS = 2048 * 2;
|
||||
FAT_OPEN_HANDLE_SLOTS = 65000;
|
||||
type
|
||||
TFATCacheLine = record
|
||||
SectorIdx : uint32;
|
||||
@@ -162,6 +161,13 @@ type
|
||||
Exists : boolean;
|
||||
FatDirty : boolean;
|
||||
MetaDirty : boolean;
|
||||
Registered : boolean; { true once registered in the volume write-ref table }
|
||||
end;
|
||||
|
||||
TFATWriteRef = record
|
||||
SectorLBA : uint32;
|
||||
EntryIdx : uint32;
|
||||
Count : uint32; { number of write handles with this dir entry open }
|
||||
end;
|
||||
|
||||
TFATTransferMode = (ftmRead, ftmWrite);
|
||||
@@ -215,6 +221,7 @@ type
|
||||
HintStamp : uint32;
|
||||
AllocHints : array[0..FAT_ALLOC_HINT_SLOTS - 1] of TFATAllocHint;
|
||||
DirHints : array[0..FAT_DIR_HINT_SLOTS - 1] of TFATDirHint;
|
||||
WriteRefs : array[0..FAT_OPEN_HANDLE_SLOTS - 1] of TFATWriteRef;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user