<> <> <> <> <> <> <> <> <<>> DIRECTORY BootFile USING [DiskFileID, Location], Disk USING [Channel, invalid, Label, labelCheck, ok, PageNumber, PageCount, Request, Status], DiskFace USING [DontCare, RelID], File USING [FP, FileID, Handle, nullFP, PageCount, PageNumber, PropertyStorage, RC, Volume, VolumeFile, VolumeID], FileBackdoor USING [VolumeFlusher], 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 FileImplMonitorLock: MONITORLOCK; -- monitor for FileImpl and FilePagesImpl <> << 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: FileBackdoor.VolumeFlusher _ NIL, flusherData: REF ANY _ NIL, flushing: BOOL _ FALSE ]; Handle: TYPE = REF Object; << Exported to 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, diskRunPages: CARDINAL _ 1, runPages: CARDINAL _ 1, diskPropertyPages: CARDINAL _ 1, propertyPages: CARDINAL _ 1, logicalRunTable: LONG POINTER TO VolumeFormat.LogicalRunObject _ NIL, runTable: RunTable _ NIL ]; RunTable: TYPE = REF VMBacking.RunTableObject; PhysicalRun: TYPE = VMBacking.Run; scratchWriter: LONG POINTER; -- scratch buffer for writing (all 0) scratchReader: LONG POINTER; -- scratch buffer for reading notReallyFree: INT ; DoPinnedIO: PROC[channel: Disk.Channel, label: POINTER TO Disk.Label, req: POINTER TO Disk.Request] RETURNS[ status: Disk.Status, countDone: Disk.PageCount] ; <> TranslateStatus: PROC[status: Disk.Status] RETURNS [File.RC] = INLINE { RETURN[ SELECT status FROM Disk.ok => ok, Disk.labelCheck => software, Disk.invalid => wentOffline, ENDCASE => hardware ] }; ActionType: TYPE = {write, read}; WhereLocation: TYPE = {header, data}; MaxTransferRun: Disk.PageCount; Transfer: PROC[file: Handle, data: LONG POINTER, filePage: File.PageNumber, nPages: File.PageCount, action: ActionType, where: WhereLocation ]; <> CheckStatus: PROC[status: Disk.Status, diskPage: INT]; <> <<-- ******** Labels ******** -->> <<>> <<>> HeaderLabel: PROC[fp: File.FP] RETURNS[Disk.Label]; DataLabel: PROC[fp: File.FP] RETURNS[Disk.Label] ; FreeLabel: PROC[volume: File.Volume] RETURNS[Disk.Label] ; WriteLabels: PROC[channel: Disk.Channel, diskPage: Disk.PageNumber, count: Disk.PageCount, data: LONG POINTER, label: POINTER TO Disk.Label] RETURNS[ status: Disk.Status, countDone: Disk.PageCount] ; VerifyLabels: PROC[channel: Disk.Channel, diskPage: Disk.PageNumber, count: Disk.PageCount, label: POINTER TO Disk.Label] RETURNS[ status: Disk.Status, countDone: Disk.PageCount] ; GetScratchPage: PROC RETURNS[data: LONG POINTER]; FreeScratchPage: PUBLIC PROC[data: LONG POINTER]; <<>> <<-- ******** 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]; <> <<>> Acquire: PROC[file: Handle, mode: LockMode]; <<>> <> PhysicalPageBad: PROC[physical: PhysicalVolume.Physical, address: Disk.PageNumber] RETURNS[ badTableFull: BOOL, status: PhysicalVolume.PhysicalRC ]; <> GetBadPages: PROC[subVolume: PhysicalVolume.SubVolumeDetails, work: PROC[VolumeFormat.LogicalPage]]; <> <> 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]; <> <> VAM: TYPE = LONG POINTER TO VolumeFormat.VAMObject; FindLargestFreeBlockInBiggestSubVolume: PROC[volume: File.Volume] RETURNS [first: VolumeFormat.LogicalPage, count: VolumeFormat.LogicalPageCount, subVolume: PhysicalVolume.SubVolumeDetails]; <> IsUsed: PROC[volume: File.Volume, page: VolumeFormat.LogicalPage] RETURNS [inUse: BOOL]; <> <<>> SetPageUsed: PROC[volume: File.Volume, page: VolumeFormat.LogicalPage, inUse: BOOL] RETURNS [wasInUse: BOOL]; <> <<>> 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]; <> <
> RunsToHeaderPages: PROC[runs: CARDINAL] RETURNS [pages: VolumeFormat.LogicalPageCount]; HeaderPagesToRuns: PROC[pages: VolumeFormat.LogicalPageCount] RETURNS [runs: CARDINAL]; WriteRunTable: PROC[file: Handle]; <> GetHeaderVM: PROC[file: Handle, runs: CARDINAL, propertyPages: CARDINAL _ 1]; <> FreeHeaderVM: PROC[file: Handle]; <> TranslateLogicalRunTable: PROC[file: Handle, prefixOnly: BOOL _ FALSE] 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]; <> SplitPhysicalRunTable: PROC[file: File.Handle, page: VolumeFormat.LogicalPage] RETURNS [runNumber: CARDINAL]; <> ExtendFileHeader: PROC[file: File.Handle, newRunPages: CARDINAL, newPropertyPages: CARDINAL]; RegisterVMFile: PROC[file: File.Handle]; <> 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, diskPage: INT] RETURNS[exit: BOOL _ FALSE]; <> EnumeratePages: PROC[volume: File.Volume, start: VolumeFormat.LogicalPage, skipBadPages: BOOL _ TRUE, work: EnumeratePagesProc]; <> <> AllocForCreate: PROC RETURNS[Handle]; <> Insert: PROC [Handle]; <> DontInsert: PROC; <> Lookup: PROC [volume: File.Volume, fp: File.FP] RETURNS[Handle]; <> <> 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. << >> <> <> <<>>