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: 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 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; -- ******** 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]; -- ******** Volume Allocation Map ******** -- VAM: TYPE = LONG POINTER TO VolumeFormat.VAMObject; ReadRootPage: PROC[volume: File.Volume]; Alloc: PROC[volume: File.Volume, first: VolumeFormat.LogicalPage, size: 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]; -- ******** Global table of file objects ******** -- AllocForCreate: PROC RETURNS[Handle]; Insert: PROC [Handle]; Lookup: PROC [volume: File.Volume, id: File.FileID] RETURNS[Handle]; END. ÞCedar Nucleus (Files): internal interface FileInternal.mesa Andrew Birrell August 8, 1983 11:59 am The remaining fields (and fp.da) are accessed only under the per-file interlock, or during initialization or finalization of the object Gives physical-volume-relative data for a logical-volume-relative run Records the root file in the logical volume root page. Issues a new unique ID, ensuring all issued ID's are recorded in the volume root Reads the volume's VAM from disk and records free page count Find a logical run marked free in the in-core VAM. May be smaller than requested Mark the logical run free in the in-core VAM. Ensure the volume's VAM is up to date on disk 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. Allocate VM for a file's header, initializing file.logicalRunTable. Free VM that was used for file's header. Copy file's logical run table into newly allocated physical run table. Add pages to the file's physical and logical run tables Returns the logical page number of the last page of the file. Removes pages from the file's physical and logical run tables Find the physical location of contiguous initial subset of the given pages of the file. Write labels of specified pages marking them as "free". Allocate an object, but don't place it in the table. Insert the object into the table (after successful creation). Look-up the [volume,id] in the table, inserting if needed. ÊȘJšœ*™*Jšœ™Jšœ'™'J˜šÏk ˜ JšœœC˜MJšœ œ˜!JšœœœBœ0˜‚Jšœœœ˜Jšœ œf˜xJšœœ˜)Jšœ œ˜(—J˜Jšœœ œ˜!J˜Jš˜J˜J˜JšÏc8˜8˜Jšž œœœœ˜$J˜šž œœ œœ˜/Jšœœœ˜Jšœ˜Jšœ œœ!˜4Jšœ œœ˜Jš œœœœœ˜5Jšœœ˜#Jšœœ˜"Jšœ œœ˜J˜$J˜(Jšœœœ˜Jšœ œœ˜Jšœœ˜Jšœœ˜Jšœ œ˜Jšœœ˜"Jšœ œœœ˜—J˜Jšœœœ˜J˜š ž œœœ œœ˜0Jšœ œž<˜WJšœœž ˜'JšœœžD˜XJšœ œœž2˜JJšœœžM˜]Jšœ9žœ8™‡Jšœ(˜(Jšœœž˜+Jšœ œœœ˜Jšœ#œ˜'Jšœ˜Jšœœ!œ˜EJšœœ˜—J˜Jšœ œœ˜/J˜Jšœ œ˜#J˜šÏnœœœ ˜EJš˜šœ˜šœ˜J˜J˜J˜Jšœ˜——Jšœ˜J˜J˜—J˜J˜—JšžS˜S˜šŸœœ:˜Sšœ3˜:JšœE™E——J˜šŸœœ6œ]˜©Jšœ6™6—J˜šŸœœœ˜7JšœP™PJ˜J˜—J˜J˜—Jšž-˜-˜Jš œœœœœ˜3J˜šŸ œœ˜(Jšœ<™<—J˜šŸœœ6˜AJ˜$šœ!˜(JšœQ™Q——J˜šŸœœ;˜EJšœ-™-—J˜šŸœœ˜"Jšœ-™-—J˜šŸœœ;œœ˜TJšœŠ™ŠJ˜J˜J˜—J˜J˜—Jšž7˜7˜šŸ œœœ˜0JšœC™C—J˜šŸ œœ˜!Jšœ(™(—J˜šŸœœœ˜GJšœF™F—J˜šŸœœ˜Jšœœœ ˜J˜&šœ$˜$Jšœ7™7——J˜šŸœœœ˜GJšœ=™=—J˜šŸœœœ˜4Jšœ=™=—J˜šŸœœD˜QšœI˜PJšœW™W——J˜šŸœœ˜(J˜—J˜J˜—JšžL˜L˜šŸœœ;˜HJšœ7™7J˜—J˜J˜—Jšž4˜4˜šŸœœœ ˜%J™4—J˜šŸœœ ˜J™=—J˜šŸœœ(œ ˜DJ™;—J˜—Jšœ˜J˜J˜—…—x