The Buffer Cache
Figure: The Buffer Cache
As the mounted file systems are used they generate a lot of requests to the block
devices to read and write data blocks.
All block data read and write requests are given to the device drivers in the form
of buffer_head data structures via standard kernel routine calls.
These give all of the information that the block device drivers need; the device
identifier uniquely identifies the device and the block number tells the driver
which block to read.
All block devices are viewed as linear collections of blocks of the same size.
To speed up access to the physical block devices, Linux maintains a cache of block
All of the block buffers in the system are kept somewhere in this buffer cache, even
the new, unused buffers.
This cache is shared between all of the physical block devices; at any one time
there are many block buffers in the cache, belonging to any one of the system's
block devices and often in many different states.
If valid data is available from the buffer cache this saves the system
an access to a physical device.
Any block buffer that has been used to read data from a block device or to write data
to it goes into the buffer cache.
Over time it may be removed from the cache to make way for a more deserving
buffer or it may remain in the cache as it is frequently accessed.
Block buffers within the cache are uniquely identfied by the owning device
identifier and the block number of the buffer.
The buffer cache is composed of two functional parts.
The first part is the lists of free block buffers.
There is one list per supported buffer size and the system's free block buffers
are queued onto these lists when they are first created or when they have been
The currently supported buffer sizes are 512, 1024, 2048, 4096 and 8192 bytes.
The second functional part is the cache itself.
This is a hash table which is a vector of pointers to chains of buffers that have
the same hash index.
The hash index is generated from the owning device identifier and the block number
of the data block.
Figure 9.7 shows the hash table together with a few entries.
Block buffers are either in one of the free lists or they are in the buffer cache.
When they are in the buffer cache they are also queued onto Least Recently Used
There is an LRU list for each buffer type and
these are used by the system to perform work on buffers of a type, for example, writing
buffers with new data in them out to disk.
The buffer's type reflects its state and Linux currently supports the following types:
- Unused, new buffers,
- Buffers that are locked, waiting to be written,
- Dirty buffers. These contain new, valid data, and will be written
but so far have not been scheduled to write,
- Shared buffers,
- Buffers that were once shared but which are now not shared,
Whenever a file system needs to read a buffer from its underlying physical
device, it trys to get a block from the buffer cache.
If it cannot get a buffer from the buffer cache, then it will get a clean one from
the appropriate sized free list and this new buffer will go into the buffer cache.
If the buffer that it needed is in the buffer cache, then it may or may not be up to
If it is not up to date or if it is a new block buffer, the file system must request
that the device driver read the appropriate block of data from the disk.
Like all caches, the buffer cache must be maintained so that it runs efficiently
and fairly allocates cache entries between the block devices using the buffer
Linux uses the bdflush
kernel daemon to perform a lot of housekeeping duties
on the cache but some happen automatically as a result of the cache being used.