// IFSExtend.bcpl -- code for extending an Interim File System
// Copyright Xerox Corporation 1979, 1981

// Last modified November 19, 1981  9:24 AM by Taft

get "Ifs.decl"
get "IfsFiles.decl"

external
[
// Outgoing procedures
ExtendIFS

// Incoming procedures
ExtendStackCall; Lock; Unlock
TFSDiskModel; SysAllocate; SysFree
WriteBlock; ReadBlock; Closes
OpenTFSDisk; CreateIFSDisk
CreateSystemEntries; OpenSystemFile

// Incoming statics
driveTab; openLock
]

//---------------------------------------------------------------------------
let ExtendIFS(ifs, drive) = ExtendStackCall(3000, DoExtend, ifs, drive)
//---------------------------------------------------------------------------
// Extends a running IFS by adding a new drive to it.
// Returns zero if successful and an error code if unsuccessful.

//---------------------------------------------------------------------------
and DoExtend(ifs, drive) = valof
//---------------------------------------------------------------------------
[
let ec = ExtendOneDisk(ifs, drive)
if ec eq 0 & TFSDiskModel(ifs>>IFS.lpdt↑(ifs>>IFS.numUnits-1)) eq 300 then
   ec = ExtendOneDisk(ifs, #400+drive)  // Put second file system on T-300
resultis ec
]

//---------------------------------------------------------------------------
and ExtendOneDisk(ifs, drive) = valof
//---------------------------------------------------------------------------
[
// Get a copy of the home block for the existing ifs
let name = "IFS.Home"
let s = OpenSystemFile(ifs>>IFS.lpdt↑0, name)
let home = SysAllocate(lenHome)
ReadBlock(s, home, lenHome)
Closes(s)

// Update to account for new unit
let newUnit = home>>Home.numUnits
home>>Home.numUnits = newUnit+1

// Create virgin file system on new drive
let ec = CreateIFSDisk(newUnit, drive, home)
if ec eq 0 then
   [
   Lock(openLock, true)

   // Update the home blocks of all existing units
   for i = 0 to newUnit-1 do
      [
      s = OpenSystemFile(ifs>>IFS.lpdt↑i, name)
      home>>Home.thisUnit = i
      WriteBlock(s, home, lenHome)
      Closes(s)
      ]

   // Insert the new disk into the running ifs
   ifs>>IFS.lpdt↑newUnit = OpenTFSDisk(drive&#377, drive rshift 8)
   driveTab>>DriveTab↑(drive&#377).ifs = ifs

   // Make IFS directory entries for system files on new disk
   CreateSystemEntries(ifs, newUnit)
   ifs>>IFS.numUnits = newUnit+1
   Unlock(openLock)
   ]

SysFree(home)
resultis ec
]