Feature/sotrage system overhaul #73
No files matched your search
@@ -1860,7 +1860,7 @@ begin
|
|||||||
if (error = eNone) and (nfctx^.handle <> 0) then begin
|
if (error = eNone) and (nfctx^.handle <> 0) then begin
|
||||||
{ WriteFileAsync needs a non-nil buffer; Length=0 so it is never read }
|
{ WriteFileAsync needs a non-nil buffer; Length=0 so it is never read }
|
||||||
driver.storage.vfs.WriteFileAsync(nfctx^.handle, 0,
|
driver.storage.vfs.WriteFileAsync(nfctx^.handle, 0,
|
||||||
puint8(@nfctx^.err), 0, @fb_newfile_written, nfctx);
|
puint8(@nfctx^.err), 0, nil, @fb_newfile_written, nfctx);
|
||||||
end else begin
|
end else begin
|
||||||
if nfctx^.handle <> 0 then
|
if nfctx^.handle <> 0 then
|
||||||
driver.storage.vfs.CloseFile(nfctx^.handle);
|
driver.storage.vfs.CloseFile(nfctx^.handle);
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ uses
|
|||||||
core.strings, arch.x86.bda;
|
core.strings, arch.x86.bda;
|
||||||
|
|
||||||
const
|
const
|
||||||
FILE_SIZE = 10 * 1024 * 1024; { 10 MB }
|
FILE_SIZE = 25 * 1024 * 1024; { 25 MB }
|
||||||
CHUNK_SIZE = 4096*64; { MB per is 4k*64 = 256 KB, so 40 chunks total }
|
CHUNK_SIZE = 4096*128; { MB per is 4k*128 = 512 KB, so 50 chunks total }
|
||||||
TICK_HZ = 1024; { timer ISR frequency }
|
TICK_HZ = 1024; { timer ISR frequency }
|
||||||
DEFAULT_PATH : pchar = '/disk/vol0/IOTEST.BIN';
|
DEFAULT_PATH : pchar = '/disk/vol0/IOTEST.BIN';
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ begin
|
|||||||
verBuf := puint8(kalloc(CHUNK_SIZE));
|
verBuf := puint8(kalloc(CHUNK_SIZE));
|
||||||
|
|
||||||
{ ==================== WRITE PHASE ==================== }
|
{ ==================== WRITE PHASE ==================== }
|
||||||
io.stdio.bufWriteStr(stdout_buf, 'Writing 10 MB to ');
|
io.stdio.bufWriteStr(stdout_buf, 'Writing 25 MB to ');
|
||||||
io.stdio.bufWriteStrLn(stdout_buf, path);
|
io.stdio.bufWriteStrLn(stdout_buf, path);
|
||||||
|
|
||||||
fh := OpenFile(path, omCreate, @fErr);
|
fh := OpenFile(path, omCreate, @fErr);
|
||||||
@@ -131,7 +131,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
t1 := arch.x86.bda.Counters.c32;
|
t1 := arch.x86.bda.Counters.c32;
|
||||||
|
io.stdio.bufWriteStrLn(stdout_buf, 'Closing write handle...');
|
||||||
CloseFile(fh);
|
CloseFile(fh);
|
||||||
|
io.stdio.bufWriteStrLn(stdout_buf, 'Write handle closed.');
|
||||||
|
|
||||||
if ok then begin
|
if ok then begin
|
||||||
elapsed := t1 - t0;
|
elapsed := t1 - t0;
|
||||||
@@ -215,7 +217,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
t1 := arch.x86.bda.Counters.c32;
|
t1 := arch.x86.bda.Counters.c32;
|
||||||
|
io.stdio.bufWriteStrLn(stdout_buf, 'Closing read handle...');
|
||||||
CloseFile(fh);
|
CloseFile(fh);
|
||||||
|
io.stdio.bufWriteStrLn(stdout_buf, 'Read handle closed.');
|
||||||
|
|
||||||
if ok then begin
|
if ok then begin
|
||||||
elapsed := t1 - t0;
|
elapsed := t1 - t0;
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -269,6 +269,9 @@ type
|
|||||||
port : PHBA_Port;
|
port : PHBA_Port;
|
||||||
device_type : TDeviceType;
|
device_type : TDeviceType;
|
||||||
ata_info : TIdentResponse;
|
ata_info : TIdentResponse;
|
||||||
|
supportsNCQ : boolean;
|
||||||
|
queueDepth : uint32; { safe active depth for this device }
|
||||||
|
slotCount : uint32; { controller slot count from CAP.NCS + 1 }
|
||||||
command_list : PHBA_CMD_HEADER;
|
command_list : PHBA_CMD_HEADER;
|
||||||
fis : PHBA_FIS;
|
fis : PHBA_FIS;
|
||||||
command_table: PHBA_CMD_TABLE;
|
command_table: PHBA_CMD_TABLE;
|
||||||
@@ -335,4 +338,3 @@ end;
|
|||||||
// end;
|
// end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@@ -86,7 +86,8 @@ end;
|
|||||||
Returns actual bytes copied. }
|
Returns actual bytes copied. }
|
||||||
function rd_ReadOffset(volume : PStorage_Volume; directory : pchar;
|
function rd_ReadOffset(volume : PStorage_Volume; directory : pchar;
|
||||||
fileName : pchar; offset : uint32;
|
fileName : pchar; offset : uint32;
|
||||||
buffer : puint32; byteCount : uint32) : uint32;
|
buffer : puint32; byteCount : uint32;
|
||||||
|
ctx : pointer) : uint32;
|
||||||
var
|
var
|
||||||
clean : pchar;
|
clean : pchar;
|
||||||
idx : sint32;
|
idx : sint32;
|
||||||
|
|||||||
@@ -45,10 +45,12 @@ const
|
|||||||
ATA_CMD_READ_PIO_EXT = $24;
|
ATA_CMD_READ_PIO_EXT = $24;
|
||||||
ATA_CMD_READ_DMA = $C8;
|
ATA_CMD_READ_DMA = $C8;
|
||||||
ATA_CMD_READ_DMA_EXT = $25;
|
ATA_CMD_READ_DMA_EXT = $25;
|
||||||
|
ATA_CMD_READ_FPDMA_QUEUED = $60;
|
||||||
ATA_CMD_WRITE_PIO = $30;
|
ATA_CMD_WRITE_PIO = $30;
|
||||||
ATA_CMD_WRITE_PIO_EXT = $34;
|
ATA_CMD_WRITE_PIO_EXT = $34;
|
||||||
ATA_CMD_WRITE_DMA = $CA;
|
ATA_CMD_WRITE_DMA = $CA;
|
||||||
ATA_CMD_WRITE_DMA_EXT = $35;
|
ATA_CMD_WRITE_DMA_EXT = $35;
|
||||||
|
ATA_CMD_WRITE_FPDMA_QUEUED = $61;
|
||||||
ATA_CMD_CACHE_FLUSH = $E7;
|
ATA_CMD_CACHE_FLUSH = $E7;
|
||||||
ATA_CMD_CACHE_FLUSH_EXT = $EA;
|
ATA_CMD_CACHE_FLUSH_EXT = $EA;
|
||||||
ATA_CMD_PACKET = $A0;
|
ATA_CMD_PACKET = $A0;
|
||||||
@@ -146,4 +148,4 @@ type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
end.
|
end.
|
||||||
@@ -37,6 +37,7 @@ type
|
|||||||
PFileDescriptor = ^TFileDescriptor;
|
PFileDescriptor = ^TFileDescriptor;
|
||||||
TFileDescriptor = record
|
TFileDescriptor = record
|
||||||
InUse : boolean;
|
InUse : boolean;
|
||||||
|
AsyncRefs : uint32; { in-flight async ops using this descriptor }
|
||||||
Volume : PStorage_Volume;
|
Volume : PStorage_Volume;
|
||||||
Directory : pchar; { directory path within the volume }
|
Directory : pchar; { directory path within the volume }
|
||||||
FileName : pchar; { filename within that directory }
|
FileName : pchar; { filename within that directory }
|
||||||
@@ -45,6 +46,8 @@ type
|
|||||||
DataSize : uint32; { cached file size in bytes (from fileSizeCallback) }
|
DataSize : uint32; { cached file size in bytes (from fileSizeCallback) }
|
||||||
DeviceOps : pointer; { PVFSDeviceOps — non-nil for device FDs }
|
DeviceOps : pointer; { PVFSDeviceOps — non-nil for device FDs }
|
||||||
DeviceData : pointer; { opaque data passed to device callbacks }
|
DeviceData : pointer; { opaque data passed to device callbacks }
|
||||||
|
FSPrivate : pointer; { opaque FS-level per-file metadata (from openFileCallback) }
|
||||||
|
FSCloseHook : pointer; { procedure(pointer) — frees FSPrivate on close }
|
||||||
end;
|
end;
|
||||||
|
|
||||||
PFDTable = ^TFDTable;
|
PFDTable = ^TFDTable;
|
||||||
@@ -68,6 +71,9 @@ function fd_alloc(table : PFDTable) : uint32;
|
|||||||
{ Get a pointer to the descriptor for a 1-based handle.
|
{ Get a pointer to the descriptor for a 1-based handle.
|
||||||
Returns nil if handle is out of range or the slot is not in use. }
|
Returns nil if handle is out of range or the slot is not in use. }
|
||||||
function fd_get(table : PFDTable; handle : uint32) : PFileDescriptor;
|
function fd_get(table : PFDTable; handle : uint32) : PFileDescriptor;
|
||||||
|
function fd_begin_async(entry : PFileDescriptor) : boolean;
|
||||||
|
procedure fd_end_async(entry : PFileDescriptor);
|
||||||
|
function fd_has_async(entry : PFileDescriptor) : boolean;
|
||||||
|
|
||||||
{ Close a single file descriptor: free its buffers and core.strings,
|
{ Close a single file descriptor: free its buffers and core.strings,
|
||||||
mark the slot as not-in-use.
|
mark the slot as not-in-use.
|
||||||
@@ -94,11 +100,20 @@ begin
|
|||||||
fd_table_new := tbl;
|
fd_table_new := tbl;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
type
|
||||||
|
TFSPrivateClose = procedure(data : pointer);
|
||||||
|
|
||||||
procedure fd_free_entry(entry : PFileDescriptor);
|
procedure fd_free_entry(entry : PFileDescriptor);
|
||||||
begin
|
begin
|
||||||
if entry = nil then exit;
|
if entry = nil then exit;
|
||||||
if not entry^.InUse then exit;
|
if not entry^.InUse then exit;
|
||||||
|
|
||||||
|
{ Free FS-level per-file metadata first }
|
||||||
|
if (entry^.FSPrivate <> nil) and (entry^.FSCloseHook <> nil) then
|
||||||
|
TFSPrivateClose(entry^.FSCloseHook)(entry^.FSPrivate);
|
||||||
|
entry^.FSPrivate := nil;
|
||||||
|
entry^.FSCloseHook := nil;
|
||||||
|
|
||||||
if entry^.Directory <> nil then begin
|
if entry^.Directory <> nil then begin
|
||||||
kfree(void(entry^.Directory));
|
kfree(void(entry^.Directory));
|
||||||
entry^.Directory := nil;
|
entry^.Directory := nil;
|
||||||
@@ -113,6 +128,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
entry^.InUse := false;
|
entry^.InUse := false;
|
||||||
|
entry^.AsyncRefs := 0;
|
||||||
entry^.DataSize := 0;
|
entry^.DataSize := 0;
|
||||||
entry^.DeviceOps := nil;
|
entry^.DeviceOps := nil;
|
||||||
entry^.DeviceData := nil;
|
entry^.DeviceData := nil;
|
||||||
@@ -148,6 +164,34 @@ begin
|
|||||||
fd_get := @table^.Entries[handle - 1];
|
fd_get := @table^.Entries[handle - 1];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function fd_begin_async(entry : PFileDescriptor) : boolean;
|
||||||
|
begin
|
||||||
|
fd_begin_async := false;
|
||||||
|
if entry = nil then exit;
|
||||||
|
asm pushf; cli end;
|
||||||
|
if entry^.InUse then begin
|
||||||
|
entry^.AsyncRefs := entry^.AsyncRefs + 1;
|
||||||
|
fd_begin_async := true;
|
||||||
|
end;
|
||||||
|
asm popf end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure fd_end_async(entry : PFileDescriptor);
|
||||||
|
begin
|
||||||
|
if entry = nil then exit;
|
||||||
|
asm pushf; cli end;
|
||||||
|
if entry^.AsyncRefs > 0 then
|
||||||
|
entry^.AsyncRefs := entry^.AsyncRefs - 1;
|
||||||
|
asm popf end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fd_has_async(entry : PFileDescriptor) : boolean;
|
||||||
|
begin
|
||||||
|
fd_has_async := false;
|
||||||
|
if entry = nil then exit;
|
||||||
|
fd_has_async := entry^.AsyncRefs > 0;
|
||||||
|
end;
|
||||||
|
|
||||||
function fd_close(table : PFDTable; handle : uint32) : boolean;
|
function fd_close(table : PFDTable; handle : uint32) : boolean;
|
||||||
begin
|
begin
|
||||||
fd_close := false;
|
fd_close := false;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
{
|
{
|
||||||
Driver->Storage->IORequest - I/O request allocation and lifecycle helpers.
|
Driver->Storage->IORequest - I/O request allocation and lifecycle helpers.
|
||||||
|
|
||||||
Provides heap allocation/free for TIORequest records used by the
|
Provides fixed-pool allocation/free for TIORequest records used by the
|
||||||
submit_io / complete_io path in driver.storage.mgr.pas.
|
submit_io / complete_io path in driver.storage.mgr.pas.
|
||||||
|
|
||||||
@author(Aaron Hance <[email protected]>)
|
@author(Aaron Hance <[email protected]>)
|
||||||
@@ -27,7 +27,7 @@ uses
|
|||||||
memory.heap,
|
memory.heap,
|
||||||
driver.storage.types;
|
driver.storage.types;
|
||||||
|
|
||||||
{ Allocate a new TIORequest on the heap and initialise its core fields.
|
{ Allocate a new TIORequest from the fixed request pool and initialise its core fields.
|
||||||
Caller, State, Error and ByteCount are zeroed (caller fills as needed). }
|
Caller, State, Error and ByteCount are zeroed (caller fills as needed). }
|
||||||
function ioreq_alloc(reqType : TIORequestType;
|
function ioreq_alloc(reqType : TIORequestType;
|
||||||
device : PStorage_Device;
|
device : PStorage_Device;
|
||||||
@@ -35,16 +35,90 @@ function ioreq_alloc(reqType : TIORequestType;
|
|||||||
sectors : uint32;
|
sectors : uint32;
|
||||||
buf : pointer) : PIORequest;
|
buf : pointer) : PIORequest;
|
||||||
|
|
||||||
{ Free a heap-allocated TIORequest. Safe to call with nil. }
|
{ Return a pooled TIORequest to the free list. Safe to call with nil. }
|
||||||
procedure ioreq_free(req : PIORequest);
|
procedure ioreq_free(req : PIORequest);
|
||||||
|
|
||||||
{ Copy an existing TIORequest into a new heap allocation (deep copy of the
|
{ Copy an existing TIORequest into a new pooled allocation (deep copy of the
|
||||||
record, NOT the buffer it points to). Used by dispatch_next to create an
|
record, NOT the buffer it points to). Used by dispatch_next to create an
|
||||||
ISR-safe copy from the CFIFO value-element. }
|
ISR-safe copy from the CFIFO value-element. }
|
||||||
function ioreq_copy(src : PIORequest) : PIORequest;
|
function ioreq_copy(src : PIORequest) : PIORequest;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
const
|
||||||
|
IOREQ_POOL_CAPACITY = 512;
|
||||||
|
IOREQ_REQ_OFFSET = sizeof(pointer);
|
||||||
|
|
||||||
|
type
|
||||||
|
PIORequestPoolNode = ^TIORequestPoolNode;
|
||||||
|
TIORequestPoolNode = record
|
||||||
|
Next : PIORequestPoolNode;
|
||||||
|
Req : TIORequest;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
ioreqPoolReady : boolean;
|
||||||
|
ioreqPoolBuf : pointer;
|
||||||
|
ioreqFreeList : PIORequestPoolNode;
|
||||||
|
|
||||||
|
procedure ioreq_pool_init();
|
||||||
|
var
|
||||||
|
i : uint32;
|
||||||
|
base : uint32;
|
||||||
|
node : PIORequestPoolNode;
|
||||||
|
begin
|
||||||
|
if ioreqPoolReady then exit;
|
||||||
|
|
||||||
|
ioreqPoolBuf := kalloc(IOREQ_POOL_CAPACITY * sizeof(TIORequestPoolNode));
|
||||||
|
if ioreqPoolBuf = nil then exit;
|
||||||
|
|
||||||
|
ioreqFreeList := nil;
|
||||||
|
base := uint32(ioreqPoolBuf);
|
||||||
|
if IOREQ_POOL_CAPACITY > 0 then
|
||||||
|
for i := 0 to IOREQ_POOL_CAPACITY - 1 do begin
|
||||||
|
node := PIORequestPoolNode(base + (i * sizeof(TIORequestPoolNode)));
|
||||||
|
node^.Next := ioreqFreeList;
|
||||||
|
ioreqFreeList := node;
|
||||||
|
end;
|
||||||
|
|
||||||
|
ioreqPoolReady := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ioreq_take() : PIORequest;
|
||||||
|
var
|
||||||
|
node : PIORequestPoolNode;
|
||||||
|
begin
|
||||||
|
if not ioreqPoolReady then
|
||||||
|
ioreq_pool_init();
|
||||||
|
if not ioreqPoolReady then begin
|
||||||
|
ioreq_take := nil;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
asm pushf; cli end;
|
||||||
|
node := ioreqFreeList;
|
||||||
|
if node <> nil then
|
||||||
|
ioreqFreeList := node^.Next;
|
||||||
|
asm popf end;
|
||||||
|
|
||||||
|
if node = nil then
|
||||||
|
ioreq_take := nil
|
||||||
|
else
|
||||||
|
ioreq_take := @node^.Req;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ioreq_release(req : PIORequest);
|
||||||
|
var
|
||||||
|
node : PIORequestPoolNode;
|
||||||
|
begin
|
||||||
|
if req = nil then exit;
|
||||||
|
node := PIORequestPoolNode(uint32(req) - IOREQ_REQ_OFFSET);
|
||||||
|
asm pushf; cli end;
|
||||||
|
node^.Next := ioreqFreeList;
|
||||||
|
ioreqFreeList := node;
|
||||||
|
asm popf end;
|
||||||
|
end;
|
||||||
|
|
||||||
function ioreq_alloc(reqType : TIORequestType;
|
function ioreq_alloc(reqType : TIORequestType;
|
||||||
device : PStorage_Device;
|
device : PStorage_Device;
|
||||||
lba : uint32;
|
lba : uint32;
|
||||||
@@ -53,7 +127,7 @@ function ioreq_alloc(reqType : TIORequestType;
|
|||||||
var
|
var
|
||||||
req : PIORequest;
|
req : PIORequest;
|
||||||
begin
|
begin
|
||||||
req := PIORequest(kalloc(SizeOf(TIORequest)));
|
req := ioreq_take();
|
||||||
if req = nil then begin
|
if req = nil then begin
|
||||||
ioreq_alloc := nil;
|
ioreq_alloc := nil;
|
||||||
exit;
|
exit;
|
||||||
@@ -75,15 +149,14 @@ end;
|
|||||||
|
|
||||||
procedure ioreq_free(req : PIORequest);
|
procedure ioreq_free(req : PIORequest);
|
||||||
begin
|
begin
|
||||||
if req <> nil then
|
ioreq_release(req);
|
||||||
kfree(void(req));
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ioreq_copy(src : PIORequest) : PIORequest;
|
function ioreq_copy(src : PIORequest) : PIORequest;
|
||||||
var
|
var
|
||||||
dst : PIORequest;
|
dst : PIORequest;
|
||||||
begin
|
begin
|
||||||
dst := PIORequest(kalloc(SizeOf(TIORequest)));
|
dst := ioreq_take();
|
||||||
if dst = nil then begin
|
if dst = nil then begin
|
||||||
ioreq_copy := nil;
|
ioreq_copy := nil;
|
||||||
exit;
|
exit;
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -134,9 +134,11 @@ type
|
|||||||
|
|
||||||
{ === I/O callback type === }
|
{ === I/O callback type === }
|
||||||
|
|
||||||
{ Async I/O completion callback — fired from ISR context when a request finishes.
|
{ Completion callback used across storage/VFS async APIs.
|
||||||
error = eNone on success; specific code on failure.
|
error = eNone on success; specific code on failure.
|
||||||
userdata is the opaque pointer passed by the submitter. }
|
userdata is the opaque pointer passed by the submitter.
|
||||||
|
Context is API-specific: some callers complete from ISR context, others
|
||||||
|
from task/worker context, and some may invoke the callback immediately. }
|
||||||
TIOCallback = procedure(error : TError; userdata : pointer);
|
TIOCallback = procedure(error : TError; userdata : pointer);
|
||||||
|
|
||||||
{ Filesystem callback core.types }
|
{ Filesystem callback core.types }
|
||||||
@@ -150,16 +152,29 @@ type
|
|||||||
PPIdentifyHook = function(volume : PStorage_Volume) : boolean;
|
PPIdentifyHook = function(volume : PStorage_Volume) : boolean;
|
||||||
PPRenameFileHook = procedure(volume : PStorage_Volume; filePath : pchar; newName : pchar; status : puint32);
|
PPRenameFileHook = procedure(volume : PStorage_Volume; filePath : pchar; newName : pchar; status : puint32);
|
||||||
{ Offset-based read: reads byteCount bytes starting at byte offset into the file.
|
{ Offset-based read: reads byteCount bytes starting at byte offset into the file.
|
||||||
Returns the number of bytes actually read. }
|
Returns the number of bytes actually read. ctx is the opaque per-file
|
||||||
PPReadOffsetHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; offset : uint32; buffer : puint32; byteCount : uint32) : uint32;
|
context returned by openFileCallback (nil when called without a handle). }
|
||||||
|
PPReadOffsetHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; offset : uint32; buffer : puint32; byteCount : uint32; ctx : pointer) : uint32;
|
||||||
{ Offset-based write: writes byteCount bytes starting at byte offset into the file.
|
{ Offset-based write: writes byteCount bytes starting at byte offset into the file.
|
||||||
Returns the number of bytes actually written.
|
Returns the number of bytes actually written.
|
||||||
Filesystems that do not implement this leave the field nil; VFS returns 0
|
Filesystems that do not implement this leave the field nil; VFS returns 0
|
||||||
for stream-mode writes on volume FDs. }
|
for stream-mode writes on volume FDs. }
|
||||||
PPWriteOffsetHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; offset : uint32; buffer : puint32; byteCount : uint32) : uint32;
|
PPWriteOffsetHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; offset : uint32; buffer : puint32; byteCount : uint32; ctx : pointer) : uint32;
|
||||||
|
{ Async offset-based read/write hooks. Implementations must return immediately
|
||||||
|
and fire callback when the transfer completes. BytesRead/BytesWritten may be
|
||||||
|
nil; if provided, implementations store the actual completed byte count. }
|
||||||
|
PPReadOffsetAsyncHook = procedure(volume : PStorage_Volume; directory : pchar; fileName : pchar; offset : uint32; buffer : puint32; byteCount : uint32; ctx : pointer; bytesRead : puint32; callback : TIOCallback; callbackData : pointer);
|
||||||
|
PPWriteOffsetAsyncHook = procedure(volume : PStorage_Volume; directory : pchar; fileName : pchar; offset : uint32; buffer : puint32; byteCount : uint32; ctx : pointer; bytesWritten : puint32; callback : TIOCallback; callbackData : pointer);
|
||||||
{ File size query: returns the size in bytes of the named file.
|
{ File size query: returns the size in bytes of the named file.
|
||||||
Returns 0 if the file does not exist or has zero length. }
|
Returns 0 if the file does not exist or has zero length. }
|
||||||
PPFileSizeHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar) : uint32;
|
PPFileSizeHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar) : uint32;
|
||||||
|
{ Per-file open hook: called by VFS on OpenFile to create FS-level cached
|
||||||
|
metadata. Returns an opaque pointer stored in the FD and passed as ctx
|
||||||
|
to read/write hooks. Also returns the current file size through the
|
||||||
|
var parameter. Returning nil is legal (disables per-call fast-path). }
|
||||||
|
PPOpenFileHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; var fileSize : uint32) : pointer;
|
||||||
|
{ Per-file close hook: frees the context allocated by openFileCallback. }
|
||||||
|
PPCloseFileHook = procedure(ctx : pointer);
|
||||||
|
|
||||||
{ === Async filesystem hook core.types ===
|
{ === Async filesystem hook core.types ===
|
||||||
Each mirrors the corresponding sync hook but receives a TIOCallback + callbackData.
|
Each mirrors the corresponding sync hook but receives a TIOCallback + callbackData.
|
||||||
@@ -168,8 +183,6 @@ type
|
|||||||
PPLinkedListBase = ^PLinkedListBase; { needed for PPReadDirAsyncHook parameter }
|
PPLinkedListBase = ^PLinkedListBase; { needed for PPReadDirAsyncHook parameter }
|
||||||
PPCreateDirAsyncHook = procedure(volume : PStorage_Volume; directory : pchar; dirname : pchar; attributes : uint32; status : puint32; callback : TIOCallback; callbackData : pointer);
|
PPCreateDirAsyncHook = procedure(volume : PStorage_Volume; directory : pchar; dirname : pchar; attributes : uint32; status : puint32; callback : TIOCallback; callbackData : pointer);
|
||||||
PPReadDirAsyncHook = procedure(volume : PStorage_Volume; directory : pchar; resultList : PPLinkedListBase; status : puint32; callback : TIOCallback; callbackData : pointer);
|
PPReadDirAsyncHook = procedure(volume : PStorage_Volume; directory : pchar; resultList : PPLinkedListBase; status : puint32; callback : TIOCallback; callbackData : pointer);
|
||||||
PPDeleteFileAsyncHook = procedure(volume : PStorage_Volume; filePath : pchar; status : puint32; callback : TIOCallback; callbackData : pointer);
|
|
||||||
PPDeleteDirAsyncHook = procedure(volume : PStorage_Volume; path : pchar; status : puint32; callback : TIOCallback; callbackData : pointer);
|
|
||||||
|
|
||||||
{ === I/O Request core.types === }
|
{ === I/O Request core.types === }
|
||||||
|
|
||||||
@@ -233,15 +246,19 @@ type
|
|||||||
readOffsetCallback : PPReadOffsetHook;
|
readOffsetCallback : PPReadOffsetHook;
|
||||||
{ Offset-based write for streaming mode — nil if not implemented }
|
{ Offset-based write for streaming mode — nil if not implemented }
|
||||||
writeOffsetCallback : PPWriteOffsetHook;
|
writeOffsetCallback : PPWriteOffsetHook;
|
||||||
|
{ Async offset-based read/write for streaming mode — nil if not implemented }
|
||||||
|
readOffsetAsyncCallback : PPReadOffsetAsyncHook;
|
||||||
|
writeOffsetAsyncCallback : PPWriteOffsetAsyncHook;
|
||||||
{ File size query — returns size in bytes without loading the file }
|
{ File size query — returns size in bytes without loading the file }
|
||||||
fileSizeCallback : PPFileSizeHook;
|
fileSizeCallback : PPFileSizeHook;
|
||||||
{ Async format — nil if FS only supports synchronous create }
|
{ Async format — nil if FS only supports synchronous create }
|
||||||
createAsyncCallback : PPCreateAsyncHook;
|
createAsyncCallback : PPCreateAsyncHook;
|
||||||
createDirAsyncCallback : PPCreateDirAsyncHook;
|
createDirAsyncCallback : PPCreateDirAsyncHook;
|
||||||
readDirAsyncCallback : PPReadDirAsyncHook;
|
readDirAsyncCallback : PPReadDirAsyncHook;
|
||||||
deleteFileAsyncCallback : PPDeleteFileAsyncHook;
|
|
||||||
deleteDirAsyncCallback : PPDeleteDirAsyncHook;
|
|
||||||
renameFileCallback : PPRenameFileHook;
|
renameFileCallback : PPRenameFileHook;
|
||||||
|
{ Per-file open/close — nil if FS does not cache per-file metadata }
|
||||||
|
openFileCallback : PPOpenFileHook;
|
||||||
|
closeFileCallback : PPCloseFileHook;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Generic storage volume }
|
{ Generic storage volume }
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -869,7 +869,8 @@ end;
|
|||||||
|
|
||||||
function readFileAtOffset(volume : PStorage_Volume; directory : pchar;
|
function readFileAtOffset(volume : PStorage_Volume; directory : pchar;
|
||||||
fileName : pchar; offset : uint32;
|
fileName : pchar; offset : uint32;
|
||||||
buffer : puint32; byteCount : uint32) : uint32;
|
buffer : puint32; byteCount : uint32;
|
||||||
|
ctx : pointer) : uint32;
|
||||||
var
|
var
|
||||||
fileEntries : PFile_Entry;
|
fileEntries : PFile_Entry;
|
||||||
fileCount : uint32;
|
fileCount : uint32;
|
||||||
|
|||||||
@@ -649,7 +649,8 @@ end;
|
|||||||
|
|
||||||
function readFileAtOffset(volume : PStorage_Volume; directory : pchar;
|
function readFileAtOffset(volume : PStorage_Volume; directory : pchar;
|
||||||
fileName : pchar; offset : uint32;
|
fileName : pchar; offset : uint32;
|
||||||
buffer : puint32; byteCount : uint32) : uint32;
|
buffer : puint32; byteCount : uint32;
|
||||||
|
ctx : pointer) : uint32;
|
||||||
var
|
var
|
||||||
buf : puint32;
|
buf : puint32;
|
||||||
pvd : PPVD;
|
pvd : PPVD;
|
||||||
|
|||||||
@@ -530,8 +530,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Write cached mbr to disk — buffer is the persistent cache }
|
{ Write cached mbr to disk through the storage manager's staged MBR path. }
|
||||||
driver.storage.mgr.storage_write_async(device, 0, 1, puint32(mbr), callback, callbackData);
|
driver.storage.mgr.write_mbr_async(device, mbr, callback, callbackData);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure remove_partition_async(device : PStorage_Device; slot : uint32;
|
procedure remove_partition_async(device : PStorage_Device; slot : uint32;
|
||||||
@@ -563,8 +563,8 @@ begin
|
|||||||
if (oldPart.LBA_start <> 0) and (oldPart.sector_count <> 0) then
|
if (oldPart.LBA_start <> 0) and (oldPart.sector_count <> 0) then
|
||||||
remove_volume_by_start(device, oldPart.LBA_start);
|
remove_volume_by_start(device, oldPart.LBA_start);
|
||||||
|
|
||||||
{ Write cached mbr to disk }
|
{ Write cached mbr to disk through the storage manager's staged MBR path. }
|
||||||
driver.storage.mgr.storage_write_async(device, 0, 1, puint32(mbr), callback, callbackData);
|
driver.storage.mgr.write_mbr_async(device, mbr, callback, callbackData);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure init_disk_async(device : PStorage_Device;
|
procedure init_disk_async(device : PStorage_Device;
|
||||||
@@ -594,8 +594,8 @@ begin
|
|||||||
PMaster_Boot_Record(cache)^.boot_sector := $AA55;
|
PMaster_Boot_Record(cache)^.boot_sector := $AA55;
|
||||||
device^.cachedMBR := pointer(cache);
|
device^.cachedMBR := pointer(cache);
|
||||||
|
|
||||||
{ Write to disk }
|
{ Write to disk through the storage manager's staged MBR path. }
|
||||||
driver.storage.mgr.storage_write_async(device, 0, 1, cache, callback, callbackData);
|
driver.storage.mgr.write_mbr_async(device, PMaster_Boot_Record(cache), callback, callbackData);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ ===================== Filesystem operations ===================== }
|
{ ===================== Filesystem operations ===================== }
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const
|
|||||||
PROCESS_STACK_SIZE = 8192;
|
PROCESS_STACK_SIZE = 8192;
|
||||||
|
|
||||||
{ Base quantum multiplier: quantum = Priority * BASE_QUANTUM ticks }
|
{ Base quantum multiplier: quantum = Priority * BASE_QUANTUM ticks }
|
||||||
BASE_QUANTUM = 5;
|
BASE_QUANTUM = 1;
|
||||||
|
|
|||||||
|
|
||||||
type
|
type
|
||||||
{ Forward declaration }
|
{ Forward declaration }
|
||||||
|
|||||||
Reference in new issue
Block a user
BASE_QUANTUM should no deviate from from 5, unless there's a very good reason.