<> <> <> <> DIRECTORY BootFile USING[ DiskFileID, Location ], Disk USING[ Channel, invalid, Label, 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, LVBootFile, PVBootFile, RunPageCount, VAMObject ], PhysicalVolume USING[ Physical, PhysicalRC, SubVolumeDetails ], VMBacking 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: BOOL _ FALSE, destroyed: BOOL _ FALSE, root: LONG POINTER TO VolumeFormat.LogicalRoot _ NIL, rootStatus: File.RC _ inconsistent, vamStatus: File.RC _ inconsistent, vamChanged: BOOL _ FALSE, checkpointing: BOOL _ TRUE, name: Rope.ROPE _ NIL, size: VolumeFormat.LogicalPageCount, free: VolumeFormat.LogicalPageCount _ 0, vam: VAM _ NIL, vamFile: File.Handle _ NIL, lastFileID: FileID _ NULL, freeboard: INT _ 0, flusher: File.VolumeFlusher _ NIL, flusherData: REF ANY _ NIL, flushing: BOOL _ FALSE]; 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 <> 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 VMBacking.RunTableObject; PhysicalRun: TYPE = VMBacking.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; <<-- ******** Checkpoint and Rollback (and ReadRootPage) ******** -->> LockAndCloseFiles: PROC; <> UnlockFiles: PROC; <> LockVolume: PROC[volume: File.Volume]; <> ReadRootPage: PROC[volume: File.Volume]; <> InitRootPage: PROC[volume: File.Volume, name: Rope.ROPE] RETURNS[File.RC]; <> LockMode: TYPE = { shared, exclusive }; Lock: PROC[file: Handle, mode: LockMode]; <> Unlock: PROC[file: Handle]; <> <<>> -- ******** Bad page table ******** -- PhysicalPageBad: PROC[physical: PhysicalVolume.Physical, address: Disk.PageNumber] RETURNS[ PhysicalVolume.PhysicalRC ]; <> GetBadPages: PROC[subVolume: PhysicalVolume.SubVolumeDetails, work: PROC[VolumeFormat.LogicalPage]]; <> -- ******** 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]; <> RecordRootFile: PROC[volume: File.Volume, root: File.VolumeFile, fp: File.FP, page: File.PageNumber, id: DiskFace.RelID, link: DiskFace.DontCare, channel: Disk.Channel]; <> NewID: PROC[volume: File.Volume] RETURNS [File.FileID]; <> WriteLogicalMarkers: PROC[volume: File.Volume] RETURNS[File.RC]; <> InitLogicalMarkers: PROC[volume: File.Volume] RETURNS[File.RC]; <> -- ******** Volume Allocation Map ******** -- VAM: TYPE = LONG POINTER TO VolumeFormat.VAMObject; Alloc: PROC[volume: File.Volume, first: VolumeFormat.LogicalPage, size, min: VolumeFormat.LogicalPageCount] RETURNS[given: VolumeFormat.LogicalRun]; <> Free: PROC[volume: File.Volume, logicalRun: VolumeFormat.LogicalRun]; <> Commit: PROC[volume: File.Volume]; <> Flush: PROC[volume: File.Volume, lack: VolumeFormat.LogicalPageCount] RETURNS[BOOL]; <> -- ******** Header and Run-table management ******** -- GetHeaderVM: PROC[file: Handle, runs: CARDINAL]; <> FreeHeaderVM: PROC[file: Handle]; <> TranslateLogicalRunTable: PROC[file: Handle] RETURNS[ File.PageCount ]; <> AddRun: PROC[file: Handle, run: POINTER TO PhysicalRun, logicalPage: VolumeFormat.LogicalPage, okPages: VolumeFormat.RunPageCount]; <> LastLogicalPage: PROC[file: Handle] RETURNS [VolumeFormat.LogicalPage]; <> RemoveFromRunTable: PROC[file: Handle, remove: INT]; <> FindRun: PROC[start: File.PageNumber, nPages: File.PageCount, runTable: RunTable] RETURNS[diskPage: Disk.PageNumber, size: Disk.PageCount, channel: Disk.Channel]; <> RegisterVMFile: PROC[file: File.Handle]; -- ******** Operations involving access to pages within a volume ******** -- FreeRun: PROC[logicalRun: VolumeFormat.LogicalRun, volume: File.Volume, verifyLabel: POINTER TO Disk.Label _ NIL]; <> EnumeratePagesProc: TYPE = PROC[status: Disk.Status, da: VolumeFormat.LogicalPage, label: POINTER TO Disk.Label] RETURNS[exit: BOOL _ FALSE]; EnumeratePages: PROC[volume: File.Volume, start: VolumeFormat.LogicalPage, work: EnumeratePagesProc]; <> -- ******** Global table of file objects ******** -- AllocForCreate: PROC RETURNS[Handle]; <> Insert: PROC [Handle]; <> DontInsert: PROC; <> Lookup: PROC [volume: File.Volume, fp: File.FP] RETURNS[Handle]; <> -- ******** Boot Locations ******** -- GetFileLocation: PROC [file: File.Handle, firstPage: File.PageNumber] RETURNS[location: BootFile.Location]; <> GetLogicalLocation: PROC [volume: File.Volume, root: VolumeFormat.LVBootFile] RETURNS[location: BootFile.Location]; <> GetPhysicalLocation: PROC [physical: PhysicalVolume.Physical, root: VolumeFormat.PVBootFile] RETURNS[location: BootFile.Location]; <> SetPhysicalLocation: PROC [physical: PhysicalVolume.Physical, root: VolumeFormat.PVBootFile, diskFileID: BootFile.DiskFileID] RETURNS[PhysicalVolume.PhysicalRC]; <> END.