Cedar Nucleus (Files): internal interface
FileInternal.mesa
Andrew Birrell August 8, 1983 11:59 am
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 ];
FileInternal: CEDAR DEFINITIONS =
BEGIN
-- ******** Data Types and minor subroutines ******** --
--File.--FileID: TYPE = RECORD[INT];
--File.--VolumeObject: TYPE = MONITORED RECORD[
rest: REF VolumeObject ← NIL,
id: File.VolumeID,
subVolumes: LIST OF PhysicalVolume.SubVolumeDetails,
initialised: BOOLFALSE,
root: LONG POINTER TO VolumeFormat.LogicalRoot ← NIL,
rootStatus: File.RC ← inconsistent,
vamStatus: File.RC ← inconsistent,
name: Rope.ROPENIL,
size: VolumeFormat.LogicalPageCount,
free: VolumeFormat.LogicalPageCount ← 0,
vam: VAMNIL,
vamChanged: BOOLFALSE,
vamFile: File.Handle ← NIL,
lastFileID: FileID ← NULL,
freeboard: INT ← 0,
flusher: File.VolumeFlusher ← NIL,
flusherData: REF ANYNIL];
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: BOOLFALSE, -- 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 POINTERNIL,
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;
-- ******** Access to volume root page and volume's list of sub-volumes ******** --
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
-- ******** Volume Allocation Map ******** --
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.
-- ******** Header and Run-table management ******** --
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];
-- ******** Operations involving access to pages within a volume ******** --
FreeRun: PROC[logicalRun: VolumeFormat.LogicalRun, volume: File.Volume];
Write labels of specified pages marking them as "free".
-- ******** Global table of file objects ******** --
AllocForCreate: PROC RETURNS[Handle];
Allocate an object, but don't place it in the table.
Insert: PROC [Handle];
Insert the object into the table (after successful creation).
Lookup: PROC [volume: File.Volume, id: File.FileID] RETURNS[Handle];
Look-up the [volume,id] in the table, inserting if needed.
END.