DiskFindHole




The procedure DiskFindHole, in DiskFindHole.br, can be used to locate a
"hole" of available space in the disk bit table.  This  procedure works
with any type of disk object (BFS or TFS).  The call:

    virtualDA = DiskFindHole(disk, nPages)

will attempt to locate a contiguous hole nPages long.  If  it succeeds,
it returns the virtual disk address  of the first page of the  hole; if
it fails, it returns eofDA (defined in Disks.d).

The call:

    virtualDA = DiskFindHole(disk, nPages, lv holeSize)

will  operate as  described above  if a  hole of  size  nPages actually
exists, and  additionally will store  nPages in holeSize.   However, if
there is no hole sufficiently  large, it will locate the  largest hole,
store the actual size of that hole in holeSize, and return  the virtual
disk address of  the first page  of the hole.   (In this type  of call,
eofDA will be returned only if the disk is entirely full.)

In order to create a  contiguous file, it is first necessary  to create
the minimal file with a leader page at the given disk address, and then
to  extend the  file to  fill the  hole.  The  first step  is  begun by
calling:

    ReleaseDiskPage(disk, AssignDiskPage(disk, virtualDA-1))

where virtualDA is the desired disk address (i.e., the  result returned
by DiskFindHole).  This operation will control the selection of  a disk
address for the next free-choice allocation.  The file is  then created
by means such as:

    let s = OpenFile("Contiguous.file", ksTypeWriteOnly, 0, verNew,
       0, 0, 0, 0, 0, disk)
    PositionPage(s, nPages-1)

Once the file is created, it  is wise to extend it to its  final length
immediately, else  other disk  allocations might  encroach on  the hole
that was located.

Note  that  the  correctness of  the  result  returned  by DiskFindHole
depends  on  the  accuracy  of  the  disk  bit  table,  which, strictly
speaking,  is only  a hint.   Applications that  require a  file  to be
contiguous must check explicitly after creating it.  For example:

    let cfa = vec lCFA
    FileLength(s)
    GetCompleteFa(s, cfa)
    unless cfa>>CFA.fp.leaderVirtualDA eq virtualDA &
     cfa>>CFA.fa.da eq virtualDA+nPages-1 do
       [ ... file is not contiguous ... ]

                             ------------
                   Copyright Xerox Corporation 1982