(FILECREATED "30-Oct-84 14:23:01" {ERIS}<STANSBURY>HARMONYDFS>DLIONFS.;1 68257 changes to: (FNS \DFSGetStreamForFile) (VARS DLIONFSCOMS) previous date: "11-Oct-84 13:57:25" {ERIS}<LISP>HARMONY>SOURCES>DLIONFS.;8) (* Copyright (c) 1983, 1984 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT DLIONFSCOMS) (RPAQQ DLIONFSCOMS ((DECLARE: EVAL@COMPILE DONTCOPY (COMS * DLIONFSCOMPILECOMS)) (DECLARE: (LOCALVARS . T)) (INITRECORDS PageGroup) (* * Public entry) (FNS DFSCREATEDIRECTORY DFSPURGEDIRECTORY VOLUMES VOLUMETYPE \DFSVolumeType) (FNS \DFSCurrentVolume \DFSCurrentVol \DFSLispVolumeP \DFSGetLVPage) (* * Initialization routines) (FNS \DFSDEVICEP \DFSEnsureDlion \DFSEnsureInitialized \DFSInit \DFSPhysicalVolumeOK \DFSCreateDevice \DFSDeviceConflict) (GLOBALVARS \DFSInitialized \DFSdevice \PhysVolumePage \DFStopMonitor) [INITVARS (\DFSInitialized NIL) \DFSdevice (\DFStopMonitor (CREATE.MONITORLOCK (QUOTE topMonitor] (P (ADDTOVAR \SYSTEMCACHEVARS \DFSInitialized)) (FNS \DFSAtLoad) (P (\DFSAtLoad)) (* * Device methods) (FNS \DFSOpenFile \DFSGetStreamForFile \DFSOpenOldFile \DFSGenFileID \DFSCreateFile \DFSNewPages \DFSMakeLeaderPage \DFSUpdateLeaderPage \DFSWriteLeaderPage \DFSFindPageAddr) (FNS \DFSCloseFile \DFSTrimHelper) (FNS \DFSDeleteFile) (FNS \DFSReadPages \DFSReadOnePage) (FNS \DFSWritePages \DFSWriteOnePage \DFSExtendFile) (FNS \DFSGetFileInfo) (FNS \DFSSetFileInfo) (FNS \DFSGetFileName) (FNS \DFSEventFn) (FNS \DFSFreeDiskPages) (FNS \DFSDirectoryNameP) (FNS \DFSHostNameP) (* * Routines for mapping file names onto volumes and directories) (FNS \DFSFileNameToDirectory \DFSVolumeNameToNumber \DFSFirstDirectory) (* * These functions transfer pages to and from the disk) (FNS \PvTransferPage \PvTransferPageNoSwap \LvGetPage \LvPutPage) [DECLARE: DONTEVAL@LOAD (P (\LOCKFN (QUOTE \PvTransferPage)) (\LOCKFN (QUOTE \PvTransferPageNoSwap)) (\LOCKVAR (QUOTE \DFSWriteFlg] (GLOBALVARS \DFSWriteFlg \DFSioMonitor) [INITVARS (\DFSioMonitor (CREATE.MONITORLOCK (QUOTE ioMonitor] (* * Display stuff) (FNS VOLUMEDISPLAY \DFSDsplyVolumes \DFSDsplyVolumes.REPAINTFN) (GLOBALVARS \DFSDISPLAY \DFSfixedFont \DFSfixedBold) (INITVARS (\DFSfixedFont (FONTCREATE (QUOTE GACHA) 10 (QUOTE MRR))) (\DFSfixedBold (FONTCREATE (QUOTE GACHA) 10 (QUOTE BRR))) \DFSDISPLAY) (* * Load other file system modules) (FILES VOLUMEDIRECTORY VOLUMEFILEMAP VOLUMEALLOCATIONMAP))) (DECLARE: EVAL@COMPILE DONTCOPY (RPAQQ DLIONFSCOMPILECOMS ((* * File system constants. maxPagesPerFile = 2↑23 - 1) (CONSTANTS (tUnassigned 0) (tPhysicalVolumeRootPage 1) (tSubVolumeMarkerPage 4) (tLogicalVolumeRootPage 5) (tFreePage 6) (tVolumeAllocationMap 7) (tVolumeFileMap 8) (tRootDirectory 18) (maxPagesPerFile 8388607) (lastPageNumber (SUB1 maxPagesPerFile)) (nullVolumePage 0) (maxLogicalVolumes 10)) (CONSTANTS (DFSPilotVolume 0) (DFSLispVolume 3)) (CONSTANTS (hardMicrocode 0)) (* * File system datatypes) (RECORDS Page) (FILES MESATYPES) (RECORDS FileID VolumeID Key Interval PageGroup FileDescriptor DiskFileID LVBootFiles RootFileArray LogicalVolumeDescriptor PVBootFiles SubVolumeDesc SubVolumeArray PhysicalVolumeDescriptor LogicalSubVolumeMarker SubVolumeMarkerPage Label) (MACROS Vfm FetchAtom ReplaceAtom) (RECORDS DLIONSTREAM DLIONDISK COREDEVICE LeaderPage) (RECORDS UNAME DFSFileSpec) (* * Macros for page reading &writing, etc.) (MACROS LVEqual VolumeNumber SwapIn&Dirty LvBasePageAddr MarkerPageAddr DiskError) (* * Interface to logical volumes, devices, directories) (MACROS CreateVols InitializeVols GetVols GetVol CreateDirectories PutDirectory GetDirectory) (GLOBALVARS \DFSLogicalVolumes \DFSdirectories) (* * Assertion mechanism) (VARS Assert) (MACROS Assert) (* * The following are for diagnostic purposes.) (FNS DISPLAYPAGE DISPLAYWORDS ShowIntervals REL))) (* * File system constants. maxPagesPerFile = 2↑23 - 1) (DECLARE: EVAL@COMPILE (RPAQQ tUnassigned 0) (RPAQQ tPhysicalVolumeRootPage 1) (RPAQQ tSubVolumeMarkerPage 4) (RPAQQ tLogicalVolumeRootPage 5) (RPAQQ tFreePage 6) (RPAQQ tVolumeAllocationMap 7) (RPAQQ tVolumeFileMap 8) (RPAQQ tRootDirectory 18) (RPAQQ maxPagesPerFile 8388607) (RPAQ lastPageNumber (SUB1 maxPagesPerFile)) (RPAQQ nullVolumePage 0) (RPAQQ maxLogicalVolumes 10) (CONSTANTS (tUnassigned 0) (tPhysicalVolumeRootPage 1) (tSubVolumeMarkerPage 4) (tLogicalVolumeRootPage 5) (tFreePage 6) (tVolumeAllocationMap 7) (tVolumeFileMap 8) (tRootDirectory 18) (maxPagesPerFile 8388607) (lastPageNumber (SUB1 maxPagesPerFile)) (nullVolumePage 0) (maxLogicalVolumes 10)) ) (DECLARE: EVAL@COMPILE (RPAQQ DFSPilotVolume 0) (RPAQQ DFSLispVolume 3) (CONSTANTS (DFSPilotVolume 0) (DFSLispVolume 3)) ) (DECLARE: EVAL@COMPILE (RPAQQ hardMicrocode 0) (CONSTANTS (hardMicrocode 0)) ) (* * File system datatypes) [DECLARE: EVAL@COMPILE (RECORD Page NIL (CREATE (NCREATE (QUOTE VMEMPAGEP))) (TYPE? (TYPENAMEP DATUM (QUOTE VMEMPAGEP)))) ] (FILESLOAD MESATYPES) [DECLARE: EVAL@COMPILE (MESATYPE FileID (2 WORD)) (MESATYPE VolumeID (5 WORD)) (MESARECORD Key ((fileID SWAPPEDFIXP) (filePage SWAPPEDFIXP))) (MESARECORD Interval ((key Key) (volumePage SWAPPEDFIXP) (nextKey Key))) (DATATYPE PageGroup ((filePage SWAPPEDFIXP) (volumePage SWAPPEDFIXP) (nextFilePage SWAPPEDFIXP))) (MESARECORD FileDescriptor ((fileID SWAPPEDFIXP) (volumeID VolumeID) (type WORD) location immutable temporary (size SWAPPEDFIXP))) (MESARECORD DiskFileID ((fID VolumeID) (firstPage SWAPPEDFIXP) (da SWAPPEDFIXP)) (* Booting information) ) (MESAARRAY LVBootFiles ((0 5)) DiskFileID (* Booting information) ) (MESAARRAY RootFileArray ((6 14)) FileID) (MESARECORD LogicalVolumeDescriptor ((seal WORD) (* Validation ; absolutely must be first field) (version WORD) (* must be 2nd field) (vID VolumeID) (* ID of This Volume) (labelLength WORD) (* Length of th ASCII name of this volume) (label 40 BYTE) (* Volume name in AScII) (type WORD) (volumeSize SWAPPEDFIXP) (* Number of pages in this volume) (bootingInfo LVBootFiles) (* Defines 6 PILOT file types) (NIL WORD) (NIL BITS 15) (changing FLAG) (* Change field decls from here on only) (* boolean ← T) (freePageCount SWAPPEDFIXP) (* Number of free pages remaining) (vamStart SWAPPEDFIXP) (vfmStart SWAPPEDFIXP) (* Relative address of the start of the volume file map) (lowerBound SWAPPEDFIXP) (volumeRootDirectory SWAPPEDFIXP) (rootFileID RootFileArray) (lastIDAllocated SWAPPEDFIXP) (* Highest numbered File.ID given out on this volume. We reserve the first set of IDs for Pilot's own use. In particular, files of type IN PilotRootFileType may have their ID the same as their File.Type.) (scavengerLogVolume VolumeID) (lastTimeOpendForWrite SWAPPEDFIXP) (NIL 131 WORD) (checksum WORD) (* Must be the last field) ) (ACCESSFNS (LVlabel (FetchAtom (LOCF (fetch ( LogicalVolumeDescriptor label) of DATUM)) (LOCF (fetch ( LogicalVolumeDescriptor labelLength) of DATUM))) (ReplaceAtom (LOCF (fetch ( LogicalVolumeDescriptor label) of DATUM)) (LOCF (fetch ( LogicalVolumeDescriptor labelLength) of DATUM)) 40 NEWVALUE))) (CREATE (create Page)) (TYPE? (type? Page DATUM))) (MESAARRAY PVBootFiles ((0 3)) DiskFileID) (MESARECORD SubVolumeDesc ((lvID VolumeID) (lvSize SWAPPEDFIXP) (lvPage SWAPPEDFIXP) (pvPage SWAPPEDFIXP) (nPages SWAPPEDFIXP))) (MESAARRAY SubVolumeArray ((0 9)) SubVolumeDesc) (MESARECORD PhysicalVolumeDescriptor ((seal WORD) (* Validation) (version WORD) (labelLength WORD) (pvID VolumeID) (bootingInfo PVBootFiles) (* Defines 4 PILOT file types) (label 40 BYTE) (* Ascii name of the volume) (subVolumeCount WORD) (subVolumeMarkerID VolumeID) (* Marker pages belong to this Pseudo File) (badPageCount SWAPPEDFIXP) (maxBadPages SWAPPEDFIXP) (onLineCount WORD) (subVolumes SubVolumeArray) (* See SubVolumeDesc record for description of each of six entries stored here) (NIL 47 WORD) (localTimeParametersValid WORD) (localTimeParameters 2 WORD) (checksum WORD)) (ACCESSFNS (PVlabel (FetchAtom (LOCF (fetch ( PhysicalVolumeDescriptor label) of DATUM)) (LOCF (fetch ( PhysicalVolumeDescriptor labelLength) of DATUM))) (ReplaceAtom (LOCF (fetch ( PhysicalVolumeDescriptor label) of DATUM)) (LOCF (fetch ( PhysicalVolumeDescriptor labelLength) of DATUM)) 40 NEWVALUE))) (CREATE (create Page)) (TYPE? (type? Page DATUM))) (MESARECORD LogicalSubVolumeMarker ((seal WORD) (version WORD) (labelLength BITS 6) (type BITS 2) (NIL BITS 8) (label 20 WORD) (bootingInfo LVBootFiles) (volumeRootDirectory SWAPPEDFIXP))) (MESARECORD SubVolumeMarkerPage ((logical LogicalSubVolumeMarker) (* Incomplete) ) (CREATE (create Page)) (TYPE? (type? Page DATUM))) (MESARECORD Label ((fileID VolumeID) (* valid in label of every page) (filePageLo WORD) (filePageHi BITS 7) (* 23 bit page number, valid in label of every page) (NIL BITS 6) (* always zero) (immutable FLAG) (* valid only in label of page 0) (temporary FLAG) (* valid only in label of page 0) (zeroSize FLAG) (* valid only in label of page 0) (type WORD) (* valid in label of every page) bootChainLink (* valid in label of every page) ) (ACCESSFNS (filePage (\MAKENUMBER (fetch (Label filePageHi) of DATUM) (fetch (Label filePageLo) of DATUM)) (PROGN (replace (Label filePageHi) of DATUM with (\HINUM NEWVALUE)) (replace (Label filePageLo) of DATUM with (\LONUM NEWVALUE)) NEWVALUE)))) ] (/DECLAREDATATYPE (QUOTE PageGroup) (QUOTE (SWAPPEDFIXP SWAPPEDFIXP SWAPPEDFIXP))) (DECLARE: EVAL@COMPILE (PUTPROPS Vfm MACRO ((vol) (PROGN (* * Returns the file ID of the volume file map) (* * I think (not sure for Klamath) the way it's supposed to do this is to look up the tVolumeFileMap'th element of the RootFileArray of the volume. But that doesn't work right now because of a bug in Mesatypes. Won't matter till we write labels) tVolumeFileMap))) (PUTPROPS FetchAtom MACRO [(start length) (U-CASE (PACKC (for pos from 0 to (SUB1 (\GETBASE length 0)) collect (\GETBASEBYTE start pos]) (PUTPROPS ReplaceAtom MACRO [LAMBDA (startLoc lengthLoc maxLength newAtom) (PROG ((chars (CHCON (MKATOM newAtom))) length) (SETQ length (MIN (LENGTH chars) maxLength)) (* * Output characters) (for char in chars as pos from 0 to (SUB1 length) do (\PUTBASEBYTE startLoc pos char)) (* * Output length of atom) (\PUTBASE lengthLoc 0 length)) newAtom]) ) [DECLARE: EVAL@COMPILE (RECORD DLIONSTREAM STREAM (SUBRECORD STREAM) [ACCESSFNS ((FILEDESC (fetch F1 of DATUM) (replace F1 of DATUM with NEWVALUE)) (LEADERPAGE (fetch F2 of DATUM) (replace F2 of DATUM with NEWVALUE)) (VOLUME (fetch F3 of DATUM) (replace F3 of DATUM with NEWVALUE)) (DIRINFO (fetch F4 of DATUM) (replace F4 of DATUM with NEWVALUE)) (DIRHOLEPTR (fetch F5 of DATUM) (replace F5 of DATUM with NEWVALUE] [TYPE? (AND (type? STREAM DATUM) (type? LogicalVolumeDescriptor (fetch (DLIONSTREAM VOLUME) of DATUM]) (RECORD DLIONDISK FDEV (SUBRECORD FDEV) [TYPE? (AND (type? FDEV DATUM) (EQ (fetch (FDEV CLOSEFILE) of DATUM) (QUOTE \DFSCloseFile]) (RECORD COREDEVICE NIL [TYPE? (AND (type? FDEV DATUM) (EQ (FUNCTION \CORE.CLOSEFILE) (fetch (FDEV CLOSEFILE) of DATUM]) (MESARECORD LeaderPage ((TimeCreate FIXP) (TimeWrite FIXP) (TimeRead FIXP) (FileID SWAPPEDFIXP) (AllocatedPages FIXP) (EofPage FIXP) (EOffSet WORD) (NameLength WORD) (FileName 100 BYTE) (AuthorLength WORD) (AuthorName 30 BYTE)) (ACCESSFNS (fileName (FetchAtom (LOCF (fetch (LeaderPage FileName) of DATUM)) (LOCF (fetch (LeaderPage NameLength) of DATUM))) (ReplaceAtom (LOCF (fetch (LeaderPage FileName) of DATUM)) (LOCF (fetch (LeaderPage NameLength) of DATUM)) 100 NEWVALUE))) (ACCESSFNS (author (FetchAtom (LOCF (fetch (LeaderPage AuthorName) of DATUM)) (LOCF (fetch (LeaderPage AuthorLength) of DATUM))) (ReplaceAtom (LOCF (fetch (LeaderPage AuthorName) of DATUM)) (LOCF (fetch (LeaderPage AuthorLength) of DATUM)) 30 NEWVALUE))) (CREATE (create Page)) (TYPE? (type? Page DATUM))) ] [DECLARE: EVAL@COMPILE (RECORD UNAME ((VERSION PARTNUM . ESCFLAG) . CHARPAIRS)) (RECORD DFSFileSpec (UNAME FSDIRPTR)) ] (* * Macros for page reading &writing, etc.) (DECLARE: EVAL@COMPILE (PUTPROPS LVEqual MACRO ((a b) (MESAEQUAL (fetch (LogicalVolumeDescriptor vID) of a) (fetch (LogicalVolumeDescriptor vID) of b) VolumeID))) (PUTPROPS VolumeNumber MACRO [(vol) (* hts: "28-May-84 20:19") (* vol: LogicalVolumeDescriptor; RETURNS: FIXP in 1..6) (* Converts vol into a logical volume number, becuase the page reading and writing routines expect a logical volume number rather than the logical volume itself. Should be changed later.) (OR (for otherVol in (GetVols) as volumeNumber from 0 do (if (LVEqual vol otherVol) then (RETURN volumeNumber))) (SHOULDNT (QUOTE cantFindLogicalVolume]) (PUTPROPS SwapIn&Dirty MACRO (OPENLAMBDA (page) (\PUTBASE page 0 (\GETBASE page 0)))) (PUTPROPS LvBasePageAddr MACRO ((vol) (fetch (SubVolumeDesc pvPage) of (FMESAELT (fetch ( PhysicalVolumeDescriptor subVolumes) of \PhysVolumePage) SubVolumeArray vol)))) (PUTPROPS MarkerPageAddr MACRO [(vol) (fetch (SubVolumeDesc nPages) of (FMESAELT (fetch ( PhysicalVolumeDescriptor subVolumes) of \PhysVolumePage) SubVolumeArray (OR (FIXP vol) (VolumeNumber vol]) (PUTPROPS DiskError MACRO ((errorMessage errorMessage2) (PROG ((\INTERRUPTABLE T)) (* * Gross hack to allow the error to show up as a break rather than a 9318) (LISPERROR errorMessage errorMessage2)))) ) (* * Interface to logical volumes, devices, directories) (DECLARE: EVAL@COMPILE (PUTPROPS CreateVols MACRO [NIL (if [NOT (AND (BOUNDP (QUOTE \DFSLogicalVolumes)) (type? ARRAYP \DFSLogicalVolumes) (ZEROP (ARRAYORIG \DFSLogicalVolumes)) (EQ maxLogicalVolumes (ARRAYSIZE \DFSLogicalVolumes] then (SETQ \DFSLogicalVolumes (ARRAY maxLogicalVolumes NIL NIL 0)) (for volNum from 0 to (SUB1 maxLogicalVolumes) do (SETA \DFSLogicalVolumes volNum (create LogicalVolumeDescriptor]) (PUTPROPS InitializeVols MACRO [NIL (PROGN (for volNum from 0 to (SUB1 (fetch ( PhysicalVolumeDescriptor subVolumeCount) of \PhysVolumePage)) do (\LvGetPage volNum 0 (GetVol volNum)) ) (* * DFSEventFn requires that extra LV pages be zeroed to facilitate finding out-of-date dliondisk fdevs.) (for volNum from (fetch (PhysicalVolumeDescriptor subVolumeCount) of \PhysVolumePage) to (SUB1 maxLogicalVolumes) do (\ZEROPAGE (fetch (POINTER PAGE#) of (GetVol volNum]) (PUTPROPS GetVols MACRO (NIL (for volNum from 0 to (SUB1 (fetch (PhysicalVolumeDescriptor subVolumeCount) of \PhysVolumePage)) collect (GetVol volNum)))) (PUTPROPS GetVol MACRO ((volNum) (ELT \DFSLogicalVolumes volNum))) (PUTPROPS CreateDirectories MACRO [NIL (if [NOT (AND (BOUNDP (QUOTE \DFSdirectories)) (type? ARRAYP \DFSdirectories) (ZEROP (ARRAYORIG \DFSdirectories)) (EQ maxLogicalVolumes (ARRAYSIZE \DFSdirectories] then (SETQ \DFSdirectories (ARRAY maxLogicalVolumes NIL NIL 0]) (PUTPROPS PutDirectory MACRO (OPENLAMBDA (vol directory) (SETA \DFSdirectories (OR (FIXP vol) (VolumeNumber vol)) directory))) (PUTPROPS GetDirectory MACRO [OPENLAMBDA (vol) (ELT \DFSdirectories (OR (FIXP vol) (VolumeNumber vol]) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \DFSLogicalVolumes \DFSdirectories) ) (* * Assertion mechanism) (RPAQQ Assert T) (DECLARE: EVAL@COMPILE (PUTPROPS Assert MACRO (ARGS (if (AND (BOUNDP (QUOTE Assert)) Assert) then [CONS (QUOTE PROG) (CONS (QUOTE ((\INTERRUPTABLE T))) (for I in ARGS collect (LIST (QUOTE OR) I (LIST (QUOTE SHOULDNT) (KWOTE (LIST (QUOTE Assert-failure:) I] else (CONS (QUOTE *) ARGS)))) ) (* * The following are for diagnostic purposes.) (DEFINEQ (DISPLAYPAGE [LAMBDA (VolNum PageAddr) (* hts: "19-Sep-84 17:16") (DISPLAYWORDS (\LvGetPage VolNum PageAddr) 256]) (DISPLAYWORDS [LAMBDA (Start Number) (* hts: "19-Sep-84 17:15") (for I from 0 to (SUB1 Number) do (PRIN1 (\GETBASE Start I)) (PRIN1 " ") (if (ZEROP (IREMAINDER (ADD1 I) 7)) then (TERPRI))) (TERPRI]) (ShowIntervals [LAMBDA (vol) (* hts: "19-Sep-84 17:16") (bind (intervalCache ←(PROGN (\DFSVFMContextSet vol) (\DFSVFMGetInterval))) interval for level from 0 to 5 do (printout T level ":" T "key: ") (SETQ interval (ELT intervalCache level)) (DISPLAYWORDS (fetch (Interval key) of interval) (MESASIZE Key)) (printout T "volumePage: " (fetch (Interval volumePage) of interval) T) (printout T "nextKey: ") (DISPLAYWORDS (fetch (Interval nextKey) of interval) (MESASIZE Key]) (REL [LAMBDA (FILES) (* hts: "20-Sep-84 15:25") (* * Releases FILES from connected directory to lispcore>next) (for F in FILES do (COPYFILE F (PACKFILENAME (QUOTE HOST) (QUOTE ERIS) (QUOTE DIRECTORY) (QUOTE LISPCORE>SOURCES) (QUOTE NAME) F)) (COPYFILE (PACKFILENAME (QUOTE NAME) F (QUOTE EXTENSION) (QUOTE DCOM)) (PACKFILENAME (QUOTE HOST) (QUOTE ERIS) (QUOTE DIRECTORY) (QUOTE LISPCORE>SOURCES) (QUOTE NAME) F (QUOTE EXTENSION) (QUOTE DCOM))) (printout NIL "RELEASED " F T]) ) ) (DECLARE: (DECLARE: DOEVAL@COMPILE DONTCOPY (LOCALVARS) ) ) (/DECLAREDATATYPE (QUOTE PageGroup) (QUOTE (SWAPPEDFIXP SWAPPEDFIXP SWAPPEDFIXP))) (* * Public entry) (DEFINEQ (DFSCREATEDIRECTORY [LAMBDA (volName) (* hts: "11-Oct-84 13:42") (WITH.MONITOR \DFStopMonitor (\DFSEnsureDlion) (\DFSEnsureInitialized) (if (NOT (\DFSPhysicalVolumeOK T)) then (ERROR)) (PROG ((vol (\DFSGetLVPage volName))) (if (NULL vol) then (ERROR (CONCAT "Volume " volName " not on local disk"))) (if (LVEqual vol (\DFSCurrentVol)) then (ERROR "Can't make a lisp file directory on your vmem volume")) (UNINTERRUPTABLY (PROG [(oldDevice (\GETDEVICEFROMNAME (QUOTE DSK] (if (NOT (type? DLIONDISK oldDevice)) then (\REMOVEDEVICE oldDevice) (\DFSDeviceConflict) (\DFSCreateDevice))) (\DFSVFMInitMap vol) (\DFSMakeVolumeDirectory vol)) (RETURN volName]) (DFSPURGEDIRECTORY [LAMBDA (volName) (* hts: "24-Sep-84 17:49") (WITH.MONITOR \DFStopMonitor (\DFSEnsureDlion) (\DFSEnsureInitialized) (PROG ((vol (\DFSGetLVPage volName)) device) (if (NOT vol) then (ERROR volName " is not a local disk volume")) (UNINTERRUPTABLY (* * Mark volume as being a pilot volume) (\DFSVolumeType volName (QUOTE PILOT)) (* * Remove device and directory associated with volume) (if (GetDirectory vol) then (FORGETPAGES (GetDirectory vol)) (PutDirectory vol NIL)) (* * If device was DSK, replace it with a coredevice) (if (AND [type? DLIONDISK (SETQ device (\GETDEVICEFROMNAME (QUOTE DSK] (NOT (\DFSVolumeNameToNumber))) then (\REMOVEDEVICE device))) (RETURN (PACKFILENAME (QUOTE HOST) (QUOTE DSK) (QUOTE DIRECTORY) volName]) (VOLUMES [LAMBDA NIL (* hts: " 7-Sep-84 12:55") (\DFSEnsureDlion) (\DFSEnsureInitialized) (UNINTERRUPTABLY (for vol in (GetVols) collect (fetch (LogicalVolumeDescriptor LVlabel) of vol)))]) (VOLUMETYPE [LAMBDA (volumeName type) (* hts: "24-Sep-84 17:44") (OR (EQ type (QUOTE LISPFILE)) (EQ type (QUOTE PILOT)) (NULL type) (ERROR "type must be one of LISPFILE or PILOT or NIL")) (WITH.MONITOR \DFStopMonitor (\DFSEnsureDlion) (\DFSEnsureInitialized) (\DFSVolumeType volumeName type]) (\DFSVolumeType [LAMBDA (volumeName type) (* hts: "24-Sep-84 17:44") (PROG ((vol (\DFSGetLVPage volumeName)) oldType) (if (NOT vol) then (ERROR volumeName " is not a local disk volume")) (SETQ oldType (if (EQ (fetch (LogicalVolumeDescriptor type) of vol) DFSLispVolume) then (QUOTE LISPFILE) else (QUOTE PILOT))) (if type then (UNINTERRUPTABLY (replace (LogicalVolumeDescriptor type) of vol with (if (EQ type (QUOTE LISPFILE)) then DFSLispVolume else DFSPilotVolume)) (\LvPutPage vol 0 vol) (PROG [(markerPage (\LvGetPage vol (MarkerPageAddr vol] (replace (LogicalSubVolumeMarker type) of (fetch (SubVolumeMarkerPage logical) of markerPage) with DFSPilotVolume) (\LvPutPage vol (MarkerPageAddr vol) markerPage))) (\DFSDsplyVolumes)) (RETURN oldType]) ) (DEFINEQ (\DFSCurrentVolume [LAMBDA NIL (* hts: "13-Sep-84 18:12") (* * Returns as an atom the name of the volume which contains the currently running virtual memory) (UNINTERRUPTABLY (\DFSEnsureInitialized) (fetch (LogicalVolumeDescriptor LVlabel) of (\DFSCurrentVol)))]) (\DFSCurrentVol [LAMBDA NIL (* hts: "13-Sep-84 18:13") (* * Returns the logical volume page of the volume which contains the currently running virtual memory) (for vol in (GetVols) thereis (EQP (fetch (DiskFileID da) of (FMESAELT (fetch ( PhysicalVolumeDescriptor bootingInfo) of \PhysVolumePage) PVBootFiles hardMicrocode)) (fetch (DiskFileID da) of (FMESAELT (fetch ( LogicalVolumeDescriptor bootingInfo) of vol) LVBootFiles hardMicrocode]) (\DFSLispVolumeP [LAMBDA (vol) (* hts: "13-Sep-84 18:45") (* * Tells whether vol is a lisp file volume. Should really include some checks on the integrity of the directory, etc.) (EQ DFSLispVolume (fetch (LogicalVolumeDescriptor type) of vol]) (\DFSGetLVPage [LAMBDA (lvName) (* hts: "27-Jun-84 14:07") (UNINTERRUPTABLY (SETQ lvName (MKATOM (U-CASE lvName))) (for vol in (GetVols) thereis (EQ lvName (fetch (LogicalVolumeDescriptor LVlabel) of vol))))]) ) (* * Initialization routines) (DEFINEQ (\DFSDEVICEP [LAMBDA (deviceName) (* hts: "24-Sep-84 21:26") (* * Opens and returns the dlion local file device iff: deviceName is appropriate, the disk is ok, and there is a valid lisp file volume. If the deviceName is valid, HostNameP will return the device, creating it if it didn't previously exist.) (UNINTERRUPTABLY (SELECTQ (MACHINETYPE) (DANDELION (\DFSEnsureInitialized) (AND (\DFSPhysicalVolumeOK NIL) (\DFSVolumeNameToNumber) (\DFSHostNameP deviceName))) NIL))]) (\DFSEnsureDlion [LAMBDA NIL (* hts: " 7-Sep-84 12:55") (if (NEQ (MACHINETYPE) (QUOTE DANDELION)) then (ERROR "You can't run this function if you aren't on an 1108"]) (\DFSEnsureInitialized [LAMBDA NIL (* hts: " 5-Sep-84 17:25") (OR \DFSInitialized (\DFSInit]) (\DFSInit [LAMBDA NIL (* hts: " 1-Oct-84 14:27") (* * initialize physical volume page cache) (\PvTransferPage 0 \PhysVolumePage NIL) (* * initialize logical volume page cache;) (InitializeVols) (if (\DFSPhysicalVolumeOK T) then (* * Initialize volume file map and volume allocation map) (\DFSVAMInit) (\DFSVFMInit) (* * Note that this routine has been run) (SETQ \DFSInitialized T) (\DFSDsplyVolumes) else (SETQ \DFSInitialized]) (\DFSPhysicalVolumeOK [LAMBDA (printMessage) (* hts: "30-Sep-84 19:45") (* * Checks to see that the disk you are attempting to run on is partitioned in a way the file system can understand) (if (for vol in (GetVols) always (EQ 8 (fetch (LogicalVolumeDescriptor version) of vol))) then T else (if printMessage then (printout NIL "Local disk is not formatted as Klamath disk." T "You cannot use it." T)) NIL]) (\DFSCreateDevice [LAMBDA NIL (* hts: "21-Sep-84 20:52") (UNINTERRUPTABLY (PROG [(DEV (\MAKE.PMAP.DEVICE (create FDEV NODIRECTORIES ← T DEVICENAME ←(QUOTE DSK) CLOSEFILE ←(FUNCTION \DFSCloseFile) DELETEFILE ←(FUNCTION \DFSDeleteFile) TRUNCATEFILE ←(FUNCTION NILL) GETFILEINFO ←(FUNCTION \DFSGetFileInfo) GETFILENAME ←(FUNCTION \DFSGetFileName) OPENFILE ←(FUNCTION \DFSOpenFile) READPAGES ←(FUNCTION \DFSReadPages) SETFILEINFO ←(FUNCTION \DFSSetFileInfo) WRITEPAGES ←(FUNCTION \DFSWritePages) REOPENFILE ←(FUNCTION \DFSOpenFile) GENERATEFILES ←(FUNCTION \DFSGenerateFiles) EVENTFN ←(FUNCTION \DFSEventFn) DIRECTORYNAMEP ←(FUNCTION \DFSDirectoryNameP) HOSTNAMEP ←(FUNCTION \DFSHostNameP] (\DEFINEDEVICE (QUOTE DSK) DEV) (SETQ \DFSdevice DEV) (printout NIL "Opened local file system device {DSK}." T) (RETURN DEV)))]) (\DFSDeviceConflict [LAMBDA NIL (* hts: "20-Sep-84 14:42") (* * Resolves device name conflicts appropriately before creating DlionFS device) (if (AND (type? COREDEVICE (\GETDEVICEFROMNAME (QUOTE DSK))) (FILDIR (QUOTE {DSK}))) then (printout NIL "{DSK} is a coredevice which has files on it." T "Copying contents of {DSK} to {PSEUDO-DSK}." T) (COREDEVICE (QUOTE PSEUDO-DSK)) [for f in (FILDIR (QUOTE {DSK})) do (COPYFILE f (PACKFILENAME (QUOTE HOST) (QUOTE PSEUDO-DSK) (QUOTE DIRECTORY) (FILENAMEFIELD f (QUOTE DIRECTORY)) (QUOTE NAME) (FILENAMEFIELD f (QUOTE NAME] (printout NIL "Purging coredevice {DSK}." T]) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \DFSInitialized \DFSdevice \PhysVolumePage \DFStopMonitor) ) (RPAQ? \DFSInitialized NIL) (RPAQ? \DFSdevice NIL) (RPAQ? \DFStopMonitor (CREATE.MONITORLOCK (QUOTE topMonitor))) (ADDTOVAR \SYSTEMCACHEVARS \DFSInitialized) (DEFINEQ (\DFSAtLoad [LAMBDA NIL (* hts: "18-Sep-84 12:15") (OR (BOUNDP (QUOTE \PhysVolumePage)) (SETQ \PhysVolumePage (create PhysicalVolumeDescriptor))) (CreateVols) (CreateDirectories]) ) (\DFSAtLoad) (* * Device methods) (DEFINEQ (\DFSOpenFile [LAMBDA (FILE ACCESS RECOG OTHERINFO FDEV OLDSTREAM) (* hts: " 2-Oct-84 11:49") (* * Open a Model44 file. Gets the physical end of file and sets up ofd) (WITH.MONITOR \DFStopMonitor (PROG [(PAGESTIMATE (AND (NEQ ACCESS (QUOTE INPUT)) (for X in OTHERINFO when (EQ (CAR (LISTP X)) (QUOTE LENGTH)) do (RETURN (ADD1 (FOLDHI (CADR X) BYTESPERPAGE] (if (NOT (type? DLIONSTREAM FILE)) then (SETQ FILE (\DFSGetStreamForFile FILE RECOG ACCESS OLDSTREAM (NEQ ACCESS (QUOTE INPUT)) PAGESTIMATE OTHERINFO))) (if (NOT FILE) then (RETURN NIL) else (if (EQ ACCESS (QUOTE OUTPUT)) then (* File is EMPTY even if it is old) (replace EPAGE of FILE with (replace EOFFSET of FILE with 0))) (* For REOPENFILE op, don't change dates) (\DFSUpdateLeaderPage FILE (if (AND (NOT OLDSTREAM) (NOT (FMEMB (QUOTE DON'T.CHANGE.DATE) OTHERINFO))) then ACCESS else NIL)) (RETURN FILE]) (\DFSGetStreamForFile [LAMBDA (NAME RECOG ACCESS OLDSTREAM CREATEFLG PAGES OTHERINFO) (* hts: "30-Oct-84 14:21") (* Creates a STREAM for dsk file NAME, creating it if necessary when CREATEFLG is true.) (PROG ((DIROFD (\DFSFileNameToDirectory NAME)) FS fileID alreadyOpenStream) (if (NOT DIROFD) then (RETURN NIL)) (SETQ FS (\DFSFileSpec NAME RECOG DIROFD)) (RETURN (COND [(fetch FSDIRPTR of FS) (* * If the directory code found a pointer into the directory, then the file already exists; just open it up) (\DFSOpenOldFile FS (\DFSReadFileID (GetDirectory (fetch PARTNUM of (fetch UNAME of FS))) (fetch FSDIRPTR of FS] ((NULL (fetch VERSION of (fetch UNAME of FS))) NIL) ((IGREATERP (fetch VERSION of (fetch UNAME of FS)) MAX.SMALLP) (printout NIL "Version number limit is 65535 on 1108 File System" T) (DiskError "FILE SYSTEM RESOURCES EXCEEDED" FILE)) (CREATEFLG (\DFSCreateFile (fetch (DFSFileSpec UNAME) of FS) PAGES OTHERINFO]) (\DFSOpenOldFile [LAMBDA (file fileID) (* hts: "16-Sep-84 19:48") (* * Open an old (existing) file and return the resultant stream) (PROG ([vol (GetVol (fetch (UNAME PARTNUM) of (fetch (DFSFileSpec UNAME) of file] STREAM) (SETQ STREAM (create DLIONSTREAM FULLFILENAME ←(\DFSFullFileName (fetch UNAME of file)) FILEDESC ←(create FileDescriptor fileID ← fileID volumeID ←(fetch (LogicalVolumeDescriptor vID) of vol) location ←(QUOTE local) type ← 0) VOLUME ← vol DIRINFO ←(fetch FSDIRPTR of file) DEVICE ← \DFSdevice)) (* * Use leader page to look up and fill in remaining fields of stream (those having to do with the length of the file)) (replace (DLIONSTREAM LEADERPAGE) of STREAM with (\LvGetPage vol (\DFSFindPageAddr vol (fetch (DLIONSTREAM FILEDESC) of STREAM) 0))) (replace (FileDescriptor size) of (fetch (DLIONSTREAM FILEDESC) of STREAM) with (fetch AllocatedPages of (fetch (DLIONSTREAM LEADERPAGE) of STREAM))) (replace (DLIONSTREAM EPAGE) of STREAM with (fetch EofPage of (fetch (DLIONSTREAM LEADERPAGE) of STREAM))) (replace (DLIONSTREAM EOFFSET) of STREAM with (fetch EOffSet of (fetch (DLIONSTREAM LEADERPAGE) of STREAM))) (RETURN STREAM]) (\DFSGenFileID [LAMBDA (vol) (* edited: "18-Jul-84 14:33") (* * Generates and returns a new file ID and updates the ID count for the logical volume) (add (fetch (LogicalVolumeDescriptor lastIDAllocated) of vol) 1]) (\DFSCreateFile [LAMBDA (fileName pages info) (* hts: "10-Oct-84 12:57") (UNINTERRUPTABLY (PROG ((initialAlloc 20) (vol (GetVol (fetch (UNAME PARTNUM) of fileName))) stream) (SETQ stream (create DLIONSTREAM FULLFILENAME ←(\DFSFullFileName fileName) FILEDESC ←(create FileDescriptor fileID ←(\DFSGenFileID vol) volumeID ←(fetch (LogicalVolumeDescriptor vID) of vol) location ←(QUOTE local) type ← 0) VOLUME ← vol DEVICE ← \DFSdevice)) (* * Allocate pages for file; this will update size field of FileDescriptor) (\DFSNewPages vol (fetch (DLIONSTREAM FILEDESC) of stream) (create PageGroup filePage ← 0 volumePage ← 0 nextFilePage ← initialAlloc)) (* * Create leader page for the new file and put it and cache it) (replace (DLIONSTREAM LEADERPAGE) of stream with (\DFSMakeLeaderPage vol (fetch (DLIONSTREAM FILEDESC) of stream) fileName info)) (* * Enter the new file in the directory) (\DFSMakeDirEntry stream fileName (GetDirectory vol)) (RETURN stream)))]) (\DFSNewPages [LAMBDA (vol file group) (* hts: "17-Jun-84 13:00") (* Attempts to allocate needed pages for file. Returns a list of intervals allocated. Interval represented as dotted pair (startPage . #ofPages)) (PROG (currentGroup) (until (EQP (fetch (FileDescriptor size) of file) (fetch (PageGroup nextFilePage) of group)) do (SETQ currentGroup (create PageGroup filePage ←(fetch (FileDescriptor size) of file) volumePage ← 0 nextFilePage ←(fetch (PageGroup nextFilePage) of group))) (\DFSVAMAllocPageGroup vol file currentGroup) (* Allocate as many pages of the desired group as possible) (\DFSVFMInsertPageGroup vol file currentGroup) (* Stick the newly allocated group into the volume file map BTree) (replace (FileDescriptor size) of file with (fetch (PageGroup nextFilePage) of currentGroup))) (\DFSDsplyVolumes]) (\DFSMakeLeaderPage [LAMBDA (vol file uname Info) (* hts: " 6-Sep-84 18:38") (* * Make, put, and return leader page for file) (PROG ([CurrentTime (IDATE (CADR (FASSOC (QUOTE CREATIONDATE) Info] (Author (OR (CADR (FASSOC (QUOTE AUTHOR) Info)) (USERNAME))) (LeaderPage (create LeaderPage))) (replace (LeaderPage TimeCreate) of LeaderPage with CurrentTime) (replace (LeaderPage TimeWrite) of LeaderPage with CurrentTime) (replace (LeaderPage FileID) of LeaderPage with (fetch (FileDescriptor fileID) of file)) (replace (LeaderPage AllocatedPages) of LeaderPage with (fetch (FileDescriptor size) of file)) (replace (LeaderPage EofPage) of LeaderPage with 0) (replace (LeaderPage EOffSet) of LeaderPage with 0) (replace (LeaderPage fileName) of LeaderPage with (\DFSFileName uname)) (replace (LeaderPage author) of LeaderPage with Author) (\LvPutPage vol (\DFSFindPageAddr vol file 0) LeaderPage) (RETURN LeaderPage]) (\DFSUpdateLeaderPage [LAMBDA (stream access) (* hts: " 3-Jul-84 11:29") (UNINTERRUPTABLY (PROG ((leaderPage (fetch (DLIONSTREAM LEADERPAGE) of stream)) (time (DAYTIME))) (* * Update end of file info) (replace (LeaderPage EofPage) of leaderPage with (fetch (STREAM EPAGE) of stream)) (replace (LeaderPage EOffSet) of leaderPage with (fetch (STREAM EOFFSET) of stream)) (replace (LeaderPage AllocatedPages) of leaderPage with (fetch (FileDescriptor size) of (fetch (DLIONSTREAM FILEDESC) of stream))) (* * Update info saying how many pages have been allocated to the file) (replace (LeaderPage AllocatedPages) of leaderPage with (fetch (FileDescriptor size) of (fetch (DLIONSTREAM FILEDESC) of stream))) (* * Update access times) (SELECTQ access ((OUTPUT BOTH APPEND) (replace (LeaderPage TimeWrite) of leaderPage with time)) NIL) (SELECTQ access ((INPUT BOTH) (replace (LeaderPage TimeRead) of leaderPage with time)) NIL) (* * and write out the refreshed leader page) (\DFSWriteLeaderPage stream)))]) (\DFSWriteLeaderPage [LAMBDA (stream) (* hts: "14-Sep-84 10:47") (PROG ((vol (fetch (DLIONSTREAM VOLUME) of stream))) (\LvPutPage vol (\DFSFindPageAddr vol (fetch (DLIONSTREAM FILEDESC) of stream) 0) (fetch (DLIONSTREAM LEADERPAGE) of stream]) (\DFSFindPageAddr [LAMBDA (vol file filePage noCheck) (* hts: "20-May-84 21:39") (PROG ((result (\DFSVFMGetPageGroup vol file filePage))) (* GetPageGroup returns a dotted pair whose CAR is NIL iff the fileID was not found, and whose CDR contains a PageGroup indicating the desired pages) (if (NULL (CAR result)) then (SHOULDNT (QUOTE keyNotFound))) [if (ZEROP (fetch (PageGroup volumePage) of (CDR result))) then (if noCheck then (RETURN NIL) else (SHOULDNT (QUOTE keyNotFound] (* Gives a zero volume page iff the fileID is found, but the page specified isn't. noCheck is T only when called to see if the file should be extended.) (RETURN (IPLUS (fetch (PageGroup volumePage) of (CDR result)) filePage (IMINUS (fetch (PageGroup filePage) of (CDR result]) ) (DEFINEQ (\DFSCloseFile [LAMBDA (STREAM) (* hts: "24-Sep-84 21:05") (* Update EOF in leader page) (WITH.MONITOR \DFStopMonitor (\CLEARMAP STREAM) (if (NEQ (fetch ACCESS of STREAM) (QUOTE INPUT)) then (UNINTERRUPTABLY (\DFSTrimHelper (fetch (DLIONSTREAM VOLUME) of STREAM) (fetch (DLIONSTREAM FILEDESC) of STREAM) (IPLUS (fetch EPAGE of STREAM) (if (ZEROP (fetch EOFFSET of STREAM)) then 1 else 2))) (\DFSUpdateLeaderPage STREAM))) STREAM]) (\DFSTrimHelper [LAMBDA (vol filePtr targetFileSize) (* hts: " 2-Jul-84 21:46") (* * Shortens or deletes a file by taking entries out of the BTree and out of the allocation map Removes the pages of the file between targetFileSize & actualFileSize) (if (NOT (EQP targetFileSize (fetch (FileDescriptor size) of filePtr))) then (bind (group ←(create PageGroup filePage ← targetFileSize volumePage ← nullVolumePage nextFilePage ←(fetch (FileDescriptor size) of filePtr))) until (PROGN (\DFSVFMDeletePageGroup vol filePtr group) (\DFSVAMFreePageGroup vol filePtr group) (replace (FileDescriptor size) of filePtr with (fetch (PageGroup filePage) of group)) (if (ZEROP (fetch (PageGroup filePage) of group)) then (replace (PageGroup nextFilePage) of group with 0) (\DFSVFMDeletePageGroup vol filePtr group) (\DFSVAMFreePageGroup vol filePtr group) T else (EQP (fetch (PageGroup filePage) of group) targetFileSize))) do (replace (PageGroup nextFilePage) of group with (fetch (PageGroup filePage) of group)) (replace (PageGroup filePage) of group with targetFileSize)) (\DFSDsplyVolumes]) ) (DEFINEQ (\DFSDeleteFile [LAMBDA (fileName dev) (* hts: "24-Sep-84 16:57") (WITH.MONITOR \DFStopMonitor (PROG ((stream (\DFSGetStreamForFile fileName (QUOTE OLDEST) (QUOTE BOTH) NIL))) (if (OR (NOT stream) (bind (NAME ←(fetch FULLFILENAME of stream)) thereis stream in \OPENFILES suchthat (EQ (fetch FULLFILENAME of stream) NAME))) then (RETURN)) (UNINTERRUPTABLY (\DFSRemoveDirEntry stream (GetDirectory (fetch (DLIONSTREAM VOLUME) of stream))) (* * Take the entire file out of the BTree and out of the allocation map) (\DFSTrimHelper (fetch (DLIONSTREAM VOLUME) of stream) (fetch (DLIONSTREAM FILEDESC) of stream) 0)) (RETURN (fetch (STREAM FULLFILENAME) of stream]) ) (DEFINEQ (\DFSReadPages [LAMBDA (stream firstPage buffers) (* hts: "24-Sep-84 17:11") (* add1 is because dlionfs enumeration of file pages starts with the leader page and stream enumeration starts with the first real page of the file) (WITH.MONITOR \DFStopMonitor (for buffer inside buffers as page from (ADD1 firstPage) do (\DFSReadOnePage stream page buffer) (BLOCK]) (\DFSReadOnePage [LAMBDA (stream page buffer) (* hts: "24-Sep-84 22:28") (PROG ((vol (fetch (DLIONSTREAM VOLUME) of stream))) (* (Assert (OR (ILEQ page (fetch EPAGE of stream)) (AND (IGREATERP (fetch EOFFSET of stream) 0) (EQP page (ADD1 (fetch EPAGE of stream))))))) (if [OR (ILEQ page (fetch EPAGE of stream)) (AND (IGREATERP (fetch EOFFSET of stream) 0) (EQP page (ADD1 (fetch EPAGE of stream] then (\LvGetPage vol (\DFSFindPageAddr vol (fetch (DLIONSTREAM FILEDESC) of stream) page) buffer]) ) (DEFINEQ (\DFSWritePages [LAMBDA (stream firstPage buffers) (* hts: "24-Sep-84 17:12") (* add1 is because dlionfs enumeration of file pages starts with the leader page and stream enumeration starts with the first real page of the file) (WITH.MONITOR \DFStopMonitor (for buffer inside buffers as page from (ADD1 firstPage) do (\DFSWriteOnePage stream page buffer) (BLOCK]) (\DFSWriteOnePage [LAMBDA (stream page buffer) (* hts: "24-Sep-84 17:12") (PROG ((vol (fetch (DLIONSTREAM VOLUME) of stream)) volumePage) (SETQ volumePage (\DFSFindPageAddr vol (fetch (DLIONSTREAM FILEDESC) of stream) page (QUOTE noError))) (if (NULL volumePage) then (* if this page is beyond the last allocated page of the file, extend the file another chunk) (\DFSExtendFile stream page) (SETQ volumePage (\DFSFindPageAddr vol (fetch (DLIONSTREAM FILEDESC) of stream) page))) (\LvPutPage vol volumePage buffer]) (\DFSExtendFile [LAMBDA (stream page) (* hts: "10-Oct-84 12:58") (PROG ((vol (fetch (DLIONSTREAM VOLUME) of stream)) (fileDesc (fetch (DLIONSTREAM FILEDESC) of stream))) (UNINTERRUPTABLY [\DFSNewPages vol fileDesc (create PageGroup filePage ←(fetch (FileDescriptor size) of fileDesc) volumePage ← 0 nextFilePage ←(MAX page (IPLUS (fetch (FileDescriptor size) of fileDesc) 20] (\DFSUpdateLeaderPage stream))]) ) (DEFINEQ (\DFSGetFileInfo [LAMBDA (stream attribute device) (* hts: "24-Sep-84 17:15") (* Get the value of the attribute for a model44 file. If stream is a filename, then the file is not open.) (WITH.MONITOR \DFStopMonitor (if (OR (type? STREAM stream) (SETQ stream (\DFSGetStreamForFile stream (QUOTE OLD) (QUOTE INPUT) NIL))) then (PROG ((infoPage (fetch (DLIONSTREAM LEADERPAGE) of stream))) (RETURN (SELECTQ attribute (LENGTH (\UPDATEOF stream) (IPLUS (ITIMES (fetch (STREAM EPAGE) of stream) BYTESPERPAGE) (fetch (STREAM EOFFSET) of stream))) (WRITEDATE (GDATE (fetch (LeaderPage TimeWrite) of infoPage))) (READDATE (GDATE (fetch (LeaderPage TimeRead) of infoPage))) (CREATIONDATE (GDATE (fetch (LeaderPage TimeCreate) of infoPage))) (IWRITEDATE (fetch (LeaderPage TimeWrite) of infoPage)) (IREADDATE (fetch (LeaderPage TimeRead) of infoPage)) (ICREATIONDATE (fetch (LeaderPage TimeCreate) of infoPage)) (AUTHOR (fetch (LeaderPage author) of infoPage)) NIL]) ) (DEFINEQ (\DFSSetFileInfo [LAMBDA (stream attribute newValue device) (* hts: "24-Sep-84 17:16") (WITH.MONITOR \DFStopMonitor (if (OR (type? STREAM stream) (SETQ stream (\DFSGetStreamForFile stream (QUOTE OLD) (QUOTE INPUT) NIL))) then (UNINTERRUPTABLY (SELECTQ attribute (CREATIONDATE (replace (LeaderPage TimeCreate) of (fetch (DLIONSTREAM LEADERPAGE) of stream) with (IDATE newValue)) (\DFSWriteLeaderPage stream) newValue) (ICREATIONDATE (replace (LeaderPage TimeCreate) of (fetch (DLIONSTREAM LEADERPAGE) of stream) with newValue) (\DFSWriteLeaderPage stream) newValue) (AUTHOR (replace (LeaderPage author) of (fetch (DLIONSTREAM LEADERPAGE) of stream) with newValue) (\DFSWriteLeaderPage stream) newValue) NIL)) else NIL]) ) (DEFINEQ (\DFSGetFileName [LAMBDA (FileName Recog Dev) (* hts: "24-Sep-84 17:23") (WITH.MONITOR \DFStopMonitor (PROG ((directory (\DFSFileNameToDirectory FileName))) (RETURN (if directory then (\DFSFullFileName (fetch UNAME of (\DFSFileSpec FileName Recog directory))) else NIL]) ) (DEFINEQ (\DFSEventFn [LAMBDA (Dev Event) (* hts: "24-Sep-84 17:28") (* * Determines dliondisk fdev behaviour across major system events. Must make the file system wake up properly on different machines, or even on the same machine with a different disk partitioning.) (WITH.MONITOR \DFStopMonitor (SELECTQ Event [(AFTERLOGOUT AFTERSYSOUT AFTERMAKESYS AFTERSAVEVM) (* * Get rid of the directories associated with this device; they will be reopened as necessary) [for vol in (GetVols) do (if (GetDirectory vol) then (UNINTERRUPTABLY (FORGETPAGES (GetDirectory vol)) (PutDirectory vol NIL))] (* * Chop out the device to force \DFSDEVICEP to be run) (UNINTERRUPTABLY (SETQ \DFSdevice) (\REMOVEDEVICE Dev)) (* * If on an alien machine, make sure you can't reopen files. \DFSDEVICEP will force reinitialization.) (if (NOT (\DFSDEVICEP (QUOTE DSK))) then (replace (FDEV REOPENFILE) of Dev with (FUNCTION NILL] (BEFORELOGOUT (* * BVM claims you should flush open streams associated with this device only before logout) (\FLUSH.OPEN.STREAMS Dev)) NIL]) ) (DEFINEQ (\DFSFreeDiskPages [LAMBDA (volName recompute) (* hts: "24-Sep-84 17:30") (WITH.MONITOR \DFStopMonitor (PROG ((vol (\DFSGetLVPage volName))) (if (NULL vol) then (ERROR (CONCAT "Volume " volName " not on local disk") )) (if recompute then (\DFSVAMRecomputeFreePageCount vol) (\DFSDsplyVolumes)) (RETURN (fetch (LogicalVolumeDescriptor freePageCount) of vol]) ) (DEFINEQ (\DFSDirectoryNameP [LAMBDA (DirSpec) (* hts: "24-Sep-84 21:40") (* * Implements the DIRECTORYNAMEP method for the dlionfs. If DirSpec is a reasonable directory specification, returns the canonical form of that directory; otherwise returns NIL) (WITH.MONITOR \DFStopMonitor (PROG ((directoryInfo (\DFSFirstDirectory DirSpec)) volNum directory subdirectory) (RETURN (if (SETQ volNum (\DFSVolumeNameToNumber (CAR directoryInfo))) then [SETQ directory (PACKFILENAME (QUOTE HOST) (QUOTE DSK) (QUOTE DIRECTORY) (fetch (LogicalVolumeDescriptor LVlabel) of (GetVol volNum] (if (SETQ subdirectory (SUBSTRING DirSpec (CADDR directoryInfo) (LASTCHPOS (CHARCODE >) DirSpec 1))) then (PACK* directory subdirectory) else (MKATOM directory)) else NIL]) ) (DEFINEQ (\DFSHostNameP [LAMBDA (name) (* hts: "24-Sep-84 21:36") (* * Implements the HOSTNAMEP method for the dlionfs. If the name given it is one of DSK, the etherhostname, or the physical volume name, returns the DSK device; otherwise returns NIL.) (* * Also called by \DFSDEVICEP to determine whether the name given it is a reasonable one. For this purpose, it will actually create the device if it does not already exist) (WITH.MONITOR \DFStopMonitor (\DFSEnsureInitialized) (PROG [(deviceName (MKATOM (U-CASE name] (RETURN (if (OR (EQ deviceName (ETHERHOSTNAME)) (EQ deviceName (fetch (PhysicalVolumeDescriptor PVlabel) of \PhysVolumePage)) (EQ deviceName (QUOTE DSK))) then (OR \DFSdevice (\DFSCreateDevice)) else NIL]) ) (* * Routines for mapping file names onto volumes and directories) (DEFINEQ (\DFSFileNameToDirectory [LAMBDA (fileName) (* hts: "14-Sep-84 16:52") (* * Finds the directory stream corresponding to fileName (if there is such a directory)) (PROG [(volumeNumber (\DFSVolumeNameToNumber (CAR (\DFSFirstDirectory fileName] (RETURN (if volumeNumber then (OR (GetDirectory volumeNumber) (\DFSOpenDirectory (GetVol volumeNumber))) else NIL]) (\DFSVolumeNameToNumber [LAMBDA (volumeName) (* hts: "13-Sep-84 18:59") (* * Given a name, if that is the name of a lisp file volume, returns the number of that volume; else returns NIL. Not given a name, it tries to find a default lisp file volume and return its number. Default volume is the next lisp file volume after the volume containing the currently-running virtual memory.) (if volumeName then (PROG ((vol (\DFSGetLVPage volumeName))) (RETURN (if (AND vol (\DFSLispVolumeP vol)) then (VolumeNumber vol) else NIL))) else (PROG ((volumes (GetVols)) (currentVol (\DFSCurrentVol)) nextVolumes defaultVol) [SETQ nextVolumes (for vols on volumes do (if (EQ currentVol (CAR vols)) then (RETURN (APPEND (CDR vols) volumes] (SETQ defaultVol (for vol in nextVolumes thereis (\DFSLispVolumeP vol))) (RETURN (if defaultVol then (VolumeNumber defaultVol) else NIL]) (\DFSFirstDirectory [LAMBDA (name) (* hts: "13-Sep-84 21:58") (PROG (endHost restDirectory) (SETQ endHost (STRPOS "}" name)) (if (NULL endHost) then (SETQ endHost 0)) (SETQ restDirectory (STRPOS ">" name endHost)) (SETQ restDirectory (ADD1 (if (NULL restDirectory) then endHost else restDirectory))) (RETURN (LIST [MKATOM (U-CASE (SUBSTRING name (IPLUS endHost 2) (IDIFFERENCE restDirectory 2] endHost restDirectory]) ) (* * These functions transfer pages to and from the disk) (DEFINEQ (\PvTransferPage [LAMBDA (absoluteDiskAddress BUFFER WRITEFLG) (* hts: "24-Sep-84 16:45") (* * If WRITEFLG then writes BUFFER onto disk page absoluteDiskAddress; otherwise reads disk page absoluteDiskAddress onto BUFFER) [Assert (FIXP absoluteDiskAddress) (OR (EQ absoluteDiskAddress 0) (AND (IGREATERP absoluteDiskAddress 0) (ILEQ absoluteDiskAddress (PROG [(volNum (SUB1 (fetch (PhysicalVolumeDescriptor subVolumeCount) of \PhysVolumePage] (RETURN (IPLUS (LvBasePageAddr volNum) (MarkerPageAddr volNum] (Assert (type? Page BUFFER)) (WITH.MONITOR \DFSioMonitor (UNINTERRUPTABLY (SwapIn&Dirty BUFFER) (* * \DFSWriteFlg is passed globally since \MISCAPPLY* will take only 2 args. Must be exactly T or NIL, or it might invoke label reading/writing) (SETQ \DFSWriteFlg (if WRITEFLG then T else NIL)) (* * Call the page reading/writing routine in a special stack environment which will not page fault on frame extension) (\MISCAPPLY* (FUNCTION \PvTransferPageNoSwap) absoluteDiskAddress BUFFER))]) (\PvTransferPageNoSwap [LAMBDA (absoluteDiskAddress buffer) (* hts: " 9-Jul-84 17:52") (* Calls \DL.XFERDISK in a special stack environment that is guaranteed not to page fault. \DFSWriteFlg is passed as a global because \MISCAPPLY* allows only two args to be passed.) (\DL.TRANSFERPAGE absoluteDiskAddress buffer \DFSWriteFlg]) (\LvGetPage [LAMBDA (vol pageAddr buffer) (* hts: " 6-Sep-84 21:02") (* Reads a page from the disk and puts the result in Buffer. The page read is the PageAddr'th page of the VolNum'th logical volume.) (if (type? LogicalVolumeDescriptor vol) then (SETQ vol (VolumeNumber vol))) [Assert (FIXP vol) (IGEQ vol 0) (ILEQ vol (SUB1 (fetch (PhysicalVolumeDescriptor subVolumeCount) of \PhysVolumePage] (Assert (FIXP pageAddr) (IGEQ pageAddr 0) (ILEQ pageAddr (MarkerPageAddr vol))) (* * If buffer does not exist, create a new one.) (if (NULL buffer) then (SETQ buffer (create Page))) (Assert (type? Page buffer)) (* * Read the page off the disk) (\PvTransferPage (IPLUS (LvBasePageAddr vol) pageAddr) buffer) buffer]) (\LvPutPage [LAMBDA (vol pageAddr buffer) (* hts: " 6-Sep-84 21:02") (* Writes the contents of PagePtr onto the disk at the PageAddr'th page of the VolNum'th logical volume.) (if (type? LogicalVolumeDescriptor vol) then (SETQ vol (VolumeNumber vol))) (Assert (FIXP vol)) (Assert (FIXP pageAddr) (IGEQ pageAddr 0) (ILEQ pageAddr (MarkerPageAddr vol))) (Assert (type? Page buffer)) (\PvTransferPage (IPLUS (LvBasePageAddr vol) pageAddr) buffer T) NIL]) ) (DECLARE: DONTEVAL@LOAD (\LOCKFN (QUOTE \PvTransferPage)) (\LOCKFN (QUOTE \PvTransferPageNoSwap)) (\LOCKVAR (QUOTE \DFSWriteFlg)) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \DFSWriteFlg \DFSioMonitor) ) (RPAQ? \DFSioMonitor (CREATE.MONITORLOCK (QUOTE ioMonitor))) (* * Display stuff) (DEFINEQ (VOLUMEDISPLAY [LAMBDA (newState) (* mjs "10-Aug-84 11:00") (* If newState = OFF, turns volume display window off; if ON, turns it on; if anything else, doesn't do anything. Returns old state (oneof {ON, OFF})) (SELECTQ (MACHINETYPE) [DANDELION (UNINTERRUPTABLY (\DFSEnsureInitialized) (PROG [(oldState (if (WINDOWP \DFSDISPLAY) then (QUOTE ON) else (QUOTE OFF] (SELECTQ newState (ON (if (WINDOWP \DFSDISPLAY) then (CLOSEW \DFSDISPLAY)) (SETQ \DFSDISPLAY T) (\DFSDsplyVolumes)) (OFF (if (WINDOWP \DFSDISPLAY) then (CLOSEW \DFSDISPLAY))) NIL) (RETURN oldState)))] NIL]) (\DFSDsplyVolumes [LAMBDA NIL (* mjs "10-Aug-84 11:15") (if \DFSDISPLAY then [if (NOT (WINDOWP \DFSDISPLAY)) then (SETQ \DFSDISPLAY (CREATEW (if (AND (BOUNDP (QUOTE \DFSDsplyVolumes.REGION)) (type? REGION \DFSDsplyVolumes.REGION)) then \DFSDsplyVolumes.REGION else (create REGION WIDTH ← 290 HEIGHT ←(IPLUS 45 (ITIMES 15 (fetch ( PhysicalVolumeDescriptor subVolumeCount) of \PhysVolumePage))) LEFT ← 100 BOTTOM ← 50)) "1108 InterLisp File System")) [WINDOWPROP \DFSDISPLAY (QUOTE CLOSEFN) (FUNCTION (LAMBDA (W) (SETQ \DFSDISPLAY NIL] (WINDOWPROP \DFSDISPLAY (QUOTE RESHAPEFN) (FUNCTION RESHAPEBYREPAINTFN)) (WINDOWPROP \DFSDISPLAY (QUOTE REPAINTFN) (FUNCTION \DFSDsplyVolumes.REPAINTFN)) (WINDOWPROP \DFSDISPLAY (QUOTE RESHAPEFN) (FUNCTION (LAMBDA (W) (CLEARW \DFSDISPLAY) (REDISPLAYW \DFSDISPLAY] (CLEARW \DFSDISPLAY) (REDISPLAYW \DFSDISPLAY]) (\DFSDsplyVolumes.REPAINTFN [LAMBDA (W REG) (* hts: "16-Sep-84 16:19") (UNINTERRUPTABLY (CLEARW W) (DSPXPOSITION 0 W) (DSPYPOSITION (IPLUS (fetch (REGION TOP) of REG) (DSPLINEFEED NIL W)) W) (printout W .FONT \DFSfixedFont "Physical Volume: " .FONT \DFSfixedBold (fetch ( PhysicalVolumeDescriptor PVlabel) of \PhysVolumePage) .FONT \DFSfixedFont T "Logical Volumes:" T) (for vol in (GetVols) do (printout W .FONT \DFSfixedFont (if (EQ (fetch ( LogicalVolumeDescriptor type) of vol) DFSLispVolume) then "* " else " ") (VolumeNumber vol) " " .FONT \DFSfixedBold (fetch (LogicalVolumeDescriptor LVlabel) of vol) " " .FONT \DFSfixedFont .FR 18 (fetch ( LogicalVolumeDescriptor volumeSize) of vol) " Pages" .FR 31 (fetch (LogicalVolumeDescriptor freePageCount) of vol) " Free" T)))]) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS \DFSDISPLAY \DFSfixedFont \DFSfixedBold) ) (RPAQ? \DFSfixedFont (FONTCREATE (QUOTE GACHA) 10 (QUOTE MRR))) (RPAQ? \DFSfixedBold (FONTCREATE (QUOTE GACHA) 10 (QUOTE BRR))) (RPAQ? \DFSDISPLAY NIL) (* * Load other file system modules) (FILESLOAD VOLUMEDIRECTORY VOLUMEFILEMAP VOLUMEALLOCATIONMAP) (PUTPROPS DLIONFS COPYRIGHT ("Xerox Corporation" 1983 1984)) (DECLARE: DONTCOPY (FILEMAP (NIL (20265 22213 (DISPLAYPAGE 20275 . 20448) (DISPLAYWORDS 20450 . 20787) (ShowIntervals 20789 . 21445) (REL 21447 . 22211)) (22390 26302 (DFSCREATEDIRECTORY 22400 . 23385) (DFSPURGEDIRECTORY 23387 . 24481) (VOLUMES 24483 . 24777) (VOLUMETYPE 24779 . 25173) (\DFSVolumeType 25175 . 26300)) ( 26303 27949 (\DFSCurrentVolume 26313 . 26679) (\DFSCurrentVol 26681 . 27284) (\DFSLispVolumeP 27286 . 27625) (\DFSGetLVPage 27627 . 27947)) (27986 32413 (\DFSDEVICEP 27996 . 28613) (\DFSEnsureDlion 28615 . 28873) (\DFSEnsureInitialized 28875 . 29037) (\DFSInit 29039 . 29678) (\DFSPhysicalVolumeOK 29680 . 30248) (\DFSCreateDevice 30250 . 31453) (\DFSDeviceConflict 31455 . 32411)) (32695 32976 ( \DFSAtLoad 32705 . 32974)) (33017 44743 (\DFSOpenFile 33027 . 34468) (\DFSGetStreamForFile 34470 . 35863) (\DFSOpenOldFile 35865 . 37580) (\DFSGenFileID 37582 . 37886) (\DFSCreateFile 37888 . 39242) ( \DFSNewPages 39244 . 40569) (\DFSMakeLeaderPage 40571 . 41884) (\DFSUpdateLeaderPage 41886 . 43350) ( \DFSWriteLeaderPage 43352 . 43714) (\DFSFindPageAddr 43716 . 44741)) (44744 46979 (\DFSCloseFile 44754 . 45508) (\DFSTrimHelper 45510 . 46977)) (46980 48050 (\DFSDeleteFile 46990 . 48048)) (48051 49244 ( \DFSReadPages 48061 . 48535) (\DFSReadOnePage 48537 . 49242)) (49245 51115 (\DFSWritePages 49255 . 49731) (\DFSWriteOnePage 49733 . 50505) (\DFSExtendFile 50507 . 51113)) (51116 52601 (\DFSGetFileInfo 51126 . 52599)) (52602 53837 (\DFSSetFileInfo 52612 . 53835)) (53838 54286 (\DFSGetFileName 53848 . 54284)) (54287 55780 (\DFSEventFn 54297 . 55778)) (55781 56327 (\DFSFreeDiskPages 55791 . 56325)) ( 56328 57431 (\DFSDirectoryNameP 56338 . 57429)) (57432 58388 (\DFSHostNameP 57442 . 58386)) (58462 60819 (\DFSFileNameToDirectory 58472 . 58973) (\DFSVolumeNameToNumber 58975 . 60168) ( \DFSFirstDirectory 60170 . 60817)) (60884 64232 (\PvTransferPage 60894 . 62212) (\PvTransferPageNoSwap 62214 . 62606) (\LvGetPage 62608 . 63564) (\LvPutPage 63566 . 64230)) (64535 67792 (VOLUMEDISPLAY 64545 . 65438) (\DFSDsplyVolumes 65440 . 66683) (\DFSDsplyVolumes.REPAINTFN 66685 . 67790))))) STOP