Outline thoughts on buffering

FSw holds file buffers, and operates some appropriate strategy.
  - files are of two kinds:
     - those having a direct underlying representation - in which case the
        buffers are read/written directly by FSw to the HFS, after having
        determined their location by "readcontig" calls
     - those having no such direct representation - in which case the buffers
        are read/written by FSw calling the underlying IFS as necessary
  - there's an email on buffer strategy that looks interesting - FIFO for
     blocks within a file (sequential access), LIFO for files (LRU) - needs
     further study

  Buffers may contain:
    - data which has been written by the client, but not yet written to the
      device (modified)
    - no data - awaiting a read ahead to complete
    - data awaiting a write behind to complete
    - data which has been read by the client (and so the buffer could be
       re-used)
    - data which has been written to the disc (and so the buffer could be
       re-used)

Each IFS will maintain its own directory entry cache.

For NC, this will be in the form of directory blocks: that is, each buffer
can contain exactly one directory block. Associated with each buffer is:
   - directory name (full path name, eg dir1.dir2)
   - buffer address
   - object id (disc address)
   - "time" when last accessed ("age" of buffer)
This header info could be held in an array, and items accessed by some simple
hashing function (sum of characters in path name? backwards sum of first 10
chars in path name?). But probably a linear search is fine (currently I have
a 20k SCSI dir cache, and a 16k ADFS dir cache => 40 entries to look at
before giving up).
An alternative would be to hold the header info as a tree, or as a linear
list - both in alphabetical order of path name.

There is, essentially, no problem in keeping these structures up-to-date,
since they are not "slaves" of disc contents, but rather the disc contents
themselves.


Unix BSD 4.3 buffer techniques:

  - A hash table is used to determine rapidly whether a requested disc block
     is in a buffer.
  - An LRU list links together all those buffers which have proved their
     usefulness - whenever a buffer is read/written to, it is moved to the
     end of the LRU list.
  - An AGE list links together all those buffers which have not yet proved
     their usefulness, or which have been used and are unlikely to be used
     again - read-ahead buffers will be added to the end of this list, and
     buffers which have been written-behind will be added to the front (of
     course, as soon as one of these buffers is accessed, it is moved to the
     end of the LRU list.
  - When a new buffer is needed - and none are available - buffers are taken
     from the front of the AGE list first, then the front of the LRU list.
  - BSD 4.3 deliberately defers writing out updated buffers for a while - say
     15 seconds - since most buffers will be updated again in the near
     future.
