The Block I/O Buffer Cache services are provided to support user access to device drivers through block I/O special files. This access is required by the operating system file system for mounts and other limited activity, as well as for compatibility services required when other file systems are installed on these kinds of systems. These services are not used by the operating system's JFS (journal file system), NFS (Network File System), or CDRFS (CD-ROM file system) when processing standard file I/O data. Instead they use the virtual memory manager and pager to manage the system's memory pages as a buffer cache.
For compatibility support of other file systems and block special file support, the buffer cache services serve two important purposes:
The Buffer Cache services use the buf structure or buffer header as their main data-tracking mechanism. Each buffer header contains a pair of pointers that maintains a doubly-linked list of buffers associated with a particular block device. An additional pair of pointers maintain a doubly-linked list of blocks available for use again on another operation. Buffers that have I/O in progress or that are busy for other purposes do not appear in this available list.
Kernel buffers are discussed in more detail in Introduction to Kernel Buffers in AIX 5L Version 5.2 Technical Reference: Kernel and Subsystems Volume 1.
See Block I/O Kernel Services for a list of these services.
Fourteen kernel services provide management of this block I/O buffer cache mechanism. The getblk kernel service allocates a buffer header and a free buffer from the buffer pool. Given a device and block number, the getblk and bread kernel services both return a pointer to a buffer header for the block. But the bread service is guaranteed to return a buffer actually containing a current data for the block. In contrast, the getblk service returns a buffer that contains the data in the block only if it is already in memory.
In either case, the buffer and the corresponding device block are made busy. Other processes attempting to access the buffer must wait until it becomes free. The getblk service is used when:
The breada kernel service is used to perform read-ahead I/O and is similar to the bread service except that an additional parameter specifies the number of the block on the same device to be read asynchronously after the requested block is available. The brelse kernel service makes the specified buffer available again to other processes.
There are three slightly different write routines. All of them take a buffer pointer as a parameter and all logically release the buffer by placing it on the free list. The bwrite service puts the buffer on the appropriate device queue by calling the device's strategy routine. The bwrite service then waits for I/O completion and sets the caller's error flag, if required. This service is used when the caller wants to be sure that I/O takes place synchronously, so that any errors can be handled immediately.
The bawrite service is an asynchronous version of the bwrite service and does not wait for I/O completion. This service is normally used when the overlap of processing and device I/O activity is desired.
The bdwrite service does not start any I/O operations, but marks the buffer as a delayed write and releases it to the free list. Later, when the buffer is obtained from the free list and found to contain data from some other block, the data is written out to the correct device before the buffer is used. The bdwrite service is used when it is undetermined if the write is needed immediately.
For example, the bdwrite service is called when the last byte of the write operation associated with a block special file falls short of the end of a block. The bdwrite service is called on the assumption that another write will soon occur that will use the same block again. On the other hand, as the end of a block is passed, the bawrite service is called, because it is assumed the block will not be accessed again soon. Therefore, the I/O processing can be started as soon as possible.
Note that the getblk and bread services dedicated the specified block to the caller while making other processes wait, whereas the brelse, bwrite, bawrite, or bdwrite services must eventually be called to free the block for use by other processes.