DIRECTORY
Disk USING[ Channel, invalid, labelCheck, ok, PageNumber, PageCount, Status],
DiskFace USING[ DontCare, RelID],
File USING[ FP, FileID, Handle, nullFP, PageCount, PageNumber, PropertyStorage, RC, Volume, VolumeFile, VolumeFlusher, VolumeID ],
Rope USING[ ROPE ],
VolumeFormat USING[ LogicalPage, LogicalPageCount, LogicalRoot, LogicalRun, LogicalRunObject, RunPageCount, VAMObject ],
PhysicalVolume USING[ SubVolumeDetails ],
VMSideDoor USING[ Run, RunTableObject ];
--File.--FileID: TYPE = RECORD[INT];
--File.--VolumeObject:
TYPE =
MONITORED
RECORD[
rest: REF VolumeObject ← NIL,
id: File.VolumeID,
subVolumes: LIST OF PhysicalVolume.SubVolumeDetails,
initialised: BOOL ← FALSE,
root: LONG POINTER TO VolumeFormat.LogicalRoot ← NIL,
rootStatus: File.RC ← inconsistent,
vamStatus: File.RC ← inconsistent,
name: Rope.ROPE ← NIL,
size: VolumeFormat.LogicalPageCount,
free: VolumeFormat.LogicalPageCount ← 0,
vam: VAM ← NIL,
vamChanged: BOOL ← FALSE,
vamFile: File.Handle ← NIL,
lastFileID: FileID ← NULL,
freeboard: INT ← 0,
flusher: File.VolumeFlusher ← NIL,
flusherData: REF ANY ← NIL];
Handle: TYPE = REF Object;
--File.--Object:
PUBLIC
TYPE =
MONITORED
RECORD[
fp: File.FP ← File.nullFP, -- fp.id is immutable; fp.da is under the per-file interlock
volume: File.Volume ← NIL, -- immutable
rest: Handle ← NIL, -- chain in file hash table used by FileTableImpl inside its monitor
reissued: BOOL ← FALSE, -- marker used by FileTableImpl inside its monitor
users: INT ← 0, -- per-file shared/exclusive interlock. Accessed under FileImpl monitor lock
The remaining fields (and fp.da) are accessed only under the per-file interlock, or during initialization or finalization of the object
state: { none, opened, deleted } ← none,
headerVMPages: INT ← 0, -- how many to free
headerVM: LONG POINTER ← NIL,
properties: File.PropertyStorage ← NIL,
size: File.PageCount ← 0,
logicalRunTable: LONG POINTER TO VolumeFormat.LogicalRunObject ← NIL,
runTable: RunTable ← NIL ];
RunTable: TYPE = REF VMSideDoor.RunTableObject;
PhysicalRun: TYPE = VMSideDoor.Run;
TranslateStatus:
PROC[status: Disk.Status]
RETURNS [File.RC] =
INLINE
BEGIN
RETURN[
SELECT status
FROM
Disk.ok => ok,
Disk.labelCheck => software,
Disk.invalid => wentOffline,
ENDCASE => hardware ]
END;
TranslateLogicalRun:
PROC[logicalRun: VolumeFormat.LogicalRun, volume: File.Volume]
RETURNS[channel: Disk.Channel, diskPage: Disk.PageNumber];
Gives physical-volume-relative data for a logical-volume-relative run
RecordRootFile:
PROC[volume: File.Volume, root: File.VolumeFile, fp: File.
FP, page: File.PageNumber, id: DiskFace.RelID, link: DiskFace.DontCare, channel: Disk.Channel];
Records the root file in the logical volume root page.
NewID:
PROC[volume: File.Volume]
RETURNS [File.FileID];
Issues a new unique ID, ensuring all issued ID's are recorded in the volume root
VAM: TYPE = LONG POINTER TO VolumeFormat.VAMObject;
ReadRootPage:
PROC[volume: File.Volume];
Reads the volume's VAM from disk and records free page count
Alloc:
PROC[volume: File.Volume, first: VolumeFormat.LogicalPage,
size: VolumeFormat.LogicalPageCount]
RETURNS[given: VolumeFormat.LogicalRun];
Find a logical run marked free in the in-core VAM. May be smaller than requested
Free:
PROC[volume: File.Volume, logicalRun: VolumeFormat.LogicalRun];
Mark the logical run free in the in-core VAM.
Commit:
PROC[volume: File.Volume];
Ensure the volume's VAM is up to date on disk
Flush:
PROC[volume: File.Volume, lack: VolumeFormat.LogicalPageCount]
RETURNS[
BOOL];
Try to ensure there are at least "lack" free pages on the volume by running any volume flusher. Returns TRUE iff it might have succeeded.
GetHeaderVM:
PROC[file: Handle, runs:
CARDINAL];
Allocate VM for a file's header, initializing file.logicalRunTable.
FreeHeaderVM:
PROC[file: Handle];
Free VM that was used for file's header.
TranslateLogicalRunTable:
PROC[file: Handle]
RETURNS[ File.PageCount ];
Copy file's logical run table into newly allocated physical run table.
AddRun:
PROC[file: Handle,
run: POINTER TO PhysicalRun,
logicalPage: VolumeFormat.LogicalPage,
okPages: VolumeFormat.RunPageCount];
Add pages to the file's physical and logical run tables
LastLogicalPage:
PROC[file: Handle]
RETURNS [VolumeFormat.LogicalPage];
Returns the logical page number of the last page of the file.
RemoveFromRunTable:
PROC[file: Handle, remove:
INT];
Removes pages from the file's physical and logical run tables
FindRun:
PROC[start: File.PageNumber, nPages: File.PageCount, runTable: RunTable]
RETURNS[diskPage: Disk.PageNumber, size: Disk.PageCount, channel: Disk.Channel];
Find the physical location of contiguous initial subset of the given pages of the file.
RegisterVMFile:
PROC[file: File.Handle];