Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 16: Page and Buffer Cache


back. Thereafter, the buffers — whether just created or already in existence — are identified using
page_buffersbefore they are handled as described below.page_bufferssimply translates theprivate
element of the page into abuffer_headpointer by means of pointer conversion because, by convention,
privatepoints to the first buffer if buffers are attached to a page.

The main work of the kernel is to find out which buffers are current (their data match that on the block
device or may even be more up-to-date) and therefore need not be read, and which buffers hold invalid
data. To do this, the kernel makes use of theBH_MappingandBH_Uptodatestate bits, both of which may
be set or unset.

It iterates over all buffers attached to the page and performs the following checks:


  1. If the buffer contents are up-to-date (this can be checked withbuffer_uptodate), the kernel
    continues to process the next buffer. In this case, the data in the page cache and on the block
    device match, and an additional read operation is not required.

  2. If there isnomapping (BH_Mappingis not set),get_blockis invoked to determine the posi-
    tion of the block on the block storage medium.
    ext2_get_blockandext3_get_block, respectively, are used for this purpose on Ext2/Ext3
    filesystems. Other filesystems use functions with similar names. Common to all alternatives
    is that thebuffer_headstructure is modified so that it can be used to locate the desired block
    in the filesystem. Essentially, this involves setting theb_bdevandb_blocknrfields because
    they identify the desired block.


The actual reading of data from the block device is performednotbyget_blockbut
later during the course ofblock_read_full_page.

After execution ofget_block, the state of the buffer isBH_Mappedbut notBH_Uptodate^12.


  1. A third situation is also possible. The buffer already has a mapping but is not up-to-date.
    The kernel then need perform no other actions.

  2. Once the individual combinations ofBH_UptodateandBH_Mappedhave been distinguished,
    the buffer is placed in a temporary array if it has a mapping but is not up-to-date. Processing
    then continues with the page’s next buffer until no further buffers are available.


Ifallbuffers attached to the page are up-to-date, the whole page can be set to this state using
SetPageUptodate. The function then terminates because all the data on the whole page now reside in
memory.

However, there are usually still buffers that have a mapping but do not reflect the current contents of the
block device. Reminder: Buffers of this kind are collected in an array that is used for the second and third
phases ofblock_read_full_page.

In the second phase, all buffers to be read are locked usinglock_buffer. This prevents two kernel
threads from reading the same buffer at the same time and therefore interfering with each other.

(^12) There is one other state in which a buffer is up-to-date but is not mapped. This state occurs when a file with gaps is read (as can
occur with the Second Extended Filesystem, e.g.). In this case, the buffer is filled with null bytes, but I shall ignore this scenario.

Free download pdf