.SH
Buffer Cache
.PP
When the file server is
booted,
all of the unused memory is allocated to
a block buffer pool.
There are two major operations on the buffer
pool.
.CW Getbuf
will find the buffer associated with a
particular block on a particular device.
The returned buffer is locked so that the
caller has exclusive use.
If the requested buffer is not in the pool,
some other buffer will be relabeled and
the data will be read from the requested device.
.CW Putbuf
will unlock a buffer and
if the contents are marked as modified,
the buffer will be written to the device before
the buffer is relabeled.
If there is some special mapping
or CPU cache flushing
that must occur in order for the physical I/O
device to access the buffers,
this is done between
.CW getbuf
and
.CW putbuf .
The contents of a buffer is never touched
except while it is locked between
.CW getbuf
and
.CW putbuf
calls.
.PP
The
file system server processes
prevent deadlock in the buffers by
always locking parent and child
directory entries in that order.
Since the entire directory structure
is a hierarchy,
this makes the locking well-ordered,
preventing deadlock.
The major problem in the locking strategy is
that locks are at a block level and there are many
directory entries in a single block.
There are unnecessary lock conflicts
in the directory blocks.
When one of these directory blocks is tied up
accessing the very slow WORM,
then all I/O to dozens of unrelated directories
is blocked.
