below....
On Mon, Jan 7, 2019 at 4:22 PM Warner Losh <imp(a)bsdimp.com> wrote:
So what's the origin of the name
'strategy' for the I/O routine in Unix
that drivers provide? Everything I've found in the early papers just says
that's what the routine is called. Is there a story behind why it was
chosen? My own theory is that it's in the sense of 'coping strategy' when
the driver needs to service more I/O for the upper layers, but that's just
a WAG.
FWIW: Warren has a scan of the 1976 USG document: "UNIX Program
Description" Program Generic PG-1C300 Issue 2
From the section called: BIO01 - Block I/O, on the 5th
page I think there
seems to be a hint of why it was called strategy. Under the
description
of the breada routine are the words:
*Read ahead is a technique whereby an attempt is made to anticipate where
the next read request on a device will be and to preread that data. In this
manner, the program requesting the read will not be subjected to positional
and rotational latency or device queuing, if read ahead is completed before
the next block is requested. There are different strategies that can be
used for-doing read ahead. On UNIX, all reads (not including physical I/O)
result in a full 512 byte block being read from· the device. Smaller
amounts of data could be read if a program requested it, however, since
disks transfer times are small in comparison to positional and rotational
latency times, any extra transfer is inconsequential. Also, most DEC disks
are designed around a 512 byte sector and while fewer than 512 bytes may be
specified, the disk controller is busy until a full sector has been
transferred. By reading the full 512 bytes, any subsequent read or write
which references data within that block will not have to be lead (if the
block does not leave the system). Besides the advantage gained by reading a
minimum of 512 bytes instead of the desired quantities, the next block is
anticipated and read under certain conditions. Thus, one request will spawn
several read requests to bring data into the system. A routine for finding
a block that is already in memory (bio.c/incore) must be available to
determine whether any reads need be done and the read ahead strategy must
be capable of determining when read ahead should be discontinued so that
superfluous reads are not generated.*
*The strategy adopted under UNIX is to pursue read ahead as long as a
process is reading (512 byte blocks) sequentially through a file or a
device. When the first non sequential read is requested, read ahead is
discontinued and is not restarted until sequential accesses begin again. *
*Bio.c/breada carries out the read ahead operation. Starting and stopping
read ahead and determining which block number in a file or on a device is
the read ahead block ("rablkno") is done by the higher level function
rdwri.c/readi. *
*In implementing the read ahead strategy, bio.c/breada makes use of
bio.c/incore to determine whether a block is already in memory. For the
desired block "blkno", the bio.c/breada function behaves exactly like
bio.c/bread. That is, a synchronous read is performed and the process
requesting the read is roadblocked until it is completed. Since the desired
block may already be within system. bio.c/incore is called to look for that
block among the buffers on the freelist (bfreelist"). If the block is
already in memory. bio.c/bread is called to get the buffer. If the desired
biock has not already been read by a previous read operation then
bio.c/getblk is called to see if the block is possibly on a device queue
waiting for its turn to be read. If that is not the case, a buffer is
allocated for the read and the appropriate device strategy routine is
called. *
*Bio.c/breada does not wait (yet) for the read to complete. Rather, it goes
through a similar operation for the read ahead block "rablkno".
Bio.c/incore is called to search the free list of buffers ("bfreelist") to
see if the block was read in a previous read operation. Nothing will be
done, of course, if the read ahead block is in memory. If it is not in
memory, bio.c/getblk is called to search the device queue for it or to
allocate a block so that it may be read. The device strategy module is
called to read the read ahead block, however, the buffer will be marked
(B_ASYNC in "b_flags") so that when the read completes the buffer is
returned to the pool of available buffers. Bio.c/breada then waits for the
read of the the desired block to complete. It does not wait for the read
ahead block . *
*An external variable "raflg" is available for turning off all read ahead
on alldevices. "Raflg" is initialized to one, however, by changing it to
zero read ahead is eliminated. As with bio.c/bread any error detection is
done as a result of the interrupt handler indicating an error to
bio.c/lncore and a system error (in "u_error") being posted. These errors
are of no concern to bio.c/breada or bio.c/bread and are used only at
higher levels of software to return errors to the user. *
ᐧ