below.... On Mon, Jan 7, 2019 at 4:22 PM Warner Losh 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. * ᐧ